所以我在我的一些模型上使用blinn着色器程序,它使用DIRECTIONAL灯而不是点光源。我开始使用点光源的原始代码:
VERTEX:
varying vec3 Half;
varying vec3 Light;
varying vec3 Normal;
varying vec4 Ambient;
void main()
{
// Vertex location in modelview coordinates
vec3 P = vec3(gl_ModelViewMatrix * gl_Vertex);
Light = vec3(gl_LightSource[0].position) - P;
Normal = gl_NormalMatrix * gl_Normal;
Half = gl_LightSource[0].halfVector.xyz;
Ambient = gl_FrontMaterial.emission + gl_FrontLightProduct[0].ambient + gl_LightModel.ambient*gl_FrontMaterial.ambient;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
FRAGMENT:
varying vec3 Half;
varying vec3 Light;
varying vec3 Normal;
varying vec4 Ambient;
uniform sampler2D tex;
vec4 blinn()
{
vec3 N = normalize(Normal);
vec3 L = normalize(Light);
vec4 color = Ambient;
float Id = dot(L,N);
if (Id>0.0)
{
color += Id*gl_FrontLightProduct[0].diffuse;
vec3 H = normalize(Half);
float Is = dot(H,L); // Specular is cosine of reflected and view vectors
if (Is>0.0) color += pow(Is,gl_FrontMaterial.shininess)*gl_FrontLightProduct[0].specular;
}
return color;
}
void main()
{
gl_FragColor = blinn() * texture2D(tex,gl_TexCoord[0].xy);
}
然而,如上所述,我想要一个定向光,而不是点光源,这样无论在场景中的哪个位置,模型都是光的方向是相同的。所以我做了以下更改:
而不是:
varying vec3 Light;
和
vec3 P = vec3(gl_ModelViewMatrix * gl_Vertex);
Light = vec3(gl_LightSource[0].position) - P;
我摆脱了上面的代码行,而在我的片段着色器中有:
uniform vec4 lightDir;
和
vec3 L = normalize(lightDir.xyz);
我将光的方向作为我的着色器程序之外的制服传递,这很好用:无论它在世界上的位置,模型都从单一方向点亮! HOWEVER ,现在根据用户的视图,灯光变化剧烈且不切实际,这是有道理的,因为我在原始代码的灯光计算中摆脱了(“ - P”)。我已经尝试将其添加到代码中(通过将lightDir移回到顶点着色器并再次将其传递到各种变化中)到我所拥有的并且它只是不能解决问题。我担心我只是不明白什么进展得很好,我明白Light-vec3的“-P”是必要的:使镜面/反射工作,但我不知道如何使它适用于定向灯。如何制作上述原始代码,并将光线视为定向光而不是点光源?