2

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)

Community
  • 1
  • 1
andras
  • 3,305
  • 5
  • 30
  • 45

1 Answers1

4

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?)

solidpixel
  • 10,688
  • 1
  • 20
  • 33
  • I only tested the highp on the lower device, it is an ARM Mali-400 MP2 (dual core). The better one with Adreno 305 which supports the es 3.0 also supports highp, which solved my problem. Note for anybody else having this issue, you can check support for precision: http://stackoverflow.com/questions/4414041/what-is-the-precision-of-highp-floats-in-glsl-es-2-0-for-iphone-ipod-touch-ipad glGetShaderPrecisionFormat returns zeros if highp is not supported. – andras Dec 14 '16 at 13:25
  • The Mali-400 series is OpenGL ES 2.x only, and doesn't support fp32 so in that case you'll just be getting fp16 – solidpixel Dec 15 '16 at 12:13