2014-09-22 25 views
0

爲什麼我的光線會隨着相機移動?在我的繪畫場景功能中,我設置了光源位置,然後調用我的矩陣,翻譯「相機」,然後是一個球體,並在兩個立方體之後。當我將相機與第一個立方體一起移動時,光源隨之移動...當物體被翻譯時,靜態光線會繼續移動

function drawScene() { 
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); 
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 

    mat4.perspective(45, gl.viewportWidth/gl.viewportHeight, 0.1, 100.0, pMatrix); 

    //currentProgram = perFragmentProgram; 
    currentProgram = perVertexProgram; 
    gl.useProgram(currentProgram); 

    gl.uniform3f(
     currentProgram.ambientColorUniform, 
     parseFloat(document.getElementById("ambientR").value), 
     parseFloat(document.getElementById("ambientG").value), 
     parseFloat(document.getElementById("ambientB").value) 
    ); 

    gl.uniform3f(
     currentProgram.pointLightingLocationUniform, 
     parseFloat(document.getElementById("lightPositionX").value), 
     parseFloat(document.getElementById("lightPositionY").value), 
     parseFloat(document.getElementById("lightPositionZ").value) 
    ); 

    gl.uniform3f(
     currentProgram.pointLightingColorUniform, 
     parseFloat(document.getElementById("pointR").value), 
     parseFloat(document.getElementById("pointG").value), 
     parseFloat(document.getElementById("pointB").value) 
    ); 

    mat4.identity(mvMatrix); 

    //Camera 
    mat4.translate(mvMatrix, [-xPos, -yPos, -10]); 
    mat4.rotate(mvMatrix, degToRad(180), [0, 1, 0]); 

    //Sphere 
    mvPushMatrix(); 
    mat4.rotate(mvMatrix, degToRad(moonAngle), [0, 1, 0]); 
    mat4.translate(mvMatrix, [5, 0, 0]); 

    gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer); 
    gl.vertexAttribPointer(currentProgram.vertexPositionAttribute, moonVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); 

    gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer); 
    gl.vertexAttribPointer(currentProgram.vertexNormalAttribute, moonVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0); 

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer); 
    setMatrixUniforms(); 
    gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0); 
    mvPopMatrix(); 

    //Cube 1 
    object.render(xPos, yPos); 

    //Cube 2 
    object2.render(0, 5); 
} 

而且我的着色器看起來像這樣。

<script id="per-vertex-lighting-fs" type="x-shader/x-fragment"> 
precision mediump float; 

varying vec3 vLightWeighting; 

void main(void) { 
    vec4 fragmentColor; 
    fragmentColor = vec4(1.0, 1.0, 1.0, 1.0); 
    gl_FragColor = vec4(fragmentColor.rgb * vLightWeighting, fragmentColor.a); 
} 
</script> 

<script id="per-vertex-lighting-vs" type="x-shader/x-vertex"> 
attribute vec3 aVertexPosition; 
attribute vec3 aVertexNormal; 

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

uniform vec3 uAmbientColor; 

uniform vec3 uPointLightingLocation; 
uniform vec3 uPointLightingColor; 

uniform bool uUseLighting; 

varying vec2 vTextureCoord; 
varying vec3 vLightWeighting; 

void main(void) { 
    vec4 mvPosition = uMVMatrix * vec4(aVertexPosition, 1.0); 
    gl_Position = uPMatrix * mvPosition; 


    vec3 lightDirection = normalize(uPointLightingLocation - mvPosition.xyz); 

    vec3 transformedNormal = uNMatrix * aVertexNormal; 
    float directionalLightWeighting = max(dot(transformedNormal, lightDirection), 0.0); 

    vLightWeighting = uAmbientColor + uPointLightingColor * directionalLightWeighting; 

} 
</script> 

我能做些什麼,以被搬來搬去,從而阻止了光線的靜態

+0

這聽起來很愚蠢,但那些點光計算?他們看起來像方向計算。它看起來不像在vert或shader着色器中使用'lightPositionX/Y/Z'。 – zero298 2014-09-22 16:01:01

+0

我不確定...我對glsl非常陌生..如何更改uPointLightLocation來計算位置而不是方向 – namenamesoseji 2014-09-22 16:05:10

+0

'uPointLightingLocation'必須位於*眼睛空間*中,與'transformedNormal'匹配,重新比較它。在傳遞之前,將'lightPosition'(假設它在世界空間中)乘以視圖/相機矩陣。 – jozxyqk 2014-09-23 06:47:53

回答

1

uPointLightingLocation必須在眼空間,匹配transformedNormal其中你比較它與點積。

乘法lightPosition(假設它是在世界的空間)由視圖/相機矩陣。在着色器之外執行此操作會更便宜,因爲在渲染過程中值不會更改。

查看矩陣已經存在於您的代碼中途通過模型視圖構造。 //Camera區塊是視圖//Sphere區塊在型號變換中相乘。要僅提取視圖,請在CameraSphere之間複製mvMatrix變換塊(或者只是在時間和空間處轉換光線)。

//untested, but something along these lines 
var worldSpaceLight = vec4.fromValues(//not sure which lib your using 
    parseFloat(document.getElementById("lightPositionX").value), 
    parseFloat(document.getElementById("lightPositionY").value), 
    parseFloat(document.getElementById("lightPositionZ").value), 
    1.0 
); 
... 
//Camera 
... 
var eyeSpaceLight = vec4.create(); 
vec4.transformMat4(eyeSpaceLight, worldSpaceLight, mvMatrix); 
gl.uniform3f(currentProgram.pointLightingLocationUniform, eyeSpaceLight); 
//Sphere 
... 
+0

非常感謝,這幫助我弄明白了! – namenamesoseji 2014-09-25 17:29:50