9

我正在努力让下一个简单的算法在三星 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));
....

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

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

4

2 回答 2

9

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

在我看来,您应该使用实际的噪声功能,而不是这个东西。至少它将在硬件上产生可预测的结果。

于 2012-07-02T19:20:37.747 回答
5

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

问题在于 Mali GPU 上片段着色器的 FP16 精度。基本上,调用时没有留下小数位fract(因为乘数太大),所以你根本不会得到任何“噪音”。如果你让常数变小,你会开始得到非零值,但它们不会有噪音。(我不完全确定这些值是如何被挑选出来的,也不清楚这个算法是从哪里来的)。

从技术上讲,这种噪声算法依赖于更高(中?高?)精度的浮点运算,这在片段着色器中是可选的。根据this other post,您可以通过检查glGetString(GL_EXTENSIONS).

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

于 2013-04-06T02:47:17.553 回答