/// LSU EE 4702-1 (Fall 2016), GPU Programming // /// Fragment Shader / Phong Shading Demonstration /// See demo-9-shader.cc for details. // Specify version of OpenGL Shading Language. // #version 450 compatibility vec4 generic_lighting(vec4 vertex_e, vec4 color, vec3 normal_e, bool front); #define USE_MATERIAL_COLOR layout ( location = 1 ) uniform vec4 material_color; /// /// Vertex-Shader Only Code -- "Lighting" Program /// // Declare variables for communication between vertex shader // and fragment shader. // #ifdef _VERTEX_SHADER_ out vec3 var_normal_e; out vec4 var_vertex_e; out vec2 gl_TexCoord[]; // Declaring this is optional, since it's predefined. #endif #ifdef _FRAGMENT_SHADER_ in vec3 var_normal_e; in vec4 var_vertex_e; in vec2 gl_TexCoord[]; // We can change its interpolation, say to noperspective. uniform sampler2D tex_unit_0; #endif // Entry Point for Vertex Shader Code // #ifdef _VERTEX_SHADER_ void vs_main_lighting() { /// Pre-Defined Inputs // // gl_Vertex, gl_Normal, gl_Color // // (storage qualifier "in") (Compatibility Profile) // See OGSL Spec 4.5 Section 7.2 /// Pre-Defined Outputs // // gl_Position, gl_FrontColor, etc. // // (storage qualifier "out") /// Pre-Defined Uniforms // // gl_ModelViewMatrix, gl_NormalMatrix, gl_ModelViewProjectionMatrix, .. // // (storage qualifier uniform) (Compatibility Profile) // See OGSL Spec 4.3 Section 7.4.1 // Transform vertex coordinate to clip space. gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; // Compute eye-space coordinates for vertex and normal. // vec4 vertex_e = gl_ModelViewMatrix * gl_Vertex; vec3 normal_e = normalize(gl_NormalMatrix * gl_Normal); #ifdef USE_MATERIAL_COLOR vec4 our_color = material_color; #else vec4 our_color = gl_Color; #endif // Call our lighting routine to compute the lighted color of this // vertex. // gl_FrontColor = generic_lighting(vertex_e,our_color,normal_e,true); gl_BackColor = generic_lighting(vertex_e,our_color,normal_e,false); // Copy texture coordinate to output (no need to modify it). // Only copy x and y components since it's a 2D texture. // gl_TexCoord[0].xy = gl_MultiTexCoord0.xy; } #endif /// /// Routine used by Either Vertex or Fragment Shader /// vec4 generic_lighting(vec4 vertex_e, vec4 color, vec3 normal_e, bool front_facing) { // See OpenGL 4.5 Section 12.2.1.1 for a lighting formula. // // Return lighted color of vertex_e. // vec4 light_pos = gl_LightSource[0].position; vec3 v_vtx_light = light_pos.xyz - vertex_e.xyz; float dist = length(v_vtx_light); float d_n_vl = dot(normalize(normal_e), v_vtx_light) / dist; float phase_light = max(0,front_facing ? d_n_vl : -d_n_vl ); vec3 ambient_light = gl_LightSource[0].ambient.rgb; vec3 diffuse_light = gl_LightSource[0].diffuse.rgb; float distsq = dist * dist; float atten_inv = gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist + gl_LightSource[0].quadraticAttenuation * distsq; vec4 lighted_color; lighted_color.rgb = color.rgb * gl_LightModel.ambient.rgb + color.rgb * ( ambient_light + phase_light * diffuse_light ) / atten_inv; lighted_color.a = color.a; return lighted_color; } /// /// Vertex & Fragment Shader Code /// #ifdef _VERTEX_SHADER_ void vs_main_phong() { // Transform vertex to clip space. gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; // Compute eye-space vertex coordinate and normal. // These are outputs of the vertex shader and inputs to the frag shader. // var_vertex_e = gl_ModelViewMatrix * gl_Vertex; var_normal_e = normalize(gl_NormalMatrix * gl_Normal); // Copy color to output unmodified. Lighting calculations will // be performed in the fragment shader. // #ifndef USE_MATERIAL_COLOR gl_BackColor = gl_FrontColor = gl_Color; #endif // Copy texture coordinate to output (no need to modify it). gl_TexCoord[0].xy = gl_MultiTexCoord0.xy; } #endif #ifdef _FRAGMENT_SHADER_ void fs_main_phong() { // Note: gl_Color in fragment shader is either gl_FrontColor or gl_BackColor // in vertex shader. // Get filtered texel. // vec4 texel = texture(tex_unit_0,gl_TexCoord[0].xy); #ifdef USE_MATERIAL_COLOR vec4 our_color = material_color; #else vec4 our_color = gl_Color; #endif // Multiply filtered texel color with lighted color of fragment. // gl_FragColor = texel * generic_lighting (var_vertex_e,our_color,normalize(var_normal_e),gl_FrontFacing); // Copy fragment depth unmodified. // gl_FragDepth = gl_FragCoord.z; } #endif