C++ OpenGL:如何使光独立于旋转?

C++ OpenGL:如何使光独立于旋转?,c++,opengl,rotation,shader,lighting,C++,Opengl,Rotation,Shader,Lighting,我有一个漫反射照明着色器,它似乎在对象不旋转时工作。但是,当我应用旋转变换时,灯光似乎也会随着对象旋转。这就像物体和光线保持静止,但相机是围绕物体移动的 以下是我的顶点着色器代码: #version 110 uniform mat4 projectionMatrix; uniform mat4 modelviewMatrix; uniform vec3 lightSource; attribute vec3 vertex; attribute vec3 normal; varying ve

我有一个漫反射照明着色器,它似乎在对象不旋转时工作。但是,当我应用旋转变换时,灯光似乎也会随着对象旋转。这就像物体和光线保持静止,但相机是围绕物体移动的

以下是我的顶点着色器代码:

#version 110

uniform mat4 projectionMatrix;
uniform mat4 modelviewMatrix;
uniform vec3 lightSource;

attribute vec3 vertex;
attribute vec3 normal;

varying vec2 texcoord;

void main() {
    gl_Position = projectionMatrix * modelviewMatrix * vec4( vertex, 1.0 );

    vec3 N = gl_NormalMatrix * normalize( normal );
    vec4 V = modelviewMatrix * vec4( vertex, 1.0 );
    vec3 L = normalize( lightSource - V.xyz );

    float NdotL = max( 0.0, dot( N, L ) );

    gl_FrontColor = vec4( gl_Color.xyz * NdotL, 1.0 );

    gl_TexCoord[0] = gl_MultiTexCoord0;
}
下面是进行旋转的代码:

scene.LoadIdentity();
scene.Translate( 0.0f, -5.0f, -20.0f );
scene.Rotate( angle, 0.0f, 1.0f, 0.0f );
object->Draw();
我通过一个glUniform3f,在object->Draw()函数中发送了眼睛空间的光线位置。灯光位置是静态的,定义为:

glm::vec4 lightPos( light.x, light.y, light.z, 1.0 );
glm::vec4 lightEyePos = modelviewMatrix * lightPos;
glUniform3f( uniforms.lightSource, lightEyePos.x, lightEyePos.y, lightEyePos.z );
这种方法有什么问题

编辑:glm::lookAt代码

Scene scene;
scene.LoadMatrix( projection );
scene.SetMatrixMode( Scene::Modelview );
scene.LoadIdentity();
scene.SetViewMatrix( glm::lookAt( glm::vec3( 0.0f, 0.0f, 0.0f ), glm::vec3( 0.0f, -5.0f, -20.0f ), glm::vec3( 0.0f, 1.0f, 0.0f ) ) );
SetViewMatrix代码:

void Scene::SetViewMatrix( const glm::mat4 &matrix ) {
    viewMatrix = matrix;
    TransformMatrix( matrix );
}
然后我只是将我使用的modelviewMatrix更改为viewMatrix:

glm::vec4 lightPos( light.x, light.y, light.z, 1.0 );
glm::vec4 lightEyePos = viewMatrix * lightPos;
glUniform3f( uniforms.lightSource, lightEyePos.x, lightEyePos.y, lightEyePos.z );
语句1:灯的位置是静态的

语句2:
lightEyePos=modelviewMatrix*lightPos

这两种说法不一致。如果灯光位置应该是静态的,则不应该对其应用旋转模型矩阵


如果lightPos是在世界坐标中定义的,则应将其与
viewMatrix
相乘,而不是与
modelviewMatrix
相乘。modelviewMatrix包含模型矩阵,其中包含模型的旋转(您不希望将此应用于固定光源)。

我猜您的眼睛空间灯光位置不正确。你是怎么产生的?我当然希望是这样。我是这样做的:glm::vec4lightpos(light.x,light.y,light.z,1.0);glm::vec4 lightEyePos=模型视图矩阵*lightPos;glUniform3f(制服光源、光源位置x、光源位置y、光源位置z);啊,我不知道你能把它们分开。我会试试你的建议,看看效果如何。由于某种原因,它仍然不起作用。我使用glm::lookAt函数创建的视图矩阵乘以灯光位置。对吗?因为我从来没有真正修改过相机的位置,所以我也尝试过只发送灯光位置值而不进行转换,但它仍然是一样的。@JackyBoen:我本以为glm::lookAt矩阵就是您需要使用的。如果这不起作用,您能否清楚地描述您得到的新结果,并将所有更新的代码(使用lookAt作为视图矩阵)添加到原始帖子的附加编辑中?不要费心尝试在着色器中使用原始光坐标,除非你在世界空间中完成所有的光照方程,否则它不会工作。我得到的结果是,光线似乎仍然随着球体旋转(我的对象是球体)。所以它看起来有点像月球相变。@JackyBoen嗯,对不起,我不明白为什么它不起作用。我仍然很确定我的建议是正确的(似乎很多人都同意),但我无法解释为什么它不能正确旋转,除非代码中有我看不到的其他东西。