2016-12-14 4 views
0

WebGL im Vergleich Ich versuche, einen Simplex-Lärm auf Android machen, basierend auf diesem Beispiel:Ungenaue Shader Präzision auf Android

https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl

Nach der Code-Umwandlungs und es auf dem Gerät zusammenzustellen, wurde mir klar, dass die Muster ist bei weitem nicht zufällig. Ich habe den Code auf den grundlegendsten Teil heruntergebrochen, wo ich immer noch einen großen Unterschied zwischen dem Desktop (ich teste diese auf http://glslsandbox.com/e) und dem Handy sehe und ich habe das.

#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); 
} 

Der Zweck für sie in Linien seperating ist, dass ich diese Art auch früher von Fehlern begegnet ist. GLSL ES fragment shader produces very different results on different devices

Auf dem Gerät wird dieser Code (#ifdef und # extension entfernt, und die uniform Variablen richtig eingestellt) erzeugt einen weißen Bildschirm. (Getestet auf mehreren Geräten, mit #version 300 es und auch mit der älteren Shader-Version, immer das gleiche Ergebnis.)

Wird dieser Fehler durch die Ungenauigkeit von floor() verursacht?

Oder gibt es eine Möglichkeit, Simplex-Rauschen ohne diese mod289 Funktionen zu generieren? (2d Rauschen lief einwandfrei)

Antwort

2

Es ist sehr wahrscheinlich, dass Ihre Desktop-GPU fp32-Genauigkeit für die Berechnung verwendet (auch wenn Sie mediump im Shader angeben, der nur fp16 erfordert).

Wenn Sie precision highp float einstellen funktioniert es besser? Dies wird fp32 Fließkommaberechnung erzwingen.

Beachten Sie jedoch, dass nicht alle mobilen Geräte highp unterstützen - es wurde erst ab OpenGL ES 3.x obligatorisch, sodass einige OpenGL ES 2.x-GPUs nur fp16-Berechnungen unterstützen.

(welches Gerät laufen Sie?)

+0

Getestet habe ich nur die HighP auf dem unteren Gerät, es ist ein ARM Mali-400 MP2 (Dual-Core). Der bessere mit Adreno 305, der das es 3.0 unterstützt, unterstützt auch highp, was mein Problem gelöst hat. Hinweis für alle anderen, die dieses Problem haben, können Sie die Unterstützung für die Genauigkeit überprüfen: http://StackOverflow.com/Questions/4414041/what-is-the-precision-of-highp-floats-in-glsl-es -2-0-für-iphone-ipod-touch-ipad glGetShaderPrecisionFormat gibt Nullen zurück, wenn highp nicht unterstützt wird. – andras

+0

Die Mali-400-Serie ist nur OpenGL ES 2.x und unterstützt nicht fp32. In diesem Fall erhalten Sie nur fp16 – solidpixel