Per*_*abs 11 random algorithm shader 16-bit glsles
我正在尝试编写一个紧凑而简单的噪声功能,严格限制FP16.这是什么,我就出来了,到目前为止,但我觉得某处操作的数量变得太小FRACT或罪,因为在GPU,我必须写这篇文章,这些都是内FP16限制.关于我做错什么的任何想法?顺便说一句,我不能使用时间变量,也不能使用样本噪声纹理.我需要正确的功能必须紧凑,小巧且自给自足,并产生简单的颗粒噪声效果.注意:下一个算法适用于任何桌面GPU卡,但在" MALI 400 MP "GPU 上完全失败,因为这个浮点值具有FP16限制.
vec3 noise(vec3 color)
{
float variation = length(color);
float dot_product = dot(variation, -0.577350269);
float sin_result = sin(dot_product) * 1.19245;
float random = fract(sin_result);
return color + vec3(random);
}
Run Code Online (Sandbox Code Playgroud)
如果任何人可以为GLSL-ES推荐任何其他随机功能,但严格遵守FP16限制,也会很棒.我知道其他随机实现,例如单纯形噪声,但是这些对于我需要做的事情来说太大而且速度太慢.因此Perlin和Simplex噪声算法不是一种选择.
虽然这是一个老问题,但我最终很久以前就找到了解决方案。接下来是脚本,以便任何人都可以使用它。作为种子,您应该传递一个动态或随机值,您可以将其作为属性传递给着色器。
float getNoise(vec2 seed)
{
vec2 theta_factor_a = vec2(0.9898, 0.233);
vec2 theta_factor_b = vec2(12.0, 78.0);
float theta_a = dot(seed.xy, theta_factor_a);
float theta_b = dot(seed.xy, theta_factor_b);
float theta_c = dot(seed.yx, theta_factor_a);
float theta_d = dot(seed.yx, theta_factor_b);
float value = cos(theta_a) * sin(theta_b) + sin(theta_c) * cos(theta_d);
float temp = mod(197.0 * value, 1.0) + value;
float part_a = mod(220.0 * temp, 1.0) + temp;
float part_b = value * 0.5453;
float part_c = cos(theta_a + theta_b) * 0.43758;
return fract(part_a + part_b + part_c);
}
Run Code Online (Sandbox Code Playgroud)