2011-01-18 20 views
6

Sto tentando di implementare più luci nel mio shader ma ho difficoltà a riempire l'uniforme con i miei dati chiari.Passaggio di un array di vettori a un'uniforme

mio vertex shader:

attribute vec3 aVertex; 
attribute vec3 aNormal; 
attribute vec2 aTexture; 

uniform mat4 uMVMatrix; 
uniform mat4 uPMatrix; 
uniform mat4 uNMatrix; 

uniform vec3 uAmbientColor; 
uniform vec3 uPointLightingLocation[16]; 
uniform vec3 uPointLightingColor[16]; 

varying vec2 vTexture; 
varying vec3 vLightWeighting; 

void main(void) { 
    vec4 mvPosition = uMVMatrix * vec4(aVertex, 1.0); 
    gl_Position = uPMatrix * mvPosition; 
    vTexture = aTexture; 

    int i; 
    for (i = 0; i < 16; i++) { 
     vec3 lightDirection = normalize(uPointLightingLocation[i] - mvPosition.xyz); 
     vec4 transformedNormal = uNMatrix * vec4(aNormal, 1.0); 
     float directionalLightWeighting = max(dot(transformedNormal.xyz, lightDirection), 0.0); 
     if (i == 0) { 
      vLightWeighting = uAmbientColor + uPointLightingColor[i] * directionalLightWeighting; 
     } else { 
      vLightWeighting = vLightWeighting * (uAmbientColor + uPointLightingColor[i] * directionalLightWeighting); 
     } 
    } 
} 

codice che mostra solo l'ultima luce:

for (var light in this.lightsDirection) { 
    gl.uniform3fv(this.shaderProgram.pointLightingLocationUniform, this.lightsDirection[light]); 
    gl.uniform3fv(this.shaderProgram.pointLightingColorUniform, this.lightsColor[light]); 
} 

Come l'uniforme uPointLightingLocation è una matrice vec3 con le dimensioni di 16, ho pensato che sarebbe stato possibile passare l'array completo alla divisa, ma non ho una soluzione funzionante.

Quando provo a passare l'array completo this.lightsColor (senza l'indice) non vedo alcuna luce.

+0

Non vedo perché questa domanda è stata respinta. Sembra perfettamente ragionevole. –

risposta

11

gl.uniform3fv si aspetta una serie appiattita di galleggianti. Inoltre, lo chiami più volte con la stessa posizione uniforme. Quindi, l'ultimo vince. Immagina che uniform3fv sia un comando di copia di basso livello e tu lo dai (destinazione, origine). Copia solo un buffer da un posto all'altro.

Assumendo il tuo esempio ha solo 3 luci, è possibile assegnare la divisa posizione in questo modo:

var locations = [ 
    1.0, 0, 0, 
    0, 1.0, 0, 
    0, 0, 0 
]; 
gl.uniform3fv(shaderProgram.pointLightingLocationUniform, locations); 

Vorrei inoltre consiglia di utilizzare un più semplice di shader quando si esegue il debug problemi come questo. Con qualcosa di simile a quanto segue nel vertex shader:

for (int i = 0; i < 3; i++) { 
    vColor += uPointLightingLocation[i]; 
} 

E frammento di shader:

gl_FragColor = vec4(vColor, 1); 

Quindi, se i poligoni sono di colore giallo si sa che sta lavorando.

+0

Grazie per la vostra risposta ... l'array "appiattito" era quello che mi mancava. Il debug non è un problema, basta cambiare una cosa alla volta e il mio shader ha funzionato bene con una fonte di luce. Grazie! – WarrenFaith

+0

funziona come un incantesimo ... grazie! – WarrenFaith

Problemi correlati