然后乘以然后在GLSL中划分采样的纹理值会在某些Android设备上产生不正确的结果?

时间:2012-05-01 15:10:03

标签: android glsl opengl-es-2.0

一些背景:这是我的第一个OpenGL ES 2程序,所以我没经验。我一直在使用着色器来显示颜色索引纹理。它从一个纹理中采样一个点,将其乘以256.0以将其扩展到8位整数范围,从调色板纹理中的该偏移量中采样相应的RGBA值,并设置gl_FragColor。

我已经在三星Galaxy S2上完美运行了一个月,但它从未在我的Galaxy S1上运行,只显示黑色纹理。在无数次尝试将我的头撞到墙上试图通过我的代码的所有部分的反复试验来找到问题之后,我最终将其缩小为一片着色器代码,可以有效地简化为以下内容:

precision highp float;

varying vec2 v_texCoord;
uniform sampler2D texture;

void main()
{
    float multiplied = texture2D(texture, v_texCoord).s * 256.0;

    float divided = multiplied / 256.0;

    gl_FragColor = vec4(divided, divided, divided, 1.0);
}

对于该示例,texture是256x256像素纹理,每个值都设置为0xFF。如果我在我的Galaxy S2上运行该代码,它工作正常:我得到一个完全白色的屏幕,正好是0xFFFFFF。如果我在我原来的Galaxy S1上运行它,屏幕就是0x000000。

现在,我发现如果我减少256.0的值然后运行它,我的Galaxy S1上的输出开始从所有黑色增加到各种灰度。例如,8.0给了我0x424142,4.0给了我0x848284。当我乘以/除以2.0时,它就像我的Galaxy S2一样开始输出0xFFFFFF!

知道什么可能导致这样的问题吗?我会采取你最疯狂的猜测,因为我在这一点上绝对失败了。我没有看到任何可能导致这种情况的事情。

1 个答案:

答案 0 :(得分:1)

答案是浮点截断吗?

允许片段着色器使用“lowp”浮点精度,这意味着16位浮点,256 * 256将溢出(参见http://en.wikipedia.org/wiki/Half-precision_floating-point_format)。此时数学分崩离析,结果未定义。

然而,据我所知(参见glblenchmark.com data),Galaxy S1应支持片段着色器中的highp浮点数,因为它在glGetString(GL_EXTENSIONS)输出中具有“OES_fragment_precision_high”扩展名。 (虽然我可能在那里有错误的模型......)

也许还有其他原因你没有得到高精度浮子。您在着色器中使用了哪些#version