噪声算法在Samsung Galaxy SIII(GLES)中失败

问题描述 投票:9回答:3

我正在努力使下一个简单算法在Samsung 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和Google Nexus S中完美地产生了预期的噪声。但是,在使用ARM的Mali-400 / MP4的新型智能手机中,该代码完全失败了。

任何人都可以发现此算法有什么问题吗?或者也许理解为什么它会失败?

android opengl-es glsl shader
3个回答
9
投票

您的问题可能是来自大量的sin。其结果取决于sin的确切实现,尚不可用。显然,Mali芯片使用的sin函数具有比其他函数更大的可预测结果。

在我看来,您应该使用an actual noise function,而不是这个东西。至少它将在整个硬件上产生可预测的结果。


5
投票

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

问题是由于Mali GPU上片段着色器的FP16精度。基本上,在调用fract时没有剩余的小数位(因为乘数很大),因此您根本不会得到任何“噪音”。如果使常数变小,则将开始获取非零值,但它们不会有干扰。 (我不完全确定如何选择值及其not clear where this algorithm came from。)>

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

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

使用Gold Noise,均匀的标准化分布。它是专为以低精度(lowp)运行而设计的。它还接受种子(例如时间)。

float gold_noise(in vec2 xy, in float seed){
    return fract(tan(distance(xy*PHI, xy)*seed)*xy.x);
}

2
投票

使用Gold Noise,均匀的标准化分布。它是专为以低精度(lowp)运行而设计的。它还接受种子(例如时间)。

© www.soinside.com 2019 - 2024. All rights reserved.