简体   繁体   English

在GLSL中将采样的纹理值相乘然后相除会在某些Android设备上产生不正确的结果吗?

[英]Multiplying then dividing sampled texture values in GLSL produces incorrect results on some Android devices?

Some background: This is my first OpenGL ES 2 program, so I'm inexperienced. 一些背景:这是我的第一个OpenGL ES 2程序,所以我没有经验。 I've been working on a shader to display color-indexed textures. 我一直在研究着色器以显示颜色索引的纹理。 It samples a point from one texture, multiplies it by 256.0 to scale it up to 8-bit integer range, samples the corresponding RGBA value from that offset in a palette texture, and sets the gl_FragColor. 它从一个纹理中采样一个点,将其乘以256.0以将其缩放到8位整数范围,从调色板纹理中的该偏移量采样相应的RGBA值,并设置gl_FragColor。

I've had it working perfectly on my Samsung Galaxy S2 for a month now, but it never worked on my Galaxy S1, displaying only a black texture. 我已经将它在我的Samsung Galaxy S2上正常工作了一个月,但它从未在我的Galaxy S1上工作过,仅显示黑色纹理。 After countless attempts of banging my head against the wall trying to find the problem through trial and error in all parts of my code, I finally narrowed it down to a piece of shader code that can effectively be reduced to the following: 在无数次尝试敲击墙壁以尝试通过代码的所有部分反复尝试找出问题之后,我最终将其范围缩小为一段着色器代码,可以将其有效地简化为以下内容:

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);
}

For that example, texture is a 256x256 pixel texture with every value set to 0xFF. 对于该示例, texture是256x256像素纹理,每个值均设置为0xFF。 If I run that code on my Galaxy S2, it works fine: I get a completely white screen, exactly 0xFFFFFF. 如果我在Galaxy S2上运行该代码,则可以正常工作:我得到一个完全白屏,正好是0xFFFFFF。 If I run it on my original Galaxy S1, the screen is exactly 0x000000. 如果我在原始的Galaxy S1上运行它,则屏幕恰好是0x000000。

Now, I found that if I decrease that 256.0 value then run it, the output on my Galaxy S1 starts to increase from all black to various shades of gray. 现在,我发现,如果我降低了256.0的值然后运行它,我的Galaxy S1的输出就会开始从全黑增加到各种灰度。 For example, 8.0 gave me 0x424142, and 4.0 gave me 0x848284. 例如,8.0给我0x424142,而4.0给我0x848284。 By the time I multiply / divide by 2.0, it starts outputting 0xFFFFFF just like my Galaxy S2! 到我乘以2.0时,它就像我的Galaxy S2一样开始输出0xFFFFFF!

Any idea what could possibly cause an issue like this? 任何想法可能会导致这样的问题吗? I'll take your wildest guesses, because I'm absolutely defeated at this point. 我会做出最疯狂的猜测,因为在这一点上我已经被击败了。 I don't see anything that could be causing this. 我看不到任何可能导致这种情况的原因。

Is the answer floating point truncation? 答案浮点数被截断了吗?

A fragment shader is allowed to use "lowp" float precision, which means 16-bit floating point, which 256 * 256 would overflow (see http://en.wikipedia.org/wiki/Half-precision_floating-point_format ). 片段着色器允许使用“ lowp”浮点精度,这意味着16位浮点会溢出256 * 256(请参阅http://en.wikipedia.org/wiki/Half-precision_floating-point_format )。 At this point the math falls apart and results are undefined. 此时,数学崩溃了,结果不确定。

However, as far as I can tell (see glblenchmark.com data ) the Galaxy S1 should support highp floats in the fragment shader as it has the "OES_fragment_precision_high" extension in the glGetString(GL_EXTENSIONS) output. 但是,据我所知(请参阅glblenchmark.com数据 ),Galaxy S1应该在片段着色器中支持高浮点,因为它在glGetString(GL_EXTENSIONS)输出中具有“ OES_fragment_precision_high”扩展名。 (Though I may have the wrong model there...) (尽管我那里的型号可能不对...)

Maybe there is some other reason you're not getting high precision floats though. 也许还有其他原因使您无法获得高精度的浮点数。 What #version are you using in your shader? 您在着色器中使用的是什么#version

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM