【问题标题】:Noise Algorithm fails in Samsung Galaxy SIII (GLES)三星 Galaxy SIII (GLES) 中的噪声算法失败
【发布时间】:2012-07-02 20:45:11
【问题描述】:

我正在努力让下一个简单算法在三星 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 的新智能手机中却完全失败了。

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

【问题讨论】:

  • 失败怎么办?您是否正在检查信息日志中的错误/警告?
  • 完全没有错误,根本不显示任何噪声像素。整体图像还可以,但没有任何噪点。
  • 嗯,那么不确定。我只是建议一次剥一层,直到你明白为什么。例如。 fract() 有效吗? fract(sin()) 是否有效,fract(sin(dot((()))) 是否有效?等

标签: android opengl-es glsl shader


【解决方案1】:

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

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

【讨论】:

【解决方案2】:

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,并且它产生的“结构化”噪声比您当前获得的“白色”(或“粉红色”)噪声更多。不过,它是一个出色的库,因此即使它不是直接替代品,它也值得在您的代码中工作。

【讨论】:

  • 我最终使用了 webgl-noise 库,但我仍在尝试寻找替代方案,因为算法太大,而且有时(超出我想要的)会产生看起来不像的噪音完全和噪音一样,特别是在与深色混合时。所以到现在,除了webgl-noise这个项目,我还没有找到替代方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多