2012-07-02 9 views
7

Ho difficoltà a ottenere il prossimo semplice algoritmo che lavorano nel Samsung Galaxy SIIIrumore algoritmo riesce a 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)); 
.... 

Il codice genera perfettamente il rumore atteso Samsung Galaxy S1 e Google Nexus S Ma fallisce completamente nel nuovo smartphone che utilizza ARM's Mali-400/MP4.

Chiunque può individuare qualcosa di sbagliato con questo algoritmo? O forse capisci perché potrebbe fallire?

+2

Fallisce come? Stai controllando gli infologhi per errori/avvisi? – Tim

+0

Nessun errore, semplicemente non mostra alcun pixel di disturbo. L'immagine complessiva è ok, ma senza alcun rumore. – PerracoLabs

+2

Hmm, non sono sicuro. Ti consiglio semplicemente di rimetterlo a posto uno strato alla volta fino a quando non riesci a capire perché. Per esempio. funziona() funziona? fract (sin()) funziona, fa il fract (sin (dot ((())) funziona? ecc. – Tim

risposta

9

Il problema deriva probabilmente dal numero sin di un numero elevato. Il risultato di ciò dipende dall'esatta implementazione di sin, che non è disponibile. Ovviamente la funzione sin utilizzata dal chip Mali ha risultati più prevedibili con numeri grandi rispetto agli altri.

Mi sembra che si dovrebbe usare an actual noise function, non questa cosa. Almeno avrà risultati prevedibili su tutto l'hardware.

+1

Ho provato questa opzione come se fosse la migliore, e ho ottenuto risultati molto strani. linee dappertutto anziché rumore. Ho usato il successivo dalla libreria: https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl – PerracoLabs

3

Un po 'di discussione su questo problema sui forum ARM: http://forums.arm.com/index.php?/topic/16364-random-number-with-mali-400-mp/.

Il problema è dovuto alla precisione FP16 negli ombreggiatori di frammenti sulla GPU Mali. Fondamentalmente, non vi sono bit frazionali lasciati nel momento in cui viene invocato il numero fract (perché i moltiplicatori sono così grandi), quindi non si ottiene affatto alcun "rumore". Se riduci le costanti, inizierai a recuperare valori diversi da zero, ma non saranno rumorosi. (Non sono del tutto sicuro di come sono stati selezionati i valori e il suo not clear where this algorithm came from).

Tecnicamente questo algoritmo di rumore si basa su operazioni di precisione in virgola mobile di livello superiore (medio-alto?), Che sono opzionali negli ombreggiatori di frammenti. In base a this other post, è possibile controllare la precisione supportata della piattaforma nei frammenti shader controllando l'estensione "OES_fragment_precision_high" in glGetString(GL_EXTENSIONS).

Il progetto webgl-noise nella risposta di Nicol non sembra suscettibile di problemi di troncamento a virgola mobile (sembra mantenere le cose in un vincolo più stretto). Tuttavia, ha un periodo di circa 300 e genera un rumore più "strutturato" rispetto al rumore "bianco" (o "rosa") che si ottiene attualmente. È una libreria eccellente, però, quindi vale la pena lavorare sul codice anche se non è una sostituzione drop-in.

+0

Ho finito per usare la libreria webgl-noise , anche se sto ancora cercando di trovare un'alternativa, dato che l'algoritmo è troppo grande e oltre a volte (più di quanto volessi) produce un rumore che non assomiglia affatto al rumore, specialmente quando si mescolano con i colori scuri. oltre al progetto webgl-noise, non ho trovato alcuna alternativa. – PerracoLabs