0% found this document useful (0 votes)
6 views

lectureXX OpenGL

Uploaded by

duke
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

lectureXX OpenGL

Uploaded by

duke
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 106

Introduction to Modern OpenGL

Programming
Adapted from SIGGRAPH 2012 slides by
Ed Angel
University of New Mexico
and
Dave Shreiner
ARM, Inc

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell
Outline

 Evolution of the OpenGL Pipeline


 A Prototype Application in OpenGL
 OpenGL Shading Language (GLSL)
 Vertex Shaders
 Fragment Shaders
 Examples
What Is OpenGL?

 OpenGL is a computer graphics rendering API


 With it, you can generate high-quality color images
by rendering with geometric and image primitives
 It forms the basis of many interactive applications
that include 3D graphics
 By using OpenGL, the graphics part of your
application can be
 operating system independent
 window system independent
This is the “new” OpenGL

 We’ll concentrate on the latest versions of OpenGL


 They enforce a new way to program with OpenGL
 Allows more efficient use of GPU resources
 If you’re familiar with “classic” graphics pipelines,
modern OpenGL doesn’t support
 Fixed-function graphics operations
 lighting
 transformations
 All applications must use shaders for their graphics
processing
The Evolution of the OpenGL
Pipeline

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell
In the Beginning …
 OpenGL 1.0 was released on July 1st, 1994
 Its pipeline was entirely fixed-function
 the only operations available were fixed by the
implementation
Vertex
Vertex
Transform and
Data
Lighting
Primitive Fragment
Setup and Coloring and Blending
Rasterization Texturing
Pixel
Data Texture
Store

 The pipeline evolved, but remained fixed-function


through OpenGL versions 1.1 through 2.0 (Sept. 2004)
The Start of the Programmable Pipeline

 OpenGL 2.0 (officially) added programmable shaders


 vertex shading augmented the fixed-function transform and
lighting stage
 fragment shading augmented the fragment coloring stage
 However, the fixed-function pipeline was still available

Vertex
Vertex
Transform and
Data
Lighting
Primitive Fragment
Setup and Coloring and Blending
Rasterization Texturing
Pixel
Data Texture
Store
An Evolutionary Change

 OpenGL 3.0 introduced the deprecation model


 the method used to remove features from OpenGL
 The pipeline remained the same until OpenGL 3.1
(released March 24th, 2009)
 Introduced a change in how OpenGL contexts are used
Context Type Description
Includes all features (including those marked deprecated)
Full
available in the current version of OpenGL

Includes all non-deprecated features (i.e., creates a context


Forward Compatible
that would be similar to the next version of OpenGL)
The Exclusively Programmable Pipeline

 OpenGL 3.1 removed the fixed-function pipeline


 programs were required to use only shaders

Vertex Vertex
Data Shader
Primitive
Fragment
Setup and Blending
Shader
Rasterization

Pixel Texture
Data Store

 Additionally, almost all data is GPU-resident


 all vertex data sent using buffer objects
More Programmability

 OpenGL 3.2 (released August 3rd, 2009) added an


additional shading stage – geometry shaders

Vertex Vertex
Data Shader
Primitive
Fragment
Setup and Blending
Shader
Geometry Rasterization
Shader

Pixel Texture
Data Store
More Evolution – Context Profiles

 OpenGL 3.2 also introduced context profiles


 profiles control which features are exposed
 currently two types of profiles: core and compatible

Context Type Profile Description

core All features of the current release


Full
compatible All features ever in OpenGL

core All non-deprecated features


Forward Compatible
compatible Not supported
The Latest Pipelines

 OpenGL 4.1 (released July 25th, 2010) included


additional shading stages – tessellation-control and
tessellation-evaluation shaders
 Latest version is 4.3

Vertex Vertex
Data Shader
Primitive
Fragment
Setup and Blending
Shader
Rasterization

Tessellation Tessellation
Geometry
Control Evaluation
Shader
Shader Shader

Pixel Texture
Data Store
OpenGL ES and WebGL

 OpenGL ES 2.0
 Designed for embedded and hand-held devices such as cell
phones
 Based on OpenGL 3.1
 Shader based
 WebGL
 JavaScript implementation of ES 2.0
 Runs on most recent browsers
