【问题标题】:Static light keeps moving when objects are translated物体平移时静态光会继续移动
【发布时间】:2014-09-24 20:41:00
【问题描述】:

为什么我的灯会随着相机移动?在我的绘图场景函数中,我设置了我的光源位置,然后我调用我的矩阵,平移“相机”,然后是一个球体,然后是两个立方体。当我随着第一个立方体移动相机时,光源也随之移动......

 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>

我能做些什么来阻止灯光四处移动,使其保持静止

【问题讨论】:

  • 这听起来很愚蠢,但这些是点光计算吗?它们看起来像定向计算。看起来您从未在 vert 或 frag 着色器中使用过 lightPositionX/Y/Z
  • 我不确定...我对 glsl 非常陌生。我如何更改 uPointLightLocation 来计算位置而不是方向
  • uPointLightingLocation 必须在 眼睛空间 中,与您要与之比较的 transformedNormal 匹配。将lightPosition(假设它在世界空间中)乘以视图/相机矩阵,然后再将其传入。
  • 如何将视图矩阵与 uMVMatrix 分开?对不起,我真的很陌生,有什么办法可以编辑上面的代码,这样我就可以明白你的意思了?我认为我学习的唯一方法就是看到它@jozxyqk

标签: opengl glsl webgl


【解决方案1】:

uPointLightingLocation 必须在 眼睛空间 中,与您要与之比较的 transformedNormal 与点积相匹配。

lightPosition(假设它在世界空间中)乘以view/camera 矩阵。在着色器之外执行此操作会更便宜,因为在渲染期间值不会改变。

view 矩阵在 model-view 构造的中途已经存在于您的代码中。 //Camera 块是 view//Sphere 块在 model 变换中相乘。要仅提取 视图,请在 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
...

【讨论】:

  • 非常感谢,这帮助我弄清楚了!
猜你喜欢
  • 2015-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 2011-12-03
  • 1970-01-01
相关资源
最近更新 更多