三星Galaxy SIII(GLES)中的噪声算法失败

Per*_*abs 9 shader android opengl-es glsl

我正在努力让下一个简单的算法在三星Galaxy SIII中运行

float rand(vec2 co)
{
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

....
vec3 color = texture2D(u_texture, v_texcoord);
gl_FragColor.rgb = color + vec3(rand(gl_FragCoord.xy + time / 1000.0));
....
Run Code Online (Sandbox Code Playgroud)

该代码完美地生成了三星Galaxy S1和谷歌Nexus S的预期噪音.但它完全失败了使用ARM的Mali-400/MP4的新智能手机.

任何人都可以发现这个算法有什么问题?或者也许明白为什么会失败?

Nic*_*las 9

你的问题很可能来自于sin一个大数字.其结果取决于确切的实现sin,这是不可用的.显然,sinMali芯片使用的功能比其他功能具有更多可预测的结果.

在我看来,你应该使用实际噪音的功能,没有这个东西.至少它会在硬件上产生可预测的结果.


P.T*_*.T. 5

在ARM论坛上对此问题进行了一些讨论:http : //forums.arm.com/index.php ? / topic/16364-random-number-with-mali-400-mp/

问题是由于Mali GPU上的片段着色器具有FP16精度。基本上,fract调用时间没有剩余的小数位(因为乘数很大),因此您根本不会得到任何“噪音”。如果使常数变小,则将开始返回非零值,但它们不会很吵。(我不太确定这些值是如何选择的,也不清楚该算法的来源)。

从技术上讲,此噪声算法依赖于精度更高(中高)的浮点运算,这在片段着色器中是可选的。根据一篇文章,您可以通过检查中的“ OES_fragment_precision_high”扩展名来检查片段着色器中平台支持的精度glGetString(GL_EXTENSIONS)

Nicol的答案中的webgl-noise项目似乎不易受浮点截断问题的影响(它似乎使事情更加紧密)。但是,它的周期大约为300,它产生的“结构化”噪声要比您当前获得的“白”(或“粉红色”)噪声更多。但是,它是一个出色的库,因此即使不是直接替代它,也值得在您的代码中使用。