CSE4431 Lab 05

Simple Animations with glman

glman supports simple animations through the use of the variable uniform float Timer; glman will automatically assign a value to Timer that ramps from 0 to 1 over a period of 10 seconds (you can specify the time interval in your glib file).

To illustrate the use of the timer, create the following files for the explosion example: explode.glib, explode.vert, explode.geom, and explode.frag

 

explode.glib: You can change the Timer interval to any positive time in seconds that you want.

##OpenGL GLIB

GSTAP

Perspective 70
LookAt 0 0 15  0 0 0  0 1 0
Background [1. 1. 1.]
Pointsize 2.

Vertex   explode.vert
Geometry explode.geom
Fragment explode.frag
Program Explode \
  uLevel <0 4 6> \
  uGravity <-10 -1 0> \
  uVelScale <1. 30. 50.>

Timer 10
Color .5 1. .5
Obj dino3.obj
 

explode.vert

#version 330

void main( )
{
   gl_Position = uModelViewMatrix * aVertex;
}
 

explode.geom: We talked about this shader in the lectures; it is also listed in Chapter 16 of the textbook. Here, I've used Timer to make time a value that ramps from 0 to 1 and back to 0; thus, the model looks like it is repeatedly exploding outwards and then collapsing back inwards. Other effects can be found in Table 16.2 of the textbook.

#version 330
#extension GL_EXT_geometry_shader4: enable
#extension GL_EXT_gpu_shader4: enable

layout( triangles )  in;
layout( points, max_vertices=200 )  out;

uniform int uLevel;
uniform float uGravity;
uniform float Timer;
uniform float uVelScale;

out float gLightIntensity;

const vec3 LIGHTPOS = vec3( 0., 0., 10. );

vec3  V0, V01, V02;
vec3  CG;
vec3  Normal;

void
ProduceVertex( float s, float t )
{
   // compute the time from Timer
   float time = 20 * Timer;
   if (Timer > 0.5)
      time = 20 - time;
   vec3 v = V0 + s*V01 + t*V02;
   gLightIntensity  = abs( dot( normalize(LIGHTPOS - v), Normal ) );
   vec3 vel = uVelScale * ( v - CG );
   v = v + vel*time + 0.5*vec3(0.,uGravity,0.)*time*time;
   v.y = max(v.y, -2.0);
   gl_Position = uProjectionMatrix * vec4( v, 1. );
   EmitVertex( );
}



void
main( )
{
   V01 = ( gl_PositionIn[1] - gl_PositionIn[0] ).xyz;
   V02 = ( gl_PositionIn[2] - gl_PositionIn[0] ).xyz;

   Normal = normalize( cross( V01, V02 ) );

   V0  =   gl_PositionIn[0].xyz;
   CG = ( gl_PositionIn[0].xyz + gl_PositionIn[1].xyz + gl_PositionIn[2].xyz ) / 3.;

   int numLayers = 1 << uLevel;

   float dt = 1. / float( numLayers );
   float t = 1.;

   for( int it = 0; it <= numLayers; it++ )
   {
      float smax = 1. - t;
      int nums = it + 1;
      float ds = smax / float( nums - 1 );
      float s = 0.;

      for( int is = 0; is < nums; is++ )
      {
         ProduceVertex( s, t );
         s += ds;
      }

      t -= dt;
   }
}
 

explode.frag

#version 330

in float gLightIntensity;

out vec4 fFragColor;

const vec3 COLOR = vec3( 0., 1., 0. );

void
main( )
{
   fFragColor = vec4( gLightIntensity*COLOR, 1.  );
}
 

Quadrilateral Silhouettes using the Geometry Shader

This is the variation of the silhouette shader we discussed in class; here, we output triangles for the silhouette so that we can render the silhouette in one pass. The handout describes the details of the shader. I've included the glib file, vertex, and fragment shaders below; you should type in the geometry shader included in the handout to help you understand exactly what it is doing.

 

silh3.glib: Note that you must use an ObjAdj model to obtain the adjacency information needed by the geometry shader.

##OpenGL GLIB

GSTAP

Perspective 70
LookAt 0 0 8  0 0 0  0 1 0

Vertex   silh3.vert
Geometry silh3.geom
Fragment silh3.frag

Program  Silhoutte \
  uEdgeWidth <0 0.01 0.1> \
  uPctExtend <0 0.05 1> \
  uLineColor {0. 0. 1. 1.}

ObjAdj cow.obj
 

silh3.vert.

#version 330

in vec4 aVertex;
in vec4 aNormal;

out vec3 vPosition;
out vec3 vNormal;

uniform mat4 uModelViewMatrix;
uniform mat4 uNormalMatrix;
uniform mat4 uModelViewProjectionMatrix;

void main( )
{
   vPosition = vec3(uModelViewMatrix * aVertex);
   vNormal = normalize(vec3(uNormalMatrix * aNormal));
	gl_Position = uModelViewProjectionMatrix * aVertex;
}
 

silh3.frag.

#version 330 compatibility

in vec3 gNormal;      // position in camera coords
in vec3 gPosition;    // normal in camera coords
flat in int gIsEdge; // edge?

out vec4 fFragColor;

uniform vec4 uLineColor;

// constants; would normally be uniforms

// light position in eye coordinates
const vec3 myLightPosition = vec3(1., 1., 10.);

const vec3 myLightAmbient = vec3(0., 0.2, 0.2);
const vec3 myLightDiffuse = vec3(1., 1., 1.);
const vec3 myLightSpecular = vec3(1., 1., 1.);

const vec3 myMaterialAmbient = vec3(1., 0.5, 0.);
const vec3 myMaterialDiffuse = vec3(1., 0.5, 0.);
const vec3 myMaterialSpecular = vec3(0.6, 0.6, 0.6);
const float myMaterialShininess = 80.;

vec3 ADSLightModel(in vec3 myNormal, in vec3 myPosition)
{
  // normal, light, view, and reflection directions
  vec3 norm = normalize(myNormal);
  vec3 lightv = normalize(myLightPosition - myPosition);
  vec3 viewv = normalize(-myPosition);
  vec3 refl = reflect(-lightv, norm);
  
  // ambient
  vec3 ambient = myMaterialAmbient * myLightAmbient;
  
  // diffuse
  vec3 diffuse = max(0., dot(lightv, norm)) * myMaterialDiffuse * myLightDiffuse;
  
  // specular
  vec3 specular = vec3(0., 0., 0.);
  if (dot(lightv, viewv) > 0.)
  {
    specular = pow(max(0.0, dot(viewv, refl)), myMaterialShininess) * 
               myMaterialSpecular * myLightSpecular;
  }
  return clamp(ambient + diffuse + specular, 0., 1.);
}


void main(void)
{
  if (gIsEdge > 0)
  {
    fFragColor = uLineColor;
  }
  else
  {
    vec3 color = ADSLightModel(gNormal, gPosition);
    fFragColor.rgb = color;
    fFragColor.a = 1.;
  }
}