OpenGL Application
Development

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell
A Simplified Pipeline Model

Application
GPU Data Flow Framebuffer

Vertices
Vertices
Fragments
Pixels

Vertex Fragment
Rasterizer
Processing Processing

Vertex Fragment
Shader Shader
OpenGL Programming in a Nutshell

 Modern OpenGL programs essentially do the


following steps:
1. Create shader programs
2. Create buffer objects and load data into them
3. “Connect” data locations with shader variables
4. Render
Application Framework Requirements

 OpenGL applications need a place to render into


 usually an on-screen window
 Need to communicate with native windowing
system
 Each windowing system interface is different
 We use GLUT (more specifically, freeglut)
 simple, open-source library that works everywhere
 handles all windowing operations:
 opening windows
 input processing
Simplifying Working with OpenGL

 Operating systems deal with library functions


differently
 compiler linkage and runtime libraries may expose
different functions
 Additionally, OpenGL has many versions and
profiles which expose different sets of functions
 managing function access is cumbersome, and
window-system dependent
 We use another open-source library, GLEW, to
hide those details
Representing Geometric Objects
 Geometric objects are represented using vertices
 A vertex is a collection of generic attributes
⎛ x ⎞
 positional coordinates ⎜ ⎟
 colors ⎜ y ⎟
⎜ z ⎟
 texture coordinates ⎜ ⎟
⎝ w ⎠
 any other data associated with that point in space
 Position stored in 4 dimensional homogeneous
coordinates
 Vertex data must be stored in vertex buffer objects
(VBOs)
 VBOs must be stored in vertex array objects
(VAOs)
OpenGL’s Geometric Primitives

 All primitives are specified by vertices

GL_POINTS   GL_LINES   GL_LINE_STRIP   GL_LINE_LOOP  

GL_TRIANGLES   GL_TRIANGLE_FAN  
GL_TRIANGLE_STRIP  
A First Program

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell
Rendering a Cube
 We’ll render a cube with colors at each vertex
 Our example demonstrates:
 initializing vertex data
 organizing data for rendering
 simple object modeling
 building up 3D objects from geometric primitives
 building geometric primitives from vertices
Initializing the Cube’s Data
 We’ll build each cube face from individual
triangles
 Need to determine how much storage is required
 (6 faces)(2 triangles/face)(3 vertices/triangle)
 const  int  NumVertices  =  36;  
 To simplify communicating with GLSL, we’ll use a
vec4 class (implemented in C++) similar to GLSL’s
vec4 type
 we’ll also typedef it to add logical meaning
typedef    vec4    point4;  
typedef    vec4    color4;  
Initializing the Cube’s Data (cont’d)

 Before we can initialize our VBO, we need to stage the


data
 Our cube has two attributes per vertex
 position
 color
 We create two arrays to hold the VBO data
point4    points[NumVertices];  
color4    colors[NumVertices];  
Cube Data
//  Vertices  of  a  unit  cube  centered  at  origin,  sides  aligned  
with  axes  
point4  vertex_positions[8]  =  {  
       point4(  -­‐0.5,  -­‐0.5,    0.5,  1.0  ),  
       point4(  -­‐0.5,    0.5,    0.5,  1.0  ),  
       point4(    0.5,    0.5,    0.5,  1.0  ),  
       point4(    0.5,  -­‐0.5,    0.5,  1.0  ),  
       point4(  -­‐0.5,  -­‐0.5,  -­‐0.5,  1.0  ),  
       point4(  -­‐0.5,    0.5,  -­‐0.5,  1.0  ),  
       point4(    0.5,    0.5,  -­‐0.5,  1.0  ),  
       point4(    0.5,  -­‐0.5,  -­‐0.5,  1.0  )  
};  
Cube Data
//  RGBA  colors  
color4  vertex_colors[8]  =  {  
       color4(  0.0,  0.0,  0.0,  1.0  ),    //  black  
       color4(  1.0,  0.0,  0.0,  1.0  ),    //  red  
       color4(  1.0,  1.0,  0.0,  1.0  ),    //  yellow  
       color4(  0.0,  1.0,  0.0,  1.0  ),    //  green  
       color4(  0.0,  0.0,  1.0,  1.0  ),    //  blue  
       color4(  1.0,  0.0,  1.0,  1.0  ),    //  magenta  
       color4(  1.0,  1.0,  1.0,  1.0  ),    //  white  
       color4(  0.0,  1.0,  1.0,  1.0  )      //  cyan  
};  
 
