2011-01-18 17 views
6

Estoy tratando de implementar varias luces en mi sombreador pero tengo problemas para llenar el uniforme con mis datos de luz.Pasar una matriz de vectores a un uniforme

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

código que muestra sólo la última luz:

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

Como el uniforme uPointLightingLocation es una matriz vec3 con el tamaño de 16, pensé que sería es posible pasar el conjunto completo al uniforme, pero no tengo una solución funcional.

Cuando intento pasar la matriz completa this.lightsColor (sin el índice) no veo ninguna luz.

+0

No veo por qué esta pregunta fue rechazada. Parece perfectamente razonable. –

Respuesta

11

gl.uniform3fv espera una matriz aplanada de flotadores. Además, lo está llamando varias veces con la misma ubicación uniforme. Entonces, el último gana. Imagine que uniform3fv es un comando de copia de bajo nivel, y usted le da (destino, fuente). Simplemente copia un buffer de un lugar a otro.

Asumiendo que su ejemplo tiene sólo 3 luces, podría asignar el uniforme ubicación de esta manera:

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

También recomendaría el uso de un sombreado más simple cuando se está depurando problemas de este tipo. Con algo así como lo siguiente en su vertex shader:

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

y el fragmento de sombreado:

gl_FragColor = vec4(vColor, 1); 

Entonces, si los polígonos son de color amarillo que saber si está funcionando.

+0

Gracias por su respuesta ... el arreglo "aplanar" era lo que me estaba perdiendo. La depuración no es realmente un problema siempre que solo cambies una cosa a la vez y mi sombreador funcionó bien con una fuente de luz. ¡Gracias! – WarrenFaith

+0

funciona como charme ... ¡gracias! – WarrenFaith

Cuestiones relacionadas