2011-01-18 15 views
6

シェーダに複数のライトを実装しようとしていますが、ライトデータで均一に塗りつぶすのに問題があります。ベクトルの配列をユニフォームに渡す

マイ頂点シェーダ:のみ最新の光を示し

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

はコード:制服uPointLightingLocationとして

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

は16のサイズとvec3配列である、私はそれが可能だろうと思いました完全な配列を均一に渡すことは可能ですが、私は実際の解決策はありません。

完全な配列this.lightsColor(インデックスなし)を渡そうとすると、全く光が見えません。

+0

この質問が投票された理由はわかりません。完全に合理的だと思われる。 –

答えて

11

gl.uniform3fvは、floatのフラットな配列が必要です。また、同じ場所に複数回呼び出すこともできます。だから、最後のものが勝つ。 uniform3fvが低レベルのコピーコマンドであり、それを(相手先、ソース)与えるとします。ある場所から別の場所にバッファをコピーするだけです。

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

私はまた、あなたがこのような問題をデバッグするより簡単なシェーダを使用することをお勧めします:

あなたの例では、唯一の3のライトを持っていると仮定すると、あなたは場所の制服をこのように割り当てることができます。

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

とフラグメントシェーダ:あなたのバーテックスシェーダで、次のようなもので、あなたのポリゴンが黄色で表示された場合

gl_FragColor = vec4(vColor, 1); 

その後、あなたはそれが働いている知っています。

+0

あなたのお返事ありがとうございます... "平坦化された"配列は私が欠けていたものでした。一度に1つのものを変更するだけで、シェーダが1つの光源でうまく動作する限り、デバッグは実際問題ではありません。ありがとう! – WarrenFaith

+0

はcharmeのように動作します...ありがとう! – WarrenFaith

関連する問題