OpenGL 4.0 GLSL 采用平行光照模型

在点光源光照模型中,一个重要的向量就是从物体表面到光源的向量(s)。但如果光源处于无穷远处,那么物体表面所有点到光源的向量可以近似看作是平行的,这样,我们可以用一个方向向量代替原来的光源向量s(比如太阳光就是平行光),通常这类光照模型称作:Directional  light source(这类光没有指定位置,只有方向)。

 

1.     当然这种模型同样忽略了从光源到物体表面光照强度减损的情况。

2.     这种光照模型减少了vertex shader 的计算量(不用计算从物体表面到光源的向量s)

平行光源与点光源的对比:

OpenGL 4.0 GLSL 采用平行光照模型_第1张图片


左边为点光源(positional  light),右边为平行光源(directional  light)。在左边的的图像中,光源在物体附近,右边的物体大部分被光源照到(由于所有 的光照是平行的)。通常,光源时平行的还是点光源是用光照位置的第四个分量判断,如果第四个分量为0则是平行光源(directinal ),此时位置被认为是方向向量。否则,是点光源,此时位置是从物体表面到光源的方向向量s。


顶点着色器

#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

#version 430

in vec3 Color;

layout( location = 0 ) out vec4 FragColor;

void main() {
    FragColor = vec4(Color, 1.0);
}



你可能感兴趣的:(GLSL,GLSL,4.0,算法和特效)