我为照明实现了一个简单的着色器;它有点作用,但当相机旋转时(并且只有当它旋转时),光似乎会移动。opengl - 当使用着色器时相机旋转时聚光灯移动
如果现在我旋转的摄像头,现场到处移动;例如,在这里我向下看(我根本没有动,只是朝下看),它似乎在我的脚下:
我已经看过了,我已经看到,这是一个常见的错误在着色器中混合参考系统和/或在移动相机之前设置光的位置。
事情是,我很确定我没有做这两件事,但显然我错了;这只是我找不到错误。
这里的着色器:
的Vertex Shader
varying vec3 vertexNormal;
varying vec3 lightDirection;
void main()
{
vertexNormal = gl_NormalMatrix * gl_Normal;
lightDirection = vec3(gl_LightSource[0].position.xyz - (gl_ModelViewMatrix * gl_Vertex).xyz);
gl_Position = ftransform();
}
片段着色器
uniform vec3 ambient;
uniform vec3 diffuse;
uniform vec3 specular;
uniform float shininess;
varying vec3 vertexNormal;
varying vec3 lightDirection;
void main()
{
vec3 color = vec3(0.0, 0.0, 0.0);
vec3 lightDirNorm;
vec3 eyeVector;
vec3 half_vector;
float diffuseFactor;
float specularFactor;
float attenuation;
float lightDistance;
vec3 normalDirection = normalize(vertexNormal);
lightDirNorm = normalize(lightDirection);
eyeVector = vec3(0.0, 0.0, 1.0);
half_vector = normalize(lightDirNorm + eyeVector);
diffuseFactor = max(0.0, dot(normalDirection, lightDirNorm));
specularFactor = max(0.0, dot(normalDirection, half_vector));
specularFactor = pow(specularFactor, shininess);
color += ambient * gl_LightSource[0].ambient;
color += diffuseFactor * diffuse * gl_LightSource[0].diffuse;
color += specularFactor * specular * gl_LightSource[0].specular;
lightDistance = length(lightDirection[i]);
float constantAttenuation = 1.0;
float linearAttenuation = (0.02/SCALE_FACTOR) * lightDistance;
float quadraticAttenuation = (0.0/SCALE_FACTOR) * lightDistance * lightDistance;
attenuation = 1.0/(constantAttenuation + linearAttenuation + quadraticAttenuation);
// If it's a spotlight
if(gl_LightSource[i].spotCutoff <= 90.0)
{
float spotEffect = dot(normalize(gl_LightSource[0].spotDirection), normalize(-lightDirection));
if (spotEffect > gl_LightSource[0].spotCosCutoff)
{
spotEffect = pow(spotEffect, gl_LightSource[0].spotExponent);
attenuation = spotEffect/(constantAttenuation + linearAttenuation + quadraticAttenuation);
}
else
attenuation = 0.0;
}
color = color * attenuation;
// Moltiplico il colore per il fattore di attenuazione
gl_FragColor = vec4(color, 1.0);
}
现在,我不能告诉你,我渲染的东西的代码,因为它是一种集成了opengl和用于创建3D应用程序的自定义语言(这无助于向你展示);但我做的是这样的:
SetupLights();
UpdateCamera();
RenderStuff();
其中:
- SetupLights包含实际的OpenGL调用设置灯光和它们的位置;
- UpdateCamera使用语言的内置类更新相机的位置;我在这里没有太多的权力;
- RenderStuff调用语言的内置函数来绘制场景;我也没有太多的权力。
因此,无论我在着色器中做错了什么,或者在“幕后”语言中有什么东西会破坏事情。
您能否指点我正确的方向?
我的错误,光线的位置是在着色器中的视角空间。 我认为你对其他事情是正确的,但仍然无法找到真正的问题。 – Beriol
如果您的照明位置在视野范围内,则每当照相机发生变化时您都必须更新。在UpdateCamera()之前,你的'SetupLights()'序列在概念上似乎是错误的。 – derhass