GLSL学习笔记 - 6.2 Vertex Shader

一个简单的逐顶点光照模型。光照效果由散射光和镜面反射光构成。

程序流程
转化顶点与法线到当前的眼坐标系中
vec3 ecPosition   
= vec3 (gl_ModelViewMatrix * gl_Vertex);
vec3 tnorm        
= normalize(gl_NormalMatrix * gl_Normal);

得到 顶点->光源向量 与 顶点
->观察点向量
vec3 lightVec     
= normalize(LightPosition - ecPosition);
vec3 viewVec      
= normalize(-ecPosition);

根据 入射光线向量 计算反射光线向量
vec3 reflectVec   
= reflect(-lightVec, tnorm);

假设漫反射光线强度随入射光线与法线夹角呈余弦分布,
则漫反射光照强度可以近似为
float diffuse     = max(dot(lightVec, tnorm), 0.0);

假设镜面反射光线强度随反射光线与观察方向夹角呈余弦分布,
则镜面反射光照强度可以近似为
spec              
= max(dot(reflectVec, viewVec), 0.0);
随后增强镜面反射聚集度
spec              
= pow(spec, 16.0);

最后通过混合散射光与镜面光强度获得该顶点光线强度
LightIntensity    
= DiffuseContribution * diffuse + SpecularContribution * spec;


程序清单
uniform vec3 LightPosition;

const float SpecularContribution = 0.3;

const float DiffuseContribution  = 1.0 - SpecularContribution;

varying 
float LightIntensity;

varying vec2  MCposition;

void main(void){
    vec3 ecPosition 
= vec3 (gl_ModelViewMatrix * gl_Vertex);
    
    vec3 tnorm      
= normalize(gl_NormalMatrix * gl_Normal);

    vec3 lightVec   
= normalize(LightPosition - ecPosition);

    vec3 reflectVec 
= reflect(-lightVec, tnorm);

    vec3 viewVec    
= normalize(-ecPosition);

    
float diffuse   = max(dot(lightVec, tnorm), 0.0);

    
float spec      = 0.0;

    
if (diffuse > 0.0){
        spec 
= max(dot(reflectVec, viewVec), 0.0);
        spec 
= pow(spec, 16.0);
    }


    LightIntensity  
= DiffuseContribution * diffuse + SpecularContribution * spec;

    MCposition      
= gl_Vertex.xy;
    
    gl_Position     
= ftransform();
}



posted @ 2004-08-02 14:13  Pointer  阅读(1275)  评论(0编辑  收藏  举报