JMU
Fragment Shaders
In "Modern" OpenGL


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Overview
User-Defined Inputs
Built-In Inputs
Uniforms
Outputs
Examples

A Red Fragment Shader

openglexamples/modern/red.frag
        #version 300 es

/**
 * A fragment shader that passes the  color red
 * on to the next stage in the pipeline.
 *
 * @author Prof. David Bernstein, James Madison University
 */


precision mediump float;

/**
 * Outputs.
 */
layout(location = 0) out vec3 color;

/**
 * Process the inputs and generate the outputs.
 * In this case, pass red on to the next stage.
 */
void main(){
  color = vec3(1.0f, 0.0f, 0.0f);
}        
Examples (cont.)

A Color Pass-Through Fragment Shader

openglexamples/modern/color.frag
        #version 300 es

/**
 * A fragment shader that passes the (interpolated) color
 * on to the next stage in the pipeline.
 *
 * @author Prof. David Bernstein, James Madison University
 */

precision mediump float;


/**
 * Inputs that are different for each invocation of this shader.
 */
in vec3 fragmentColor;

/**
 * Outputs.
 */
layout(location = 0) out vec3 color;

/**
 * Process the inputs and generate the outputs.
 * In this case, just pass the color on to the next stage.
 */
void main(){
  color = fragmentColor;
}        
Examples (cont.)

A Fragment Shader that Implements a Simple Lighting Model

openglexamples/modern/lighting.frag
        #version 300 es

/**
 * A fragment shader that implements a simple lighting model.
 *
 * For details, see the lecture on lighting at:
 *    https://w3.cs.jmu.edu/bernstdh/web/common/lectures/slides_lighting-3d.php
 *
 * @author Prof. David Bernstein, James Madison University
 */

precision mediump float;

/**
 * Inputs that are different for each invocation of this shader
 * (i.e., interpolated values from the vertex shaders).
 */
in vec3 vertexColor;
in vec3 position_worldspace;
in vec3 normal_cameraspace;
in vec3 eyeDirection_cameraspace;
in vec3 lightDirection_cameraspace;

/**
 * Outputs.
 */
out vec3 I;      // Total intensity of the light

/**
 * Inputs that (may) stay constant for all vertices.
 */
uniform vec3 lightPosition_worldspace;

/**
 * Process the inputs and generate the outputs.
 * In this case, calculate the total light intensity
 * for the fragment.
 */
void main(){

  // Properties of the light
  vec3  L = vec3(1.0, 1.0, 1.0) * 50.0f;
        
  // Properties of the material
  vec3 A = vertexColor;

  // For diffuse reflection (per Lambert)
  //
  //    Normalized normal of the fragment
  vec3 n = normalize(normal_cameraspace);
  
  //    Normalized direction from the fragment to the light
  vec3 l = normalize(lightDirection_cameraspace);

  //    Cosine of the angle between the normal and the light irection.
  float cosTheta = clamp(dot(n, l), 0.0 , 1.0);

  // For specular reflection (per Romney)
  //
  //    Normalized direction from the fragment to the viewer
  vec3 v = normalize(eyeDirection_cameraspace);
  
  //    (Normalized) Direction of the reflection
  vec3 r = reflect(-l, n);
  
  //    Cosine of the angle between v and r
  float cosPhi = clamp( dot(v, r), 0.0 , 1.0);

  // For the complete model
  //
  //    Distance to the light
  float d = length( lightPosition_worldspace - position_worldspace );

  //    The attenuation factor
  float beta = pow(d, 2.0);

  // Parameters of the complete model
  float kappa_A = 0.5;
  float kappa_D = 0.5;
  float kappa_S = 0.5;
  float delta   = 5.0;

  // The complete model
  I = A * kappa_A +  (L / beta) * ((kappa_D * cosTheta) + (kappa_S * pow(cosPhi, delta)));
}        
Examples (cont.)

A Fragment Shader that Implements a Simple Lighting Model

images/fragment-shader_lighting_sphere.gif images/fragment-shader_lighting_fighter.gif
Examples (cont.)

A Fragment Shader that Implements a Cartoon Lighting Model

openglexamples/modern/cartoonlighting.frag
        #version 300 es

/**
 * A fragment shader that implements a simple lighting model.
 *
 * For details, see the lecture on lighting at:
 *    https://w3.cs.jmu.edu/bernstdh/web/common/lectures/slides_lighting-3d.php
 *
 * @author Prof. David Bernstein, James Madison University
 */

precision mediump float;

/**
 * Inputs that are different for each invocation of this shader
 * (i.e., interpolated values from the vertex shaders).
 */
in vec3 vertexColor;
in vec3 position_worldspace;
in vec3 normal_cameraspace;
in vec3 eyeDirection_cameraspace;
in vec3 lightDirection_cameraspace;

/**
 * Outputs.
 */
out vec3 I;      // Total intensity of the light

/**
 * Inputs that (may) stay constant for all vertices.
 */
uniform vec3 lightPosition_worldspace;

/**
 * Process the inputs and generate the outputs.
 * In this case, calculate the total light intensity
 * for the fragment.
 */
void main(){
  // Properties of the light
  vec3  L = vec3(1.0, 1.0, 1.0) * 50.0f;
        
  // Properties of the material
  vec3 A = vertexColor;

  // Normalized normal of the fragment
  vec3 n = normalize(normal_cameraspace);
  
  // Normalized direction from the fragment to the light
  vec3 l = normalize(lightDirection_cameraspace);

  // Cosine of the angle between the normal and the light irection.
  float cosTheta = clamp(dot(n, l), 0.0 , 1.0);

  if      (cosTheta > 0.20) I = vertexColor * vec3(1.1, 1.1, 1.1);
  else if (cosTheta > 0.10) I = vertexColor;
  else if (cosTheta > 0.01) I = vertexColor * vec3(0.9, 0.9, 0.9);
  else                      I = vertexColor * vec3(0.6, 0.6, 0.6);
}        
Examples (cont.)

A Fragment Shader that Implements a Cartoon Lighting Model

images/fragment-shader_cartoonlighting_sphere.gif