2012-07-02 6 views
7

Ich kämpfe den nächsten einfachen Algorithmus in dem Samsung Galaxy Arbeits SIIILärm nicht Algorithmus in Samsung Galaxy SIII (GLES)

float rand(vec2 co) 
{ 
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 
} 

.... 
vec3 color = texture2D(u_texture, v_texcoord); 
gl_FragColor.rgb = color + vec3(rand(gl_FragCoord.xy + time/1000.0)); 
.... 

Der Code zu bekommen erzeugt perfekt das erwartete Rauschen in Samsung Galaxy S1 und Google Nexus S Aber es scheitert komplett in dem neuen Smartphone, das ARMs Mali-400/MP4 verwendet.

Jeder kann etwas falsch mit diesem Algorithmus erkennen? Oder vielleicht verstehen, warum es scheitern könnte?

+2

Fehler wie? Überprüfen Sie die Infologs auf Fehler/Warnungen? – Tim

+0

Keine Fehler, zeigt einfach kein Rauschen Pixel. Das Gesamtbild ist in Ordnung, aber ohne Lärm. – PerracoLabs

+2

Hmm, nicht sicher dann. Ich würde nur empfehlen, es Schicht für Schicht zurückzuschälen, bis Sie verstehen, warum. Z.B. funktioniert fract()? funktioniert fract (sin()) work, tut fract (sin (dot ((())) funktioniert? usw. – Tim

Antwort

9

Ihr Problem kommt wahrscheinlich von der Einnahme der sin einer großen Zahl. Das Ergebnis hängt von der genauen Implementierung von sin ab, die nicht verfügbar ist. Offensichtlich hat die vom Mali-Chip verwendete sin-Funktion vorhersagbarere Ergebnisse mit großen Zahlen als die anderen.

Es scheint mir, dass Sie an actual noise function verwenden sollten, nicht dieses Ding. Zumindest wird es über die Hardware vorhersehbare Ergebnisse haben.

+1

Ich habe diese Option ausprobiert, da ich die beste wäre, und ich habe sehr seltsame Ergebnisse Linien überall statt Lärm, ich habe den nächsten aus der Bibliothek verwendet: https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl – PerracoLabs

3

Ein bisschen Diskussion dieses Problems auf den ARM-Foren: http://forums.arm.com/index.php?/topic/16364-random-number-with-mali-400-mp/.

Das Problem liegt an der FP16-Genauigkeit in Fragment-Shadern auf der Mali-GPU. Im Grunde gibt es keine gebrochenen Bits, die bis zum Zeitpunkt fract übrig sind (weil die Multiplikatoren so groß sind), so dass Sie überhaupt kein "Rauschen" zurückbekommen. Wenn Sie die Konstanten kleiner machen, erhalten Sie Werte ungleich Null, die jedoch nicht verrauscht sind. (Ich bin nicht ganz sicher, wie die Werte ausgewählt wurden, und seine not clear where this algorithm came from).

Technisch basiert dieser Rauschalgorithmus auf höheren Gleitkommaoperationen (mittel? Hoch?), Die in Fragment-Shadern optional sind. Gemäß this other post können Sie die unterstützte Genauigkeit der Plattform in Fragment-Shadern überprüfen, indem Sie in glGetString(GL_EXTENSIONS) nach der Erweiterung "OES_fragment_precision_high" suchen.

Das webgl-noise-Projekt in Nicols Antwort scheint nicht so anfällig für Gleitkomma-Trunkierungsprobleme zu sein (es scheint die Dinge in einer engeren Grenze zu halten). Es hat jedoch einen Zeitraum von etwa 300 und erzeugt mehr "strukturiertes" Rauschen als das "weiße" (oder "rosa") Rauschen, das Sie derzeit erhalten. Es ist jedoch eine ausgezeichnete Bibliothek, so dass es sich lohnt, in Ihren Code zu arbeiten, auch wenn es kein Ersatz für einen Drop-In ist.

+0

Ich endete mit der Webgl-Noise-Bibliothek Obwohl ich immer noch versuche, eine Alternative zu finden, da der Algorithmus zu groß ist und manchmal (mehr als ich wollte) Geräusche erzeugt, die überhaupt nicht so sehr wie Rauschen aussehen, besonders wenn man mit dunklen Farben mischt. Neben dem Webgl-Noise-Projekt habe ich keine Alternative gefunden. – PerracoLabs

Verwandte Themen