参考: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; }
截图: