我想在iPad2上編寫一個簡單的GLSL片段着色器,並且我遇到了一個奇怪的問題,OpenGL似乎代表了一個8位「紅色」值,作爲紋理上傳的一部分,像素值已被轉換爲浮點數。我想要做的是傳入一個包含大量8位表索引和實際像素值的32bpp表的紋理。iOS中的片段着色器中奇怪的GLSL浮點顏色值
我的紋理數據看起來是這樣的:
// Lookup table stored in a texture
const uint32_t pixel_lut_num = 7;
uint32_t pixel_lut[pixel_lut_num] = {
// 0 -> 3 = w1 -> w4 (w4 is pure white)
0xFFA0A0A0,
0xFFF0F0F0,
0xFFFAFAFA,
0xFFFFFFFF,
// 4 = red
0xFFFF0000,
// 5 = green
0xFF00FF00,
// 6 = blue
0xFF0000FF
};
uint8_t indexes[4*4] = {
0, 1, 2, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6
};
然後每個紋理被綁定和紋理數據被上傳,像這樣:
GLuint texIndexesName;
glGenTextures(1, &texIndexesName);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texIndexesName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED_EXT, width, height, 0, GL_RED_EXT, GL_UNSIGNED_BYTE, indexes);
GLuint texLutName;
glGenTextures(1, &texLutName);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texLutName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_lut_num, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixel_lut);
我相信紋理設置和均勻值按預期工作,因爲片段着色器主要與以下代碼一起工作:
varying highp vec2 coordinate;
uniform sampler2D indexes;
uniform sampler2D lut;
void main()
{
// normalize to (RED * 42.5) then lookup in lut
highp float val = texture2D(indexes, coordinate.xy).r;
highp float normalized = val * 42.5;
highp vec2 lookupCoord = vec2(normalized, 0.0);
gl_FragColor = texture2D(lut, lookupCoord);
}
上面的代碼需要8位索引,並在lut中查找32bpp BGRA像素值。我不明白的部分是在OpenGL中定義了這個42.5值。我通過反覆試驗發現了這個比例值,並且我已經確認每個像素的輸出顏色是正確的(意味着每個查找表查找的索引是正確的)與42.5值。但是,OpenGL究竟如何提供這個值呢?
查看此OpenGL man page,我發現在將8位「索引」值轉換爲OpenGL內部使用的浮點值時似乎使用了兩個顏色常量GL_c_SCALE和GL_c_BIAS。這些常量在哪裏定義,我如何在運行時或編譯時查詢這些值? 「索引」表的實際浮點值是否是真正的問題?我不知道爲什麼texture2D(indexes,...)調用返回這個時髦的值,有沒有其他方法可以獲得適用於iOS的索引的int或float值?我試着看一維紋理,但他們似乎並不支持。
啊,它是(255 /(pixel_lut_num_1))= 42.5。非常感謝。我不知道爲什麼我以前沒有看到。重新使用縮小過濾器,你是說GL_NEAREST是更好的選擇嗎? – MoDJ
@MoDJ:是的。只要您不想在LUT中的相鄰條目之間進行混合,那麼使用GL_NEAREST是最好和最有效的選擇。請注意,「縮小」和「放大」之間的距離在訪問LUT時沒有任何意義,並且GL在這裏所做的選擇將取決於您用於相鄰片段的索引,因此用於縮小和放大的不同濾鏡不是「這裏真的是個好主意。 – derhass
我幾乎可以理解你在這裏描述的像素居中邏輯。我測試了我的表格,它的確從0.1428(又名0.0 + 1.0/7.0)的顏色索引0變爲1。所以,我看到你說的1/2像素界限是0.1428/2(又名0.0 + 1.0/2 * 7.0)。所以,你說的中心紋理座標在lut中查找應該是0 = 0.0714,1 =(2 * 0.0714)+ 0.0714等等。所以,我看到你如何得到「補償」來補充,但你是如何得出「比例」公式的? 255範圍被分成兩倍的段,但你是如何計算「規模」的? – MoDJ