Opengl blinn灯光模型中灯光的位置
我在片段着色器中实现了Blinn Phong着色,以计算具有多个灯光的每个片段的照明。除了一部分之外,计算似乎都很好。我的平行光计算正确,但我的位置光计算不正确 图片比文字更能说明问题,因此: 错误的灯光位置: 着色器的工作原理如下: 我用它们在世界空间中的位置更新灯光阵列。然后,对于每个对象,我上传它们的材质信息,并使用片段着色器绘制它们,以获得正确的颜色。顶点着色器关于照明的唯一任务是传递片段的法线。我所有的计算都是在世界空间中进行的 我已经检查了每个灯的位置,它们是正确的。这就是我来这里的原因。我想我在计算入射角的余弦时犯了一个错误,但我不知道在哪里 以下是我的片段着色器的代码: 编辑:我在Nico Schertler的帮助下纠正了一些错误,下面是使用片段和顶点着色器的新代码 编辑2:经过另一轮的检查,它实际上并不是一个错误的灯光位置。但是,在计算法线方向和灯光方向之间的点矢量时存在错误 片段着色器Opengl blinn灯光模型中灯光的位置,opengl,glsl,shader,opengl-3,fragment-shader,Opengl,Glsl,Shader,Opengl 3,Fragment Shader,我在片段着色器中实现了Blinn Phong着色,以计算具有多个灯光的每个片段的照明。除了一部分之外,计算似乎都很好。我的平行光计算正确,但我的位置光计算不正确 图片比文字更能说明问题,因此: 错误的灯光位置: 着色器的工作原理如下: 我用它们在世界空间中的位置更新灯光阵列。然后,对于每个对象,我上传它们的材质信息,并使用片段着色器绘制它们,以获得正确的颜色。顶点着色器关于照明的唯一任务是传递片段的法线。我所有的计算都是在世界空间中进行的 我已经检查了每个灯的位置,它们是正确的。这就是我来这里的
您不应该将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.));
}