我爲照明實現了一個簡單的着色器;它有點作用,但當相機旋轉時(並且只有當它旋轉時),光似乎會移動。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