为什么我的相机移动灯光?在我的绘制场景功能中,我设置了我的光源位置,然后我调用我的矩阵,翻译"相机",然后是球体,然后是两个立方体。当我将相机与第一个立方体一起移动时,光源随之移动......
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 :(得分:1)
uPointLightingLocation
必须位于眼睛空间中,与您将其与点积进行比较的transformedNormal
匹配。
通过视图 / 相机矩阵乘以lightPosition
(假设它在世界空间中)。在着色器外部执行此操作会更便宜,因为在渲染过程中值不会发生变化。
视图矩阵已经存在于代码中间的 model-view 构造中。
//Camera
块是视图,//Sphere
块在模型转换中相乘。要仅提取视图,请在mvMatrix
和Camera
转换块之间复制Sphere
(或者只转换灯光然后转换灯光)。
//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
...