Generating a Cube Face from Vertices

// quad() generates two triangles for each face and assigns


colors to the vertices
int Index = 0; // global variable indexing into VBO arrays

void quad(int a, int b, int c, int d) {


colors[Index] = vertex_colors[a]; points[Index] =
vertex_positions[a]; Index++;
colors[Index] = vertex_colors[b]; points[Index] =
vertex_positions[b]; Index++;
colors[Index] = vertex_colors[c]; points[Index] =
vertex_positions[c]; Index++;
colors[Index] = vertex_colors[a]; points[Index] =
vertex_positions[a]; Index++;
colors[Index] = vertex_colors[c]; points[Index] =
vertex_positions[c]; Index++;
colors[Index] = vertex_colors[d]; points[Index] =
vertex_positions[d]; Index++;
}
Generating the Cube from Faces

//  generate  12  triangles:  36  vertices  and  36  


colors  
void  
colorcube()  {  
       quad(  1,  0,  3,  2  );  
       quad(  2,  3,  7,  6  );  
       quad(  3,  0,  4,  7  );  
       quad(  6,  5,  1,  2  );  
       quad(  4,  5,  6,  7  );  
       quad(  5,  4,  0,  1  );  
}  
 
 
Vertex Array Objects (VAOs)

 VAOs store the data of a geometric object


 Steps in using a VAO
 generate VAO names by calling
glGenVertexArrays()  
 bind a specific VAO for initialization by calling
glBindVertexArray()  
 update VBOs associated with this VAO
 bind VAO for use in rendering
 This approach allows a single function call to
specify all the data for an objects
 previously, you might have needed to make many calls
to make all the data current
VAOs in Code
//  Create  a  vertex  array  object  
GLuint  vao;  
glGenVertexArrays(1,  &vao);  
glBindVertexArray(vao);  
 
         
Storing Vertex Attributes
 Vertex data must be stored in a VBO, and
associated with a VAO
 The code-flow is similar to configuring a VAO
 generate VBO names by calling glGenBuffers()  
 bind a specific VBO for initialization by calling
glBindBuffer(GL_ARRAY_BUFFER,  …)  
 load data into VBO using
glBufferData(GL_ARRAY_BUFFER,  …)  
 bind VAO for use in rendering
glBindVertexArray()  
VBOs in Code
//  Create  and  initialize  a  buffer  object  
GLuint  buffer;  
glGenBuffers(1,  &buffer);  
glBindBuffer(GL_ARRAY_BUFFER,  buffer);  
glBufferData(GL_ARRAY_BUFFER,  sizeof(points)  +  
                     sizeof(colors),  NULL,  
GL_STATIC_DRAW);  
glBufferSubData(GL_ARRAY_BUFFER,  0,    
                             sizeof(points),  points);  
glBufferSubData(GL_ARRAY_BUFFER,  sizeof(points),  
sizeof(colors),  colors);  
Connecting Vertex Shaders with Geometry

 Application vertex data enters the OpenGL


pipeline through the vertex shader
 Need to connect vertex data to shader
variables
 requires knowing the attribute location
 Attribute location can either be queried by
