/// LSU EE 4702-1 (Fall 2009), GPU Programming // /// Fragment Shader / Phong Shading Demonstration // $Id:$ /// See demo-9-shader.cc for details. uniform float iridescence; void vs_ff_vertex(vec4 vtx) { // Transform VTX in the same way fixed functionality would. // gl_Position = gl_ModelViewProjectionMatrix * vtx; } vec4 generic_lighting(vec4 vertex_e, vec4 color, vec3 normal_e) { // Perform lighting calculations VTX, using COLOR and NORMAL. // vec4 light_pos = gl_LightSource[0].position; vec3 v_vtx_light = vec3( light_pos - vertex_e ); float phase_light = max(0.0,dot(normal_e, normalize(v_vtx_light).xyz)); vec3 ambient_light = gl_LightSource[0].ambient.rgb; vec3 diffuse_light = gl_LightSource[0].diffuse.rgb; float dist = length(v_vtx_light); float distsq = dist * dist; float atten_inv = gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist + gl_LightSource[0].quadraticAttenuation * distsq; vec4 new_color; new_color.rgb = color.rgb * gl_LightModel.ambient.rgb + color.rgb * ( ambient_light + phase_light * diffuse_light ) / atten_inv; new_color.a = color.a; return new_color; } vec4 iridescent_lighting(vec4 vertex_e, vec4 color1, vec3 normal_e) { vec4 light_pos = gl_LightSource[0].position; vec3 v_vtx_light = vec3( light_pos - vertex_e ); float phase_light = max(0.0,dot(normal_e, normalize(v_vtx_light).xyz)); vec3 ambient_light = gl_LightSource[0].ambient.rgb; vec3 diffuse_light = gl_LightSource[0].diffuse.rgb; float dist = length(v_vtx_light); float distsq = dist * dist; float atten_inv = gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist + gl_LightSource[0].quadraticAttenuation * distsq; vec3 v_vtx_eye = -vertex_e.xyz; float dist_vtx_eye = length(v_vtx_eye); vec3 v_vtx_eye_norm = v_vtx_eye / dist_vtx_eye; float phase_eye = dot(normal_e,v_vtx_eye_norm); float iri_blend = pow(abs(phase_eye),iridescence); vec3 color2 = vec3(0,0,1); vec3 color = color1.rgb * iri_blend + color2.rgb * ( 1 - iri_blend ); vec4 new_color; new_color.rgb = color.rgb * gl_LightModel.ambient.rgb + color.rgb * ( ambient_light + phase_light * diffuse_light ) / atten_inv; new_color.a = color1.a; return new_color; } void vs_main_lighting() { // Use custom lighting model. // vs_ff_vertex(gl_Vertex); vec4 vertex_e = gl_ModelViewMatrix * gl_Vertex; vec3 normal_e = normalize(gl_NormalMatrix * gl_Normal); if ( iridescence == 0 ) gl_FrontColor = generic_lighting(vertex_e,gl_Color,normal_e); else gl_FrontColor = iridescent_lighting(vertex_e,gl_Color,normal_e); } varying vec3 var_normal_e; varying vec4 var_vertex_e; void vs_main_phong() { // Use custom lighting model. // vs_ff_vertex(gl_Vertex); var_vertex_e = gl_ModelViewMatrix * gl_Vertex; var_normal_e = normalize(gl_NormalMatrix * gl_Normal); gl_BackColor = gl_FrontColor = gl_Color; } void fs_main_phong() { // Note: gl_Color in fragment shader is either gl_FrontColor or gl_BackColor // in vertex shader. // gl_FragColor = // generic_lighting(var_vertex_e,gl_Color,normalize(var_normal_e)); if ( iridescence == 0 ) gl_FragColor = generic_lighting(var_vertex_e,gl_Color,var_normal_e); else gl_FragColor = iridescent_lighting(var_vertex_e,gl_Color,var_normal_e); gl_FragDepth = gl_FragCoord.z; }