摄影机旋转时OpenGL点光源移动

摄影机旋转时OpenGL点光源移动,opengl,glsl,Opengl,Glsl,我的场景中有一个点光源。我认为它工作正常,直到我用相机从不同角度观察照亮的物体进行测试,发现光线区域在网格上移动(在我的例子中是简单平面)。我使用的是典型的广告电话照明方式。我在客户端将灯光位置变换为摄影机空间,然后使用模型视图矩阵变换顶点着色器中的插值顶点 我的顶点着色器如下所示: #version 420 layout(location = 0) in vec4 position; layout(location = 1) in vec2 uvs; layout(location =

我的场景中有一个点光源。我认为它工作正常,直到我用相机从不同角度观察照亮的物体进行测试,发现光线区域在网格上移动(在我的例子中是简单平面)。我使用的是典型的广告电话照明方式。我在客户端将灯光位置变换为摄影机空间,然后使用模型视图矩阵变换顶点着色器中的插值顶点

我的顶点着色器如下所示:

#version 420 

layout(location = 0)  in vec4 position;
layout(location = 1)  in vec2 uvs;
layout(location = 2)  in vec3 normal;

uniform mat4 MVP_MATRIX;
uniform mat4 MODEL_VIEW_MATRIX;
uniform mat4 VIEW_MATRIX;
uniform mat3 NORMAL_MATRIX;

uniform vec4 DIFFUSE_COLOR;

//=======  OUTS  ============//
out smooth  vec2 uvsOut;
out flat  vec4 diffuseOut;

out  vec3 Position;
out smooth vec3 Normal;


out gl_PerVertex
{
   vec4 gl_Position;
};

void main()
{
    uvsOut = uvs;
    diffuseOut  =  DIFFUSE_COLOR;
    Normal = normal;
    Position = vec3(MODEL_VIEW_MATRIX * position);

    gl_Position = MVP_MATRIX * position;
}
片段着色器:

//====================  Uniforms  ===============================
struct LightInfo{

 vec4 Lp;///light position
 vec3 Li;///light intensity
 vec3 Lc;///light color
 int  Lt;///light type

};

const int MAX_LIGHTS=5;

uniform LightInfo lights[1];


// material props:
uniform vec3 KD;
uniform vec3 KA;
uniform vec3 KS;
uniform float SHININESS;
uniform int num_lights;

////ADS lighting method :

vec3 pointlightType( int lightIndex,vec3 position , vec3 normal) {

    vec3 n = normalize(normal);
    vec4 lMVPos = lights[0].Lp ;  //
    vec3 s = normalize(vec3(lMVPos.xyz) - position); //surf to light
    vec3 v = normalize(vec3(-position)); //
    vec3 r = normalize(- reflect(s , n));
    vec3 h = normalize(v+s);

    float sDotN = max( 0.0 , dot(s, n) );

    vec3 diff = KD *  lights[0].Lc * sDotN ;
    diff = clamp(diff ,0.0 ,1.0);

    vec3 spec = vec3(0,0,0);

    if (sDotN > 0.0) {
        spec = KS * pow( max( 0.0 ,dot(n,h) ) ,  SHININESS);
        spec = clamp(spec ,0.0 ,1.0);
    }

    return lights[0].Li *  ( spec+diff);
}
我已经学习了很多教程,但没有一个教程对变换空间的整个过程进行了透彻的解释。我怀疑这与我将灯光和顶点位置变换到的摄影机空间有关。在我的例子中,视图矩阵是使用

  glm::lookAt()
它总是否定“眼睛”向量,所以我的着色器中的视图矩阵否定了平移部分。应该是这样的吗?有人能详细解释一下如何在可编程管道中以正确的方式完成吗?我的着色器是基于《OpenGL 4.0着色语言烹饪书》一书实现的。作者似乎也使用了相机空间。但它不能正常工作,除非这是它应该工作的方式


我刚刚将计算移动到世界空间。现在点光源保持在点上。但是如何使用摄影机空间实现相同的效果

我锁定了这个bug,它非常愚蠢。但是它可能对其他太“数学友好”的人有帮助。我在着色器中的灯光位置是用vec3定义的。现在,在客户端,它是用vec4表示的。在用视图矩阵转换它之前,我有效地将vec4的.w分量每次设置为等于零。我相信这样做,灯光位置向量未正确变换,因此所有灯光位置问题都源于着色器。解决方案是使灯光位置向量的w分量始终等于1。

片段着色器是否也使用了
\version 420
?是的,着色器本身没有问题,所有的制服和属性都很好。看起来你没有将法线转换成相机空间(使用MV矩阵,就像你对位置所做的那样)。这可能是问题所在吗?好吧,这可能是我错过的……嗯,我做的正常转换是正确的,但我发现了问题。真是愚蠢的一个;)