在点光源光照模型中,一个重要的向量就是从物体表面到光源的向量(s)。但如果光源处于无穷远处,那么物体表面所有点到光源的向量可以近似看作是平行的,这样,我们可以用一个方向向量代替原来的光源向量s(比如太阳光就是平行光),通常这类光照模型称作:Directional light source(这类光没有指定位置,只有方向)。
1. 当然这种模型同样忽略了从光源到物体表面光照强度减损的情况。
2. 这种光照模型减少了vertex shader 的计算量(不用计算从物体表面到光源的向量s)
平行光源与点光源的对比:
左边为点光源(positional light),右边为平行光源(directional light)。在左边的的图像中,光源在物体附近,右边的物体大部分被光源照到(由于所有 的光照是平行的)。通常,光源时平行的还是点光源是用光照位置的第四个分量判断,如果第四个分量为0则是平行光源(directinal ),此时位置被认为是方向向量。否则,是点光源,此时位置是从物体表面到光源的方向向量s。
顶点着色器
[cpp]
view plain copyprint?#version 430
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
out vec3 Color;
// Normalized direction towards light source in eye coords.
uniform vec4 LightPosition;
uniform vec3 LightIntensity;
uniform vec3 Kd; // Diffuse reflectivity
uniform vec3 Ka; // Ambient reflectivity
uniform vec3 Ks; // Specular reflectivity
uniform float Shininess; // Specular shininess factor
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;
vec3 ads( vec4 position, vec3 norm )
{
vec3 s;
if( LightPosition.w == 0.0 )
s = normalize(vec3(LightPosition));
else
s = normalize( vec3(LightPosition - position) );
vec3 v = normalize(vec3(-position));
vec3 r = reflect( -s, norm );
return
LightIntensity * ( Ka +
Kd * max( dot(s, norm), 0.0 ) +
Ks * pow( max( dot(r,v), 0.0 ), Shininess ) );
}
void main()
{
vec3 eyeNorm = normalize( NormalMatrix * VertexNormal);
vec4 eyePosition = ModelViewMatrix * vec4(VertexPosition,1.0);;
// Evaluate the lighting equation
Color = ads( eyePosition, eyeNorm );
gl_Position = MVP * vec4(VertexPosition,1.0);
}
片元shader
[cpp]
view plain copyprint?#version 430
in vec3 Color;
layout( location = 0 ) out vec4 FragColor;
void main() {
FragColor = vec4(Color, 1.0);
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。