Pregunta

Estoy tratando de implementar múltiples luces en mi shader, pero tengo problemas para llenar el uniforme con los datos de mi luz.

Mi sombreado de vértices:

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

El 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]);
}

A medida que el uPointLightingLocation uniforme es una matriz de vec3 con el tamaño de 16, pensé que sería posible pasar la matriz completa a la uniforme, pero no tengo solución de trabajo.

Cuando trato de pasar el this.lightsColor completa gama (sin el índice) no veo ninguna luz en absoluto.

¿Fue útil?

Solución

gl.uniform3fv espera una matriz aplanada de flotadores. Además, a la que llama varias veces con la misma ubicación uniforme. Así, el último gana. Imaginar que uniform3fv es un comando de copia bajo nivel, y lo das (destino, origen). Es 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 como lo siguiente en su vertex shader:

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

Y fragmento shader:

gl_FragColor = vec4(vColor, 1);

Entonces, si los polígonos son de color amarillo que sabes que está trabajando.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top