I am trying to write a compact and simple noise function with a strictly FP16 limit. This is with what I came out so far, but I think somewhere on the operation the number gets too small for fract or sin, since in the GPU I must write this for these are within the FP16 limits. Any ideas on what am I doing wrong? BY the way, I cannot use a time variables, neither sample noise textures. The function I need to get right must be compact, small and self-sufficient, and produce a simple grainy noise effect. Note: The next algorithm works fine in any desktop GPU card, but fails completely on the "MALI 400 MP" GPU, since this one has a FP16 limitation on float values.
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);
}
If any one can recommend any other random function for GLSL-ES but strictly with a FP16 limit, would also be great. I know about other random implementations such as simplex noise, but these are too large and slow for what I need to do. So Perlin and Simplex noise algorithms are not an option.
These are the ones that I use but I don't know if either works in a FP16 limit:
// source: http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
highp float rand(vec2 co)
{
highp float a = 12.9898;
highp float b = 78.233;
highp float c = 43758.5453;
highp float dt= dot(co.xy ,vec2(a,b));
highp float sn= mod(dt,3.14);
return fract(sin(sn) * c);
}
float rand2(vec2 co)
{
return fract(sin(dot(co.xy,vec2(12.9898,78.233))) * 43758.5453);
}
I didn't create either of these. The link to the original author is above. I actually use rand2 and didn't have the issue mentioned on that blog. To make a greyscale noise do something like:
float randColor = rand(v_position);
gl_FragColor = vec4(randColor);
To do a full color noise it would take 3 times longer and you'd do:
gl_FragColor = vec4(rand(v_position), rand(v_position), rand(v_position), 1.0);
To add noise to whatever you're drawing you could:
float randColor = rand(v_position) * .1; // to add 10% noise
gl_FragColor = vec4(gl_FragColor.r + randColor, gl_FragColor.g + randColor, gl_FragColor.b + randColor, 1.0);
By the way, this is slow. On an iPhone5 this works fine with no major slowdown. But on a 4S it dropped by fps down to 30. If I removed adding the noise it raised it to 60. So beware.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With