opengl-使用着色器时相机旋转时聚光灯移动
我为灯光实现了一个简单的着色器;这是一种工作方式,但是当相机旋转时(并且只有当它旋转时),光线似乎会移动 我正在试验聚光灯,这是它看起来的样子(它是中心的聚光灯): 如果现在我旋转相机,聚光灯会四处移动;例如,在这里,我向下看(我一点也不动,只是向下看),它似乎在我的脚边: 我查过了,发现在着色器中混合参考系统和/或在移动摄影机之前设置灯光位置时,这是一个常见的错误 问题是,我很确定我没有做这两件事,但显然我错了;只是我找不到窃听器 以下是着色器: 顶点着色器opengl-使用着色器时相机旋转时聚光灯移动,opengl,glsl,shader,light,Opengl,Glsl,Shader,Light,我为灯光实现了一个简单的着色器;这是一种工作方式,但是当相机旋转时(并且只有当它旋转时),光线似乎会移动 我正在试验聚光灯,这是它看起来的样子(它是中心的聚光灯): 如果现在我旋转相机,聚光灯会四处移动;例如,在这里,我向下看(我一点也不动,只是向下看),它似乎在我的脚边: 我查过了,发现在着色器中混合参考系统和/或在移动摄影机之前设置灯光位置时,这是一个常见的错误 问题是,我很确定我没有做这两件事,但显然我错了;只是我找不到窃听器 以下是着色器: 顶点着色器 varying vec3 ve
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);
}
片段着色器
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);
}
其中:
- SetupLights包含设置灯光及其位置的实际opengl调用李>
- UpdateCamera使用语言的内置类更新相机的位置;我在这里没有多少权力李>
- RenderStuff调用语言的内置函数来绘制场景;我在这里也没有多少权力
另一方面,您的眼向量看起来应该在视图坐标中,但是,视图空间是右手坐标系,因此沿负z轴“向前”点。此外,您的镜面反射计算可能会关闭,因为您对所有碎片使用相同的眼向量,但它可能会指向该碎片在近/远平面上的位置。我的错误,灯光的位置在着色器的视图空间中。我认为你在其他方面是对的,但仍然不能找到真正的问题。如果你的灯光位置在视野空间中,你必须在相机改变时更新它。您在
UpdateCamera()
之前的SetupLights()
序列在概念上似乎是错误的。我的错误是,灯光的位置在着色器的视图空间中。我认为你在其他方面是对的,但仍然不能找到真正的问题。如果你的灯光位置在视野空间中,你必须在相机改变时更新它。您在UpdateCamera()
之前的SetupLights()
顺序在概念上似乎是错误的。