Opengl blinn灯光模型中灯光的位置

Opengl blinn灯光模型中灯光的位置,opengl,glsl,shader,opengl-3,fragment-shader,Opengl,Glsl,Shader,Opengl 3,Fragment Shader,我在片段着色器中实现了Blinn Phong着色,以计算具有多个灯光的每个片段的照明。除了一部分之外,计算似乎都很好。我的平行光计算正确,但我的位置光计算不正确 图片比文字更能说明问题,因此: 错误的灯光位置: 着色器的工作原理如下: 我用它们在世界空间中的位置更新灯光阵列。然后,对于每个对象,我上传它们的材质信息,并使用片段着色器绘制它们,以获得正确的颜色。顶点着色器关于照明的唯一任务是传递片段的法线。我所有的计算都是在世界空间中进行的 我已经检查了每个灯的位置,它们是正确的。这就是我来这里的

我在片段着色器中实现了Blinn Phong着色,以计算具有多个灯光的每个片段的照明。除了一部分之外,计算似乎都很好。我的平行光计算正确,但我的位置光计算不正确

图片比文字更能说明问题,因此:

错误的灯光位置:

着色器的工作原理如下:

我用它们在世界空间中的位置更新灯光阵列。然后,对于每个对象,我上传它们的材质信息,并使用片段着色器绘制它们,以获得正确的颜色。顶点着色器关于照明的唯一任务是传递片段的法线。我所有的计算都是在世界空间中进行的

我已经检查了每个灯的位置,它们是正确的。这就是我来这里的原因。我想我在计算入射角的余弦时犯了一个错误,但我不知道在哪里

以下是我的片段着色器的代码:

编辑:我在Nico Schertler的帮助下纠正了一些错误,下面是使用片段和顶点着色器的新代码

编辑2:经过另一轮的检查,它实际上并不是一个错误的灯光位置。但是,在计算法线方向和灯光方向之间的点矢量时存在错误

片段着色器


您不应该将lightDirection和positionToLightSource作为vec4处理。在灯[i]上进行w型夹持。从那时起定位并使用vec3。规范化vec4不会产生正确的方向。worldNormal和position也一样。谢谢你的回答,谢谢你纠正了我的英语错误,也谢谢你解决了vec4的正常化问题。但是它没有解决主要问题。你能更新你问题中的代码吗?在这里,我添加顶点着色器,看看我是否也做对了。
#version 330 compatibility

struct light {
   vec4 position; // position.w indicates if it's a direction or point lighting
   vec3 diffuse; // diffuse color of the light
   vec3 specular; // specular color of the light
   float attenuation; // attenuation of the light
};
struct material {
   vec3 diffuse;
   vec3 specular;
   vec3 ambient;
   float shininess;
};

uniform material objMaterial;
uniform light lights[9];
uniform int nbLight;
uniform mat4 viewMatrix; // Matrix to view coordinate
uniform mat4 viewInvMatrix; // invert view matrix to find the position of the viewer

in vec3 worldNormal; // normal in worldspace
in vec3 position; // position in worldspace

vec3 ambiant = vec3(0.2,0.2,0.2);

void main()
{
   int i;
   vec3 viewDirection = normalize((viewInvMatrix * vec4(0.0, 0.0, 0.0, 1.0) - vec4(position, 1.)).xyz);
   vec3 lightDirection, lightPositon;
   vec3 normalizeWorldNormal = normalize(worldNormal);
   float attenuation; 
   vec3 totalLight = ambiant * objMaterial.ambient;
   float cosAngIncidence;
   float blinnTerm;

   for(i=0; i<9; i=i+1){
      if(i < nbLight){
         lightPositon = lights[i].position.xyz;
         if (0.0 == lights[i].position.w) // directional light?
         {
            attenuation = 1.0; // no attenuation
            lightDirection = normalize(lightPositon);
         }
         else // point light
         {
            vec3 positionToLightSource = lightPositon - position;
            lightDirection = normalize(positionToLightSource);
            float dis = length(positionToLightSource);
            attenuation = 1.0 / (lights[i].attenuation * dis);
         }
         cosAngIncidence = dot(normalizeWorldNormal, lightDirection);
         cosAngIncidence = clamp(cosAngIncidence, 0, 1);

         vec3 halfAngle = normalize(lightDirection + viewDirection);
         blinnTerm = dot(normalizeWorldNormal, halfAngle);
         blinnTerm = clamp(blinnTerm, 0, 1);
         blinnTerm = cosAngIncidence != 0.0 ? blinnTerm : 0.0;
         blinnTerm = pow(blinnTerm, objMaterial.shininess*5);

         totalLight = totalLight
            + (lights[i].diffuse * objMaterial.diffuse * attenuation * cosAngIncidence)
            + (lights[i].specular * objMaterial.specular * attenuation * blinnTerm);
      }
   }
   gl_FragColor = vec4(totalLight.xyz, 1.0);
}
#version 330 compatibility

layout(location=0) in vec3 vx_pos;
layout(location=1) in vec3 vx_nor;
layout(location=3) in vec3 vx_col;

uniform mat4 modelMatrix; // Matrix to world coordinate
uniform mat4 normalInvTransMatrix; // Matrix for normal in world coordinate
uniform mat4 viewMatrix; // Matrix to view coordinate
uniform mat4 projectionMatrix; // Matrix to projection coordinate

out vec3 worldNormal; 
out vec3 position;

void main() {
   gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(vx_pos,1.0);
   worldNormal = vec3(normalInvTransMatrix * vec4(vx_nor, 0.));
   position = vec3(modelMatrix * vec4(vx_pos,0.)); 
}