聚光灯模型

参考:http://www.lighthouse3d.com/tutorials/glsl-tutorial/spot-light-per-pixel/

例子源代码:http://download.csdn.net/detail/netrookie/4311805

glsl vertex shader

struct MaterialParameters 
{
   vec4 emission;
   vec4 ambient;
   vec4 diffuse;
   vec4 specular;
   float shininess;
};

struct LightSourceParameters 
{
   vec4 ambient;
   vec4 diffuse;
   vec4 specular;
   vec4 position;
   vec4 halfVector;
   vec3 spotDirection;
   float spotExponent;
   float spotCutoff;
   float spotCosCutoff;
   float constantAttenuation;
   float linearAttenuation;
   float quadraticAttenuation;
};

uniform mat4 m_mvp_mat;
uniform mat4 m_mv_mat;
uniform mat4 m_model_it;

uniform MaterialParameters m_material_attr;
uniform LightSourceParameters m_light_attr;

attribute vec4 m_position;
attribute vec3 m_normal;

varying vec4 ambient;
varying vec4 diffuse;

varying float dist;

varying vec3 normal, light_dir, half_vector;

varying float constantAttenuation, linearAttenuation, quadraticAttenuation;
varying vec4 light_specular, material_spcular, material_shininess;
varying vec3 spotDirection;
varying float spotExponent, spotCutoff, spotCosCutoff;

void main()
{
    vec3 position_mv;
    vec3 view_dir;
    vec3 aux;

    position_mv = vec3(m_mv_mat * m_position);

    aux = vec3(m_light_attr.position) - position_mv;
    light_dir = normalize(aux);
    dist = length(aux);

    normal = normalize(vec3(m_model_it * vec4(m_normal, 0.0)));

    view_dir = -position_mv;
    half_vector = normalize(view_dir - light_dir);

    ambient = m_light_attr.ambient * m_material_attr.ambient;
    diffuse = m_material_attr.diffuse * m_light_attr.diffuse;

    constantAttenuation = m_light_attr.constantAttenuation;
    linearAttenuation = m_light_attr.linearAttenuation;
    quadraticAttenuation = m_light_attr.quadraticAttenuation;

    light_specular = m_light_attr.specular;
    material_spcular = m_material_attr.specular;
    material_shininess = m_material_attr.shininess;

    spotDirection = m_light_attr.spotDirection;
    spotExponent = m_light_attr.spotExponent;
    spotCutoff = m_light_attr.spotCutoff;
    spotCosCutoff = m_light_attr.spotCosCutoff;

    gl_Position = m_mvp_mat * m_position;
}

glsl fragment shader

varying vec4 ambient;
varying vec4 diffuse;

varying float dist;

varying vec3 normal, light_dir, half_vector;

varying float constantAttenuation, linearAttenuation, quadraticAttenuation;
varying vec4 light_specular, material_spcular, material_shininess;
varying vec3 spotDirection;
varying float spotExponent, spotCutoff, spotCosCutoff;

void main(void)
{
   float n_dot_l, n_dot_hv;
   float att, spotEffect;
   vec4 color, specular;
   
   color = vec4(0.1, 0.1, 0.1, 1.0);
   
   /* normal and light_dir has normalized */
   n_dot_l = max(dot(normal, light_dir), 0.0);
   if(n_dot_l > 0.0)
   {
      spotEffect = dot(spotDirection, (-light_dir));
      if(spotEffect > spotCosCutoff)
      {
    spotEffect = pow(spotEffect, spotExponent);
      }

      att = spotEffect / (constantAttenuation + 
      linearAttenuation * dist + 
      quadraticAttenuation * dist * dist);
      
      n_dot_hv = max(dot(normal, half_vector), 0.0);
      
      diffuse = n_dot_l * diffuse;
      
      specular = material_spcular * light_specular * pow(n_dot_hv, material_shininess); 
      
      color += att * (ambient + diffuse + specular);
   }
   gl_FragColor = color;
}

截图:

posted on 2012-05-18 14:55  zengqh  阅读(301)  评论(0编辑  收藏  举报