calling glGetVertexAttribLocation()  
Vertex Array Code
//  set  up  vertex  arrays  (after  shaders  are  loaded)  
GLuint  vPosition  =  glGetAttribLocation(program,  
"vPosition”);  
glEnableVertexAttribArray(vPosition);  
glVertexAttribPointer(vPosition,  4,  GL_FLOAT,  
GL_FALSE,  0,  BUFFER_OFFSET(0));  
GLuint  vColor  =  glGetAttribLocation(program,  
"vColor”);  
glEnableVertexAttribArray(vColor);  
glVertexAttribPointer(vColor,  4,  GL_FLOAT,  
GL_FALSE,  0,  BUFFER_OFFSET(sizeof(points)));  
Drawing Geometric Primitives

 For contiguous groups of vertices


glDrawArrays(GL_TRIANGLES,  0,  NumVertices);  

 Usually invoked in display callback


 Initiates vertex shader
Shaders and GLSL

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell
GLSL Data Types
Scalar types: float, int, bool

Vector types: vec2, vec3, vec4


ivec2, ivec3, ivec4
bvec2, bvec3, bvec4

Matrix types: mat2, mat3, mat4

Texture sampling: sampler1D, sampler2D, sampler3D,


samplerCube

C++ style constructors: vec3 a = vec3(1.0, 2.0, 3.0);


Operators
 Standard C/C++ arithmetic and logic operators
 Operators overloaded for matrix and vector operations

mat4  m;  
vec4  a,  b,  c;  
 
b  =  a*m;  
c  =  m*a;  
Components and Swizzling
For vectors can use [ ], xyzw, rgba or stpq
Example:
vec3  v;  
v[1],  v.y,  v.g,  v.t  all refer to the same element
Swizzling:
vec3  a,  b;  
a.xy  =  b.yx;  
Qualifiers
 in, out
 Copy vertex attributes and other variables to/from
shaders
 in  vec2  tex_coord;  
 out  vec4  color;  
 Uniform: variable from application
 uniform  float  time;  
 uniform  vec4  rotation;  
Flow Control

 if
 if else
 expression ? true-expression : false-
expression
 while, do while
 for
Functions
 Built in
 Arithmetic: sqrt, power, abs
 Trigonometric: sin, asin
 Graphical: length, reflect
 User defined
Built-in Variables
 gl_Position: output position from vertex
shader
 gl_FragColor: output color from fragment
shader
 Only for ES, WebGL and older versions of GLSL
 Present version use an out variable
Simple Vertex Shader for Cube

in  vec4  vPosition;  
in  vec4  vColor;  
out  vec4  color;  
 
void  main()  {  
       color  =  vColor;  
       gl_Position  =  vPosition;  
}  
 
The Simplest Fragment Shader

in  vec4  color;  
out  vec4  FragColor;  
 
void  main()  {  
       FragColor  =  color;  
}  
Getting Shaders into OpenGL
Create
glCreateProgram()
 Shaders need to be compiled Program
and linked to form an
Create
executable shader program Shader
glCreateShader() These
steps need
 OpenGL provides the compiler to be
Load Shader
and linker Source
glShaderSource() repeated
for each
 A program must contain type of
Compile shader in
 vertex and fragment Shader
glCompileShader() the shader
program
shaders
Attach Shader
 other shaders are optional to Program
glAttachShader()

Link
glLinkProgram()
Program

Use Program glUseProgram()


A Simpler Way

 We’ve created a routine for this course to make it


easier to load your shaders
 available at course website
GLuint  InitShaders(  const  char*  vFile,  const  char*  
fFile);
 InitShaders  takes two filenames
 vFile for the vertex shader
 fFile for the fragment shader
 Fails if shaders don’t compile, or program doesn’t
link
Associating Shader Variables and Data
 Need to associate a shader variable with an OpenGL data
source
 vertex shader attributes → app vertex attributes
 shader uniforms → app provided uniform values
 OpenGL relates shader variables to indices for the app to
set
 Two methods for determining variable/index association
 specify association before program linkage
 query association after program linkage
Determining Locations After Linking

Assumes you already know the variables’ name

GLint idx =
glGetAttribLocation(program, “name”);

GLint idx =
glGetUniformLocation(program, “name”);
Initializing Uniform Variable Values

Uniform Variables
glUniform4f(index,  x,  y,  z,  w);  
 
Glboolean  transpose  =  GL_TRUE;      
       //  Since  we’re  C  programmers  
Glfloat  mat[3][4][4]  =  {  …  };  

glUniformMatrix4fv(index,  3,  transpose,  mat);    


Finishing the Cube Program
int  main(int  argc,  char  **argv)  {  
 glutInit(&argc,  argv);  
 glutInitDisplayMode(GLUT_RGBA  |  GLUT_DOUBLE  |  
GLUT_DEPTH);  
   glutInitWindowSize(512,  512);  
   glutCreateWindow("Color  Cube”);  
   glewInit();  
   init();  
   glutDisplayFunc(display);  
   glutKeyboardFunc(keyboard);  
   glutMainLoop();  
   return  0;  
}  
Cube Program GLUT Callbacks
void  display(void)  {  
     glClear(GL_COLOR_BUFFER_BIT  |  GL_DEPTH_BUFFER_BIT);  
       glDrawArrays(GL_TRIANGLES,  0,  NumVertices);  
       glutSwapBuffers();  
}  
 
void  keyboard(unsigned  char  key,  int  x,  int  y)  {  
       switch(  key  )  {  
               case  033:  case  'q':  case  'Q':  
                       exit(  EXIT_SUCCESS  );  
                       break;  
       }  
}  
 
Vertex Shader Examples
 A vertex shader is initiated by each vertex output by
glDrawArrays()  
 A vertex shader must output a position in clip
coordinates to the rasterizer
 Basic uses of vertex shaders
 Transformations
 Lighting
 Moving vertex positions
Transformations
Camera Analogy
3D is just like taking a photograph (lots of
photographs!)

viewing

volume

camera

model

tripod

Transformations
" Transformations take us from one “space” to
another
" All of our transforms are 4×4 matrices

Modeling Modeling
Transform" Transform"

Object Coords.

Perspective
Vertex Model-View Projection
Division"
Viewport 2D Window
Data Transform" Transform" Transform" Coordinates
(w)"

Normalized
World Coords. Eye Coords. Clip Coords. Device
Coords.
Camera Analogy Transform Sequence

 Modeling transformations
 assemble the world and move the objects
 Viewing transformations
 define position and orientation of the viewing
volume in the world
 Projection transformations
 adjust the lens of the camera
 Viewport transformations
 enlarge or reduce the physical photograph
3D Homogeneous Transformations
 A vertex is  matrices are always
transformed by 4×4 post-multiplied
matrices  product of matrix and
vector is
 all affine operations
are matrix 
Mv
multiplications
 all matrices are stored ⎡m0 m4 m8 m12 ⎤
column-major in ⎢ m ⎥
OpenGL ⎢ 1 m5 m9 m13 ⎥
M=
 this is opposite of ⎢m2 m6 m10 m14 ⎥
what “C” ⎢ ⎥
programmers expect
⎣ m3 m7 m11 m15 ⎦
View Specification
 Set up a viewing frustum to specify how much
of the world we can see
 Done in two steps
 specify the size of the frustum (projection transform)
 specify its location in space (model-view transform)
 Anything outside of the viewing frustum is
clipped
 primitive is either modified or discarded (if entirely
outside frustum)
View Specification (cont’d)
 OpenGL projection model uses eye coordinates
 the “eye” is located at the origin
 looking down the -z axis
 Projection matrices use a six-plane model:
 near (image) plane and far (infinite) plane
 both are distances from the eye (positive values)
 enclosing planes
 top & bottom, left & right
Viewing Transformations
 Position the camera/eye in the scene
 To “fly through” a scene
 change viewing transformation and
redraw scene
 LookAt(eyex,  eyey,  eyez,  
           lookx,  looky,  lookz,  
           upx,  upy,  upz)  
 up vector determines unique orientation
 careful of degenerate positions
Translation

Move object or change


frame origin

&1 0 0 tx #
$ !
$0 1 0 ty !
T (t x , t y , t z ) = $ !
$0 0 1 tz !
$ !
$0 0 0 1 !"
%
Scale

Stretch, mirror or decimate a


coordinate direction

& sx 0 0 0#
$ !
$0 sy 0 0!
S (sx , s y , sz ) = $ !
$0 0 sz 0!
$ !
$0 0 0 1 !"
% Note, there’s a translation applied here to
make things easier to see

Rotation
Rotate coordinate system about an axis in space

Note, there’s a translation applied


here to make things easier to see

Vertex Shader for Cube Rotation
in  vec4  vPosition;  
in  vec4  vColor;  
out  vec4  color;  
uniform  vec3  theta;  
 
void  main()  {  
       //  Compute  the  sines  and  cosines  of  theta  for
 
       //  each  of  the  three  axes  in  one  computation.
 
       vec3  angles  =  radians(theta);  
       vec3  c  =  cos(angles);  
       vec3  s  =  sin(angles);  
Vertex Shader for Cube Rotation
       //  Remember:  these  matrices  are  column-­‐major  
 
       mat4  rx  =  mat4(  1.0,    0.0,    0.0,  0.0,  
                                       0.0,    c.x,    s.x,  0.0,  
                                       0.0,  -­‐s.x,    c.x,  0.0,  
                                       0.0,    0.0,    0.0,  1.0  );  
 
       mat4  ry  =  mat4(  c.y,  0.0,  -­‐s.y,  0.0,  
                                       0.0,  1.0,    0.0,  0.0,  
                                       s.y,  0.0,    c.y,  0.0,  
                                       0.0,  0.0,    0.0,  1.0  );  
 
Vertex Shader for Cube Rotation
 
       mat4  rz  =  mat4(  c.z,  -­‐s.z,  0.0,  0.0,  
                                       s.z,    c.z,  0.0,  0.0,  
                                       0.0,    0.0,  1.0,  0.0,  
                                       0.0,    0.0,  0.0,  1.0  );  
 
       color  =  vColor;  
       gl_Position  =  rz  *  ry  *  rx  *  vPosition;  
}    
Sending Angles from Application
//  compute  angles  using  mouse  and  idle  callbacks    
GLuint  theta;    //  theta  uniform  location  
vec3    Theta;      //  Axis  angles  
 
void  display(void)  {  
     glClear(GL_COLOR_BUFFER_BIT  |  GL_DEPTH_BUFFER_BIT);  
 
     glUniform3fv(theta,  1,  Theta);  
     glDrawArrays(GL_TRIANGLES,  0,  NumVertices);  
 
     glutSwapBuffers();  
}  
Vertex Lighting

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell
Lighting Principles
 Lighting simulates how objects reflect light
 material composition of object
 light’s color and position
 global lighting parameters
 Lighting functions deprecated in 3.1
 Can implement in
 Application (per vertex)
 Vertex or fragment shaders
Modified Phong Model
 Computes a color or shade for each vertex using a
lighting model (the modified Phong model) that takes
into account
 Diffuse reflections
 Specular reflections
 Ambient light
 Emission
 Vertex shades are interpolated across polygons by the
rasterizer
Modified Phong Model

 The model is a balance between simple computation


and physical realism
 The model uses
 Light positions and intensities
 Surface orientation (normals)
 Material properties (reflectivity)
 Viewer location
 Computed for each source and each color component
OpenGL Lighting
 Modified Phong lighting model
 Computed at vertices
 Lighting contributors
 Surface material properties
 Light properties
 Lighting model properties
Surface Normals
 Normals define how a surface reflects light
 Application usually provides normals as a vertex atttribute
 Current normal is used to compute vertex’s color
 Use unit normals for proper lighting
 scaling affects a normal’s length
Material Properties
 Define the surface properties of a primitive

Property Description
Diffuse Base object color
Specular Highlight color
Ambient Low-light color
Emission Glow color
Surface
Shininess
smoothness
 you can have separate materials for front and back
Adding Lighting to Cube
//  vertex  shader    
 
in  vec4  vPosition;  
in  vec3  vNormal;  
out  vec4  color;  
 
uniform  vec4  AmbientProduct,  DiffuseProduct,  
SpecularProduct;  
uniform  mat4  ModelView;  
uniform  mat4  Projection;  
uniform  vec4  LightPosition;  
uniform  float  Shininess;  
Adding Lighting to Cube
void  main()  {  
     //  Transform  vertex    position  into  eye  coordinates  
     vec3  pos  =  (ModelView  *  vPosition).xyz;  
                 
     vec3  L  =  normalize(LightPosition.xyz  -­‐  pos);  
     vec3  E  =  normalize(-­‐pos);  
     vec3  H  =  normalize(L  +  E);  
 
     //  Transform  vertex  normal  into  eye  coordinates  
     vec3  N  =  normalize(ModelView  *  vec4(vNormal,  0.0)).xyz;  
Adding Lighting to Cube
//  Compute  terms  in  the  illumination  equation  
       vec4  ambient  =  AmbientProduct;  
       float  Kd  =  max(dot(L,  N),  0.0);  
       vec4    diffuse  =  Kd*DiffuseProduct;  
       float  Ks  =  pow(max(dot(N,  H),  0.0),  Shininess);  
       vec4    specular  =  Ks  *  SpecularProduct;  
       if(dot(L,  N)  <  0.0)    
               specular  =  vec4(0.0,  0.0,  0.0,  1.0)    
 
       gl_Position  =  Projection  *  ModelView  *  vPosition;  
 
       color  =  ambient  +  diffuse  +  specular;  
       color.a  =  1.0;  
}  
Shader Examples

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell
Fragment Shaders
 A shader that’s executed for each “potential” pixel
 fragments still need to pass several tests before making it to
the framebuffer
 There are lots of effects we can do in fragment shaders
 Per-fragment lighting
 Bump Mapping
 Environment (Reflection) Maps
Per Fragment Lighting
 Compute lighting using same model as for per
vertex lighting but for each fragment
 Normals and other attributes are sent to vertex
shader and output to rasterizer
 Rasterizer interpolates and provides inputs for
fragment shader
Shader Examples
 Vertex Shaders
 Moving vertices: height fields
 Per vertex lighting: height fields
 Per vertex lighting: cartoon shading
 Fragment Shaders
 Per vertex vs. per fragment lighting: cartoon shader
 Samplers: reflection Map
 Bump mapping
Height Fields
 A height field is a function y = f(x, z) where the
y value represents a quantity such as the height
above a point in the x-z plane.
 Heights fields are usually rendered by sampling
the function to form a rectangular mesh of
triangles or rectangles from the samples yij =
f(xi, zj)
Displaying a Height Field
 Form a quadrilateral mesh
for(i=0;i<N;i++)  for(j=0;j<N;j++)  data[i][j]=f(i,  j,  time);  
 
vertex[Index++]  =  vec3((float)i/N,  data[i][j],  (float)j/N);  
vertex[Index++]  =  vec3((float)i/N,  data[i][j],  (float)(j+1)/N);  
vertex[Index++]  =  vec3((float)(i+1)/N,  data[i][j],  (float)(j+1)/N);  
vertex[Index++]  =  vec3((float)(i+1)/N,  data[i][j],  (float)(j)/N);    

 Display each quad using


 for(i=0;i<NumVertices  ;i+=4)  glDrawArrays(GL_LINE_LOOP,  4*i,  4);  
Time Varying Vertex Shader
in  vec4  vPosition;  
in  vec4  vColor;  
 
uniform  float  time;  /*  in  milliseconds  */  
uniform  mat4  ModelView,  ProjectionMatrix;  
 
void  main()    {  
       vec4    v  =  vPosition;  
       vec4    t  =  sin(0.001*time  +  5.0*v);          
       v.y  =  0.1*t.x*t.z;  
 
       gl_Position  =  ModelViewProjectionMatrix  *  t;  
}  
Mesh Display
Adding Lighting
 Solid Mesh: create two triangles for each
quad
 Display with
glDrawArrays(GL_TRIANGLES,  0,  NumVertices);  
 For better looking results, we’ll add lighting
 We’ll do per-vertex lighting
 leverage the vertex shader since we’ll also use it to
vary the mesh in a time-varying way
Mesh Shader
uniform  float  time,  shininess;  
uniform  vec4  vPosition,  light_position  diffuse_light,  
specular_light;  
uniform  mat4  ModelViewMatrix,  ModelViewProjectionMatrix,  
       NormalMatrix;  
 
void  main()  {  
     vec4    v  =  vPosition;  
     vec4    t  =  sin(0.001*time  +  5.0*v);  
     v.y  =  0.1*t.x*t.z;  
 
     gl_Position  =  ModelViewProjectionMatrix  *  v;  
 
     vec4  diffuse,  specular;  
     vec4  eyePosition  =  ModelViewMatrix  *  vPosition;  
     vec4  eyeLightPos  =  light_position;  
Mesh Shader (cont’d)
       vec3  N  =  normalize(NormalMatrix  *  Normal);  
       vec3  L  =  normalize(eyeLightPos.xyz  -­‐  eyePosition.xyz);  
       vec3  E  =  -­‐normalize(eyePosition.xyz);  
       vec3  H  =  normalize(L  +  E);  
 
       float  Kd  =  max(dot(L,  N),  0.0);  
       float  Ks  =  pow(max(dot(N,  H),  0.0),  shininess);  
       diffuse    =  Kd*diffuse_light;  
       specular  =  Ks*specular_light;  
       color        =  diffuse  +  specular;  
}  
Shaded Mesh
Texture Mapping

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell
Texture Mapping

z x
geometry screen

t
image

s
Texture Mapping in OpenGL
 Images and geometry flow through separate
pipelines that join at the rasterizer
 “complex” textures do not affect geometric
complexity

Vertices
Geometry
Pipeline
Fragment
Rasterizer
Shader
Pixel
Pixels

Pipeline
Applying Textures
 Three basic steps to applying a texture
1. specify the texture
 read or generate image
 assign to texture
 enable texturing
2. assign texture coordinates to vertices
3. specify texture parameters
 wrapping, filtering
Applying Textures
1. specify textures in texture objects
2. set texture filter
3. set texture function
4. set texture wrap mode
5. set optional perspective correction hint
6. bind texture object
7. enable texturing
8. supply texture coordinates for vertex
Texture Objects
 Have OpenGL store your images
 one image per texture object
 may be shared by several graphics contexts

 Generate texture names


glGenTextures(n,  *texIds);  
Texture Objects (cont'd.)
 Create texture objects with texture data and
state
 glBindTexture(target,  id);  
 Bind textures before using
 glBindTexture(target,  id);  
Specifying a Texture Image
 Define a texture image from an array of
texels in CPU memory
glTexImage2D(target,  level,  components,  
     w,  h,  border,  format,  type,  *texels);  
 Texel colors are processed by pixel pipeline
 pixel scales, biases and lookups can be
done
Mapping a Texture
 Based on parametric texture coordinates
 Coordinates need to be specified at each vertex

Texture Space Object Space


t 1, 1 (s, t) = (0.2, 0.8)
0, 1 A
a

c (0.4, 0.2)
b
B C
0, 0 1, 0 s (0.8, 0.4)
Applying the Texture in the Shader
// Declare the sampler
uniform sampler2D diffuse_mat;
// GLSL 3.30 has overloaded texture();
// Apply the material color
vec3 diffuse = intensity *
texture2D(diffuse_mat, coord).rgb;
Texturing the Cube
// add texture coordinate attribute to quad
function

quad(int a, int b, int c, int d) {


quad_colors[Index] = vertex_colors[a];
points[Index] = vertex_positions[a];
tex_coords[Index] = vec2(0.0, 0.0);
Index++;
… // rest of vertices
}
Creating a Texture Image
// Create a checkerboard pattern
for (int i = 0; i < 64; i++) {
for (int j = 0; j < 64; j++) {
GLubyte c;
c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255;
image[i][j][0] = c;
image[i][j][1] = c;
image[i][j][2] = c;
image2[i][j][0] = c;
image2[i][j][1] = 0;
image2[i][j][2] = c;
}
}
Texture Object
GLuint  textures[1];  
glGenTextures(1,  textures);  
 
glBindTexture(GL_TEXTURE_2D,  textures[0]);  
glTexImage2D(GL_TEXTURE_2D,  0,  GL_RGB,  TextureSize,  
                           TextureSize,  GL_RGB,  GL_UNSIGNED_BYTE,  image);  
glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_WRAP_S,  GL_REPEAT);  
glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_WRAP_T,  GL_REPEAT);  
glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_MAG_FILTER,  GL_NEAREST);  
glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_MIN_FILTER,  GL_NEAREST);  
glActiveTexture(GL_TEXTURE0);  
 
Vertex Shader
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord;

out vec4 color;


out vec2 texCoord;

void main() {
color = vColor;
texCoord = vTexCoord;
gl_Position = vPosition;
}
Fragment Shader
in vec4 color;
in vec2 texCoord;
out vec4 FragColor;

uniform sampler texture;

void main() {
FragColor = color * texture(texture, texCoord);
}
Next class: Visual Perception
" Topic:
How does the human visual system?
How do humans perceive color?
How do we represent color in computations?
" Read:
• Glassner, Principles of Digital Image Synthesis,
pp. 5-32. [Course reader pp.1-28]
• Watt , Chapter 15.
• Brian Wandell. Foundations of Vision. Sinauer
Associates, Sunderland, MA, pp. 45-50 and
69-97, 1995.
[Course reader pp. 29-34 and pp. 35-63]

University of Texas at Austin CS384G - Computer Graphics Fall 2010 Don Fussell 106

You might also like