I am trying make a simplex noise on android, based on this example:
https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl
After converting the code and compiling it on the device, I realised that the pattern is far from random. I have broken down the code to the most basic part where I still see a big difference between desktop (I test these on http://glslsandbox.com/e) and mobile and I've got this.
#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
float u_time = time;
vec2 u_resolution = resolution;
vec3 mod289(vec3 x) {
vec3 t = x * 0.00346020761;
t = floor(t);
t = t * 289.0;
return x - t;
//return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec3 permute(vec3 x) {
vec3 t = x * 34.0;
t = t + 1.0;
t = t * x;
return mod289(t);
//return mod289(((x*34.0)+1.0)*x);
}
void main( void ) {
vec2 p = vec2( (gl_FragCoord.xy / u_resolution.xx - 0.5) * 2.0);
vec3 value = permute( p.xyx * 10000.0 + u_time * 0.1);
gl_FragColor = vec4(value, 1.0);
//gl_FragColor = vec4(p + 1.0, 0.0, 1.0);
}
The purpose for seperating them into lines is that I've also encountered this kind of errors earlier. GLSL ES fragment shader produces very different results on different devices
On the device, this code (#ifdef and #extension removed, and the uniform variables set properly) produces a white screen. (Tested on multiple devices, using #version 300 es and also using the older shader version, always the same result.)
Is this error caused by the inaccuracy of floor() ?
Or is there a way to generate simplex noise without these mod289 functions? (2d noise ran just fine)
It's highly likely that your desktop GPU is using fp32 precision for computation (even if you specify mediump
in the shader, which only requires fp16).
If you set precision highp float
does it work any better? This will force fp32 floating point computation.
However, note that not all mobile devices support highp
- it only became Mandatory in OpenGL ES 3.x onwards, so some OpenGL ES 2.x GPUs only support fp16 computation.
(What device are you running on?)