OpenGL 4.0 GLSL 採用平行光照模型

Sunday發表於2014-02-12

在點光源光照模型中,一個重要的向量就是從物體表面到光源的向量(s)。但如果光源處於無窮遠處,那麼物體表面所有點到光源的向量可以近似看作是平行的,這樣,我們可以用一個方向向量代替原來的光源向量s(比如太陽光就是平行光),通常這類光照模型稱作:Directional  light source(這類光沒有指定位置,只有方向)。

 

1.     當然這種模型同樣忽略了從光源到物體表面光照強度減損的情況。

2.     這種光照模型減少了vertex shader 的計算量(不用計算從物體表面到光源的向量s)

平行光源與點光源的對比:



左邊為點光源(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);
}



相關文章