ipad - Weird GLSL float color value in fragment shader on iOS -
i trying write simple glsl fragment shader on ipad2 , running strange issue way opengl seems represent 8bit "red" value onces pixel value has been converted float part of texture upload. want pass in texture contains large number of 8bit table indexes , 32bpp table of actual pixel values.
my texture data looks this:
// lookup table stored in texture const uint32_t pixel_lut_num = 7; uint32_t pixel_lut[pixel_lut_num] = { // 0 -> 3 = w1 -> w4 (w4 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 }; each texture bound , texture data uploaded so:
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); i confident texture setup , uniform values working expected, because fragment shader working following code:
varying highp vec2 coordinate; uniform sampler2d indexes; uniform sampler2d lut; void main() { // normalize (red * 42.5) 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); } the code above takes 8 bit index , looks 32bpp bgra pixel value in lut. part not understand 42.5 value defined in opengl. found scale value through trial , error , have confirmed output colors each pixel correct (meaning index each lut table lookup right) 42.5 value. but, how opengl come value?
in looking @ opengl man page, find mention of 2 color constants gl_c_scale , gl_c_bias seem used when converting 8bit "index" value floating point value internally used inside opengl. these constants defined , how query value @ runtime or compile time? actual floating point value of "index" table real issue here? @ loss understand why texture2d(indexes,...) call returns funky value, there other way int or float value index works on ios? tried looking @ 1d textures not seem supported.
your color index values accessed 8bit unorms, range [0,255] mapped floating point interval [0,1]. when access lut texture, texcoord range [0,1]. currently, have width of 7. magic value of 42.5, end following:
integer index: 0: fp: 0.0 -> texcoord: 0.0 * 42.5 == 0.0 integer index: 6: fp: 6.0/255.0 -> texcoord: (6.0/255.0) * 42.5 == 0.9999999... that mapping close, not 100% correct though, since not map texel centers. correct mapping (see this answer details), need like:
integer index: 0: fp: 0.0 -> texcoord: 0.0 + 1.0/(2.0 *n) integer index: n-1: fp: (n-1)/255.0 -> texcoord: 1.0 - 1.0/(2.0 *n) where n is pixel_lut_size code above.
so, single scale value not enough, need additional offset. correct values be:
scale= (255 * (1 - 1/n)) / (n-1) == 36.428... offset= 1/(2.0*n) == 0.0714... one more thing: souldn't use gl_linear lut minification texture filter.
Comments
Post a Comment