why do we care about graphics shaders? - juniata...
TRANSCRIPT
1
Mike BaileyOregon State University
Steve CunninghamBrown Cunningham Associates
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Why Do We Care About Graphics Shaders?
1. You can get effects that are difficult or impossible to get any other way
2. You can get innovative data displays
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
4. The fixed-function pipeline has gone away in OpenGL ES 2.0 and has been deprecated in OpenGL 3.0
3. You get a much better understanding of the graphics pipeline
2
Start with Some Terminology
Fragment – a “pixel-to-be”: all of the information about that pixel is available, but the pixel’s color has not yet been determined
Fragment Processor – the part of the graphics pipeline that takes all of the information about a fragment and determines what color to paint there
Fragment Shader – the code you can write to determine the color to paint at a particular fragment
Geometry Shader – the code that you can write to convert or expand one form of geometry into another
GLSL – the OpenGL Shading Language
OpenGL – a multi-vendor, multi-platform, multi-operating system graphics API
Texture an image (read or computed) to be attached to a piece of geometry
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Texture – an image (read or computed) to be attached to a piece of geometry
Vertex Processor – the part of the graphics pipeline that handles vertices, from model coordinates to clipped screen space coordinates
Vertex Shader – the code that you can write to perform the transformations of the vertices and set auxiliary values
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
3
The Graphics Process
3D
LightingInformation
3DGeometric
Models
3DAnimation
Rendering
TextureInformation
ImageStorage and
Display
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
AnimationDefinition
The Basic Computer Graphics Pipeline
ModelTransform
ViewTransform
ProjectionTransform
HomogeneousDivision
Per-vertexLighting
ViewportTransform
FragmentProcessing, Texturing,
Per-fragment Lighting
RastersOps
Rasterization
Framebuffer
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
4
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
The Generic Computer Graphics System
CPU
InputDevices
VertexProcessor
B
Uniformvariables
RasterizerBus
Network
Z-Buffer
FragmentProcessor
RGBAZPixels
TC
ShaderMemory
Uniformvariables
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
VideoDriver
Double-bufferedFramebuffers
Texture Memory
Front
Back
5
Vertices
CPU
VertexProcessor
A Shader-eye View of the Graphics Process, with Geometry Shaders
Transformed Vertices
Bus
Assembled Primitive
Create NewGeometry
Assemble NewGeometry
AssembleGeometry
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Rasterizer
FragmentProcessor
Pixels
Interpolated Values
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
6
The Basic Computer Graphics Coordinate Systems
ModelTransform
ViewTransform
ProjectionTransform
HomogeneousDivision
Per-vertexLighting
NDC
ECWC
MC
CCEC
ViewportTransform
FragmentProcessing, Texturing,
Per-fragment Lighting
RastersOps
Rasterization
Framebuffer
SCSC
SCSC
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
MC = Model CoordinatesWC = World CoordinatesEC = Eye CoordinatesCC = Clip CoordinatesNDC = Normalized Device CoordinatesSC = Screen Coordinates
Homogeous Coordinates:Adding a 4th Value to an XYZ Triple
We usually think of a 3D point as being represented by a triple: (x,y,z).
Using homogeneous coordinates, we add a 4th number: (x,y,z,w)
A graphics system, by convention, performs transformations and clipping using (x y z w) and then divides x y and z by w before it uses them(x,y,z,w) and then divides x, y, and z by w before it uses them.
, ,x y zX Y Zw w w
= = =
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Thus (1,2,3,1) , (2,4,6,2) , (-1,-2,-3,-1) all represent the same 3D point.
7
This Seems Awkward – Why Do It?
One reason is that it allows for perspective division within the matrix mechanism. The OpenGL call glFrustum( left, right, bottom, top, near, far ) creates this matrix:
2 0 0near right left+⎡ ⎤⎢ ⎥
i 0 0'
20 0''
( ) 20 0' 1
0 0 1 0
right left right leftx x
near top bottomy y
top bottom top bottomz z
far near far nearw far near far near
⎢ ⎥− −⎢ ⎥⎧ ⎫ ⎧ ⎫+⎢ ⎥⎪ ⎪ ⎪ ⎪
⎪ ⎪ ⎪ ⎪⎢ ⎥− −=⎨ ⎬ ⎨ ⎬⎢ ⎥⎪ ⎪ ⎪ ⎪− + −⎢ ⎥⎪ ⎪ ⎪ ⎪⎢ ⎥⎩ ⎭ ⎩ ⎭− −⎢ ⎥−⎢ ⎥⎣ ⎦
i
i i
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
This gives w’ = -z, which is the necessary divisor for perspective.
Another Reason is to be able to Represent Points at Infinity
This is useful to be able to specify a parallel light source by placing the light source location at infinity.
The point (1,2,3,1) represents the 3D point (1,2,3)
The point (1 2 3 5) represents the 3D point (2 4 6)The point (1,2,3,.5) represents the 3D point (2,4,6)
The point (1,2,3,.01) represents the point (100,200,300)
So, (1,2,3,0) represents a point at infinity, but along the ray from the origin through (1,2,3)
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
8
However, When Using Homogeneous Coordinates, You Sometimes Need to be able to get a Vector Between Two Points
( , , ) ( , , )( , , , ) ( , , , ) b b b a a ab b b b a a a a
x y z x y zx y z w x y z w− = −
To get a vector between two homogeneous points, we subtract them:
( , , ) ( , , )b a
a b a b a b b a b a b a
a b
w ww x w y w z w x w y w z
w w−
=
Fortunately, most of the time that we do this, we only want a unit vector in that direction, not the full vector. So, we can ignore the denominator, and just say:
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
ˆ ( , , );a b b a a b b a a b b av normalize w x w x w y w y w z w z= − − −
vec3 Vector( vec4 b, vec4 a ){
return vec3( a.w*b.x – b.w*a.x , a.w*b.y – b.w*a.y , a.w*b.z – b.w*a.z );}
However, to keep this simpler, we will ignore w when differencing 2 coordinates
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
9
OpenGL gives you Access to two Transformations
Model View ProjectionPer-vertex
ECWC
MC
CCEC
Transform Transformj
TransformLighting
These two are lumped together into a single matrix called the ModelView Matrix.
In GLSL this is called
This one is called the Projection Matrix.
In GLSL, this is called gl ProjectionMatri
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
MC = Model CoordinatesWC = World CoordinatesEC = Eye CoordinatesCC = Clip Coordinates
In GLSL, this is called gl_ModelViewMatrix
gl_ProjectionMatrix
GLSL also provides you with these two multiplied together.
This is called gl_ModelViewProjectionMatrix
vec4 ModelCoords = gl_Vertex ;
Producing Model, Eye, and Clip Coordinates
vec4 EyeCoords = gl_ModelViewMatrix * gl_Vertex ;
vec4 ClipCoords = gl_ModelViewProjectionMatrix * gl_Vertex ;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
10
The Normal Transformation
GLSL also gives you the matrix to transform normal vectors. It performs the sameGLSL also gives you the matrix to transform normal vectors. It performs the same operations on normal vectors as the ModelView matrix does on vertices.
In GLSL, this is called gl_NormalMatrix
It is actually the transpose of the inverse of the ModelView matrix. (Trust us…)
vec3 TransfNorm = gl_NormalMatrix * gl_Normal ;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
g _ g _
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
11
varying vec4 Color;varying float X, Y, Z;varying float LightIntensity;
voidmain( void ){
Here’s What a GLSL Vertex Shader Looks Like
{vec3 TransNorm = normalize( gl_NormalMatrix * gl_Normal );vec3 LightPos = vec3( 0., 0., 10. );vec3 ECposition = ( gl_ModelViewMatrix * gl_Vertex ).xyz;LightIntensity = dot( normalize(LightPos - ECposition), TransNorm );LightIntensity = abs( LightIntensity );Color = gl_Color;vec3 MCposition = gl_Vertex.xyz;
X = MCposition.x;Y = MCposition.y;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
p y;Z = MCposition.z;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;}
Don’t worry about the details right now, just take comfort in the fact that it is C-like and that there appears to be a lot of support routines for you to use
GLSL Shaders Are Like C With Extensions for Graphics:
• Types include int, ivec2, ivec3, ivec4
• Types include float, vec2, vec3, vec4
• Types include mat2, mat3, mat4
• Types include bool, bvec2, bvec3, bvec4
• Types include sampler to access textures
• Vector components are accessed with [index], .rgba, .xyzw, and .stpq
• Vector components can be “swizzled” ( c1.rgba = c2.abgr )
• discard operator used in fragment shaders to discard fragments
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
p g g
• Type qualifiers: const, attribute, uniform, varying, flat, noperspective
• Procedure type qualifiers: in, out, inout
12
GLSL Shaders Are Missing Some C-isms:
• No type casts (use constructors instead)
• No automatic promotion
• No switch statement (they’re coming)• No switch statement (they re coming)
• No pointers
• No strings
• No bitwise operators (they’re “here”)
• No enums
•Array indices must be compiler-time constants
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
• No file-based pre-processor directives
Vertices VertexProcessor
GLSL Variables
Transformed Vertices
Per-Vertex Attribute Variables
Assembled Primitive
Create NewGeometry
Assemble NewGeometry
AssembleGeometry
UniformVariables
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Rasterizer
FragmentProcessor
Interpolated Values
VaryingVariables
VaryingVariables
13
Things You Should Know About the Shader Compiler
• A uniform variable that is not actually set from the main program will y p gnot generate an error – it will just quietly screw up
• When you attempt to set a non-existent uniform variable from the main program, you will get an error
• A uniform variable that is not actually needed by the shader is eliminated by the compiler and appears to be non-existent
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
14
genType radians( genType degrees ) Converts degrees to radians:(π/180)∗degrees
genType degrees( genType radians ) Converts radians to degrees:(180/π)∗radians
genType sin( genType angle )genType cos( genType angle )
The standard trigonometric sine, cosine, and tangent functions, with the argument angle in radians.
Trig Functions
genType tan( genType angle )
genType asin( genType x) Arc sine. Returns the primary radian value of the angle whose sine is x. The range of returned values is [−π/2, π/2]. Undefined if ∣x∣>1.
genType acos( genType x) Arc cosine. Returns the primary radian value of the angle whose cosine is x. The range of returned values is [0, π]. Results are undefined if ∣x∣>1.
genType atan( genType y, genType x ) Arc tangent. Returns the primary radian value of the angle whose tangent is y/x. The signs of x and y determine the angle’s quadrant. The range of returned values is [−π, π]. Undefined if x and y are both 0.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
genType atan( genType y_over_x ) Arc tangent. Returns the primary radian value of the angle whose tangent is y_over_x. The range of returned values is [− π/2, π/2] .
Note: gentype can be any compatible type. For example, you could take the sine of a float (giving back a float) or the component-wise sine of a vec4 (giving back a vec4).
Math Functions
genType pow( genType x, genType y ) Power function. Returns x raised to the y power, xy. Undefined if x < 0, or if x = 0 and y ≤ 0.
genType exp( genType x ) Returns the natural exponentiation of x, ex.
genType log( genType x ) Returns the natural logarithm of x, the value y for which x = ey. Undefined if x ≤ 0.
genType exp2( genType x ) Returns 2 raised to the x power: 2x
genType log2( genType x ) Returns the base 2 logarithm of x, the value y for which x = 2y. Undefined if x <= 0.
genType sqrt( genType x ) Returns the nonnegative square root of x. Undefined if x < 0.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
genType inversesqrt( genType x ) Returns the reciprocal of the square root of x. Undefined if x ≤ 0.
15
genType abs( genType x ) Returns x if x ≥ 0, otherwise returns –x.
genType sign( genType x ) Returns 1.0 if x > 0, 0.0 if x = 0, or –1.0 if x < 0.
genType floor( genType x ) Returns a value equal to the nearest integer that is less than or equal to x.
Math Functions
genType ceil( genType x ) Returns a value equal to the nearest integer that is greater than or equal to x.
genType fract( genType x ) Returns the fraction part of x: x – floor(x).
genType truncate ( genType x ) Returns the integer closest to x whose absolute value is not larger than abs(x).
genType round( genType x ) Returns the integer closest to x.
genType mod( genType x, float y )genType mod( genType x, genType y )
. Generalized modulus. Returns .
genType min( genType x, genType y )genType min( genType x, float y )
Minimum. Returns y if y < x, otherwise returns x.
x − y ∗ floor x y( )
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
ge ype ( ge ype , oat y )
genType max( genType x, genType y )genType max( genType x, float y )
Maximum. Returns y if x < y, otherwise returns x.
genType clamp( genType x,genType minVal,genType maxVal )genType clamp( genType x, float minVal, float maxVal )
Clamped value; Returns min(max(x, minVal), maxVal).Undefined if minVal > maxVal.
genType mix( genType x, genType y, genType a )genType mix( genType x, genType y, float a )
Proportional mix. Returns a linear combination of x and y:
Blending Functions
x ∗ (1− a) + y ∗ a
genType step( genType edge, genType x )genType step( float edge, genType x )
Step function at the value of edge. Returns 0.0 if x < edge, otherwise returns 1.0
genType smoothstep( genType edge0,genType edge1,genType x )
genType smoothstep( float edge0, float edge1,genType x )
Returns 0.0 if x <= edge0 and 1.0 if x >= edge1, and performs smooth Hermite interpolation between 0. and 1. when edge0 < x < edge1. This is useful in cases where you would want a threshold function with a smooth transition.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
16
float length( genType x ) Returns the length of the vector x,
float distance( genType p0, genType p1 ) Returns the distance between p0 and p1: length(p0 – p1)
float dot( genType x, genType y ) Returns the dot product of x and y:
Geometry Functions
float dot( genType x, genType y ) Returns the dot product of x and y: x[0]⊕y[0]+x[1]⊕y[1]+...
vec3 cross( vec3 x, vec3 y ) Returns the cross product of x and y,
genType normalize( genType x ) Returns a vector in the same direction as x, but with a length of 1.
genType faceforward( genType N,genType I, genType Nref )
Make N face in the direction of Nref. If dot(Nref, I) < 0 return N, otherwise return –N.
genType reflect( genType I, genType N ) For the incident vector I and surface orientation N, returns the reflection direction.. The normal vector N
l d b li d i d hi h
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
must already be normalized in order to achieve the correct result.
genType refract( genType I, genType N,float eta )
For the incident vector I and surface normal N, and the ratio of indices of refraction eta, return the refraction vector. The incident vector I and the normal vector N must already be normalized in order to achieve the correct result.
mat matrixCompMult( mat x, mat y ) Multiply matrix x by matrix y component-wise, so that result[i][j] is the scalar product of x[i][j] and y[i][j]. Note: to get linear algebraic matrix multiplication, use the multiply operator (*).
mat2 outerProduct( vec2 c, vec2 r )mat3 outerProduct( vec3 c vec3 r )
Treats the first parameter c as a column vector (matrix with one column) and the second parameter r as a row vector
Matrix Functions
mat3 outerProduct( vec3 c, vec3 r )mat4 outerProduct( vec4 c,vec4 r )mat2x3 outerProduct( vec3 c,vec2 r )mat3x2 outerProduct( vec2 c,vec3 r )mat2x4 outerProduct( vec4 c,vec2 r )mat4x2 outerProduct( vec2 c,vec4 r )mat3x4 outerProduct( vec4 c,vec3 r )mat4x3 outerProduct( vec3 c,vec4 r )
one column) and the second parameter r as a row vector (matrix with one row) and does a linear algebraic matrix multiply c*r, yielding a matrix whose number of rows is the number of components in c and whose number of columns is the number of components in r.
mat2 transpose( mat2 m )mat3 transpose( mat3 m )mat4 transpose( mat4 m )
Returns a matrix that is the transpose of m; m need not be square, as is shown. The input matrix m is not modified.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
mat2x3 transpose( mat3x2 m )mat3x2 transpose( mat2x3 m )mat2x4 transpose( mat4x2 m )mat4x2 transpose( mat2x4 m )mat3x4 transpose( mat4x3 m )mat4x3 transpose( mat3x4 m )
17
bvec lessThan( vec x, vec y )bvec lessThan( ivec x, ivec y )
Returns the component-wise compare of x < y.
bvec lessThanEqual( vec x, vec y )bvec lessThanEqual( ivec x, ivec y )
Returns the component-wise compare of x <= y.
bvec greaterThan( vec x, vec y )bvec greaterThan( ivec x, ivec y )
Returns the component-wise compare of x > y.
Boolean Functions
bvec greaterThanEqual( vec x, vec y )bvec greaterThanEqual( ivec x, vec y )
Returns the component-wise compare of x >= y.
bvec equal( vec x, vec y )bvec equal( ivec x, ivec y )bvec equal( bvec x, bvec y )
Returns the component-wise compare of x == y.
bvec notEqual( vec x, vec y )bvec notEqual( ivec x, ivec y )bvec notEqual( bvec x, bvec y )
Returns the component-wise compare of x != y.
bool any( bvec x ) The vector equivalent of the logical or, | — returns true if any component of x is true.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
p
bool all( bvec x ) The vector equivalent of the logical and, & — returns true only if all components of x are true.
bvec not( bvec x ) The vector equivalent of the logical not, ! — returns the component-wise logical complement of x.
v4.rgba Is a vec4 and the same as just using v4
v4.rgb Is a vec3 made from the first three components of v4
v4.b Is a float whose value is the third component of v4; l 4 4
Specifying Components and Swizzling
also v4.z or v4.p
v4.xz Is a vec2 made from the first and third components of v4; also v4.rb or v4.sp
v4.xgba Is illegal because the component names do not come from the same set
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
18
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Why use glman?
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Writing a program Using glman
19
1. A .glib file that acts as a scene description script
glman is looking for 4 different files
2. A .vert file that contains the vertex shader
3. A .frag file that contains the fragment shader
4. An optional .geom file that contains the geometry shader
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Load or re-load a .glib file
Edit a specific type of file
glman User
Interface
Dump an arbitrary-resolution BMP file
Display the speed of the display (fps)
Transformations in the projection matrix
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Transformations in the modelview matrix
Allow picking and transformation of individual objects
20
WindowSize wx wy Specifies the initial graphics window size
.glib commands
p g pin pixels. [600. 600.]
Ortho xl xr yb yt Set the current projection to orthographic with the given parameters. [-3. 3. -3. 3.]
Perspective fov Set the current projection to perspective with the given field of view angle in degrees. [70.]
Color r g b a Set the current rendering color to (r, g, b, a). If no alpha value is given, alpha is set to 1.0. 0. ≤ r, g, b, a ≤ 1. To make this look more like a RenderMan file, the RGBA values can also be enclosed in
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
square brackets.
.glib commands
Rotate angle ax ay az Pre-concatenate a rotation by the given angle around the line with the given direction onto the current matrix (angle in degrees)
Scale sx sy sz Pre-concatenate a scale by the given scale factors onto the current matrix
PushMatrix Push the current matrix on the matrix stack
PopMatrix Pop the current matrix from the matrix stack
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
21
.glib commands
Box dx dy dz Create a 3D box. If specified, (dx, dy, dz) are the halflengths of the sides. [2. 2. 2.]
Cylinder radius height Create a solid cylinder. [1. 1.]
Cone radius height Create a solid cone. [1. 1.]g [ ]
DiskXY Create a unit disk parallel to the XY plane and passing through Z = 0.
Obj filename Reads in a .obj geometry filename into lists of GL_TRIANGLES and GL_QUADS. If a filename is not given, glman will prompt you for it. The full .obj format can be quite complex, but glman just supports vertices, normals, texture coordinates, and faces.
ObjAdj filename Reads in a .obj geometry filename into a list of GL_TRIANGLES_ADJACENT. Triangles with adjacency are described in the GLSL and Geometry Shader chapters, and this command is useful for working with geometry shaders . If you don’t have a real need to use triangle adjacency, use Obj instead of ObjAdj. The file will read faster and the resulting geometry will display faster. If no filename is given, glman will prompt you for it. As with the Obj command, this feature just supports vertices, normals, texture coordinates, and faces.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
,
PointCloud numx numy numz Create a 3D point cloud, a regular point grid in three dimensions. The parameters num* are the number of points to use in each direction.
JitterCloud numx numy numz Create a 3D point cloud as above with the position of each point jittered (moved randomly) from its regular position.
.glib commandsQuadXY z size nx ny Create a quadrilateral parallel to the XY plane, passing through Z = z. If given, size is the
quadrilateral’s dimension, going from (-size, -size) to (size, size) in X and Y. If given, nx and ny are the number of sub-quads this quadrilateral is broken into. This is a good way to test 2D textures. [0 1 4 4]
QuadXZ y size nx nz Creates a quadrilateral parallel to the XZ plane, passing through Y = y. If given, size is the quadrilateral’s dimension, going from (-size, -size) to (size, size) in X and Z. If given, nx and nzare the number of sub-quads this quadrilateral is broken into. [0 1 4 4]
QuadYZ x size ny nz Creates a quadrilateral parallel to the YZ plane, passing through X = x. If given, size is the quadrilateral’s dimension, going from (-size, -size) to (size, size) in Y and Z. If given, ny and nz are the number of sub-quads this quadrilateral is broken into. [0 1 4 4]
Sphere radius slices stacks Create a solid sphere. This primitive sets the vertex coordinates, the vertex normals, and the vertex texture coordinates. In order to align bump-mapping, it also sets a vec3 called Tangent at each vertex. The Tangent vectors are all tangent to the sphere surface and always point in a consistent direction, towards the North Pole. [1. 60. 60.]
Teapot Create a solid teapot. The default teapot is approximately 1.6 units high and 3 units long.
Torus innerradius outerradius Create a solid torus. [.2 1.]
Wiresphere radius Create a wireframe sphere. [1.]
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Wirecylinder radius height Create a wireframe cylinder. [1. 1.]
Wirecone radius height Create a wireframe cone. [1. 1.]
Wiretorus innerradius outerradius Create a wireframe torus. [.2 1.]
Wireteapot Create a wireframe teapot.
Xarrow numslices Creates an arrow along the X-axis, from X = 0. to X = 1. If specified, numslices are the number of individual slices to use along the arrow. [100]
22
.glib commands
Texture2D texture_unit filename This reads a 2D texture from a file. Don’t use texture units 2 or 3 unless you want to override the 2D and 3D noise textures. If the filename ends in a .bmp suffix, an uncompressed BMP image file is assumed, with red, green, and blue read from the file (no alpha) Any other filename pattern implies a “raw”alpha). Any other filename pattern implies a raw file format, which is described later. The 4 components can be all unsigned bytes or all 32-bit floating point.
Texture3D texture_unit filename This reads a 3D texture from a file in a raw format, which consists of three binary 4-byte integers giving the X, Y, and Z dimensions of the volume, and then 4 components per texel specifying the red, green, blue, and alpha of that texel. The 4 components can be all unsigned bytes or all 32-bit floating point.
CubeMap texture_unit posxfile negxfile posyfile negyfile poszfile negzfile Generate a cubemap texture on texture unit texture_unit with the six 2D BMP image face files as
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
specified.
.glib commands
Vertex file.vert Specify a vertex shader filename
Geometry file.geom Specify a geometry shader filename
Fragment file.frag Specify a fragment shader filename
Program programname uniformvariables Compile and link the vertex, fragment, and possibly geometry (see below) shaders into a program and specify the uniform variables for... below), shaders into a program and specify the uniform variables for that program (see below). The program command must come last in this group of three or four. It links together the current vertex shader, the current fragment shader, and possibly the current geometry shader. This lets you re-use a shader in another shader program by simply not redefining another shader of that type. If you want to un-specify a shader in a program (that is, no longer use it), just give its vertex, fragment, or geometry command with no arguments.
If you use a geometry shader, then you must also use the following geometry commands in your GLIB file before the Program statement:
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
GeometryInputType type Specify what type of topology this geometry shader expects to find as input. This can be: GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY.
GeometryOutputType type Specify what type of topology this geometry shader will be emitting. This can be GL_POINTS, GL_LINE_STRIP, or GL_TRIANGLES_STRIP
23
.glib commands
Noise2d res Create a 2D noise texture with the given resolution
Noise3d res Create a 3D noise texture with the given resolution
Timer numsecs Sets the Timer period from the default of 10 seconds per cycle to numsecs per cycle
MessageBox An informative text message Puts up a Message Box with the text message in it. This is useful if you want to tell the user something about what this .glib file is about and what to do with this scene display.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
• Multiple whitespace characters in a row are treated as a single whitespace character.
.glib commands Misc Information
• A # causes the rest of the line to be treated as a comment and ignored
• A / causes the rest of the line to be treated as a comment and ignored (so that // will act as expected)
• A backslash (\) at the end of a line causes the carriage return to be ignored. The current line is continued onto the next line
Most OpenGL shader compilers are hea il optimi ing so if o define a niform
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
• Most OpenGL shader compilers are heavily optimizing, so if you define a uniform variable but don't use it, the variable may be dropped and not seen by the loader. This can generate an error and the shader program may fail. So be careful to use all the uniform variables you define!
24
•Scalar variables are just listed as numbers.
Array variables are enclosed in square brackets, as [ ].
• Range variables are enclosed in angle brackets, as < >. These are scalar variables, and glmanautomatically generates a slider in the Uniform Variable user interface for each range variable so that you can then change this value as glman executes. The three values in the brackets are : <min current max>,
0 5 10 l ill l k i t h d ’ b l t bl t d id if thi i bl
.glib commands Misc Information
e.g., <0. 5. 10.>. glman will look into your shader program’s symbol table to decide if this range variable should be a float or an int, and will create a slider of the appropriate type.
• Color variables are enclosed in curly brackets, as { }. Color variables may be either RGB or RGBA, as:{red green blue}
or{red green blue alpha}
This will generate a button in the UI panel that, when clicked, brings up a color selector window. The color selector allows you to change the value of this color variable as glman executes.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
• A Boolean variable is available to select or de-select options in your shader. The glman user interface will automatically create a checkbox in the user interface window. In the GLIB file, a Boolean variable has a name and then the word true or the word false inside angle brackets, e.g., “<true>”. This is the initial setting of the checkbox.
• Multiple vertex-geometry-fragment-program combinations are allowed in the same GLIB file. If there is more than one combination, then they will appear as separate rollout panels in the user interface. The first program rollout will be open, and all the others will be closed. Open the ones you need when you need them.
Sample .glib file and the User Interface it creates
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
25
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
The basic function of a vertex shader is to take the vertex coordinates as supplied by the application, and perform whatever transformation
What does a Vertex Shader Do?
as supplied by the application, and perform whatever transformation of them is required. At the same time, the vertex shader can perform various analyses based on those vertex coordinates and prepare variable values for later on in the graphics process.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
26
A GLSL Vertex Shader Replaces These Operations:
• Vertex transformations
• Normal transformations
• Normal normalization• Normal normalization
• Handling of per-vertex lighting
• Handling of texture coordinates
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
A GLSL Vertex Shader Does Not Replace These Operations:
• Frustum clipping
• Homogeneous division
• Viewport mapping• Viewport mapping
• Backface culling
• Polygon mode
• Polygon offset
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
27
Built-in Vertex Shader Variables You Will Use a Lot:
vec4 gl_Vertex
vec3 gl_Normal
vec4 gl Colorvec4 gl_Color
vec4 gl_MultiTexCoordi (i=0, 1, 2, …)
mat4 gl_ModelViewMatrix
mat4 gl_ProjectionMatrix
mat4 gl_ModelViewProjectionMatrix
mat4 gl_NormalMatrix
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
varying vec4 Color;varying float X, Y, Z;varying float LightIntensity;
voidmain( void )
Sample Vertex Shader:Stripes in Model and Eye Coordinates
{vec3 TransNorm = normalize( gl_NormalMatrix * gl_Normal );vec3 LightPos = vec3( 0., 0., 10. );vec3 ECposition = ( gl_ModelViewMatrix * gl_Vertex ).xyz;LightIntensity = dot(normalize(LightPos - ECposition), TransNorm);LightIntensity = abs( LightIntensity );Color = gl_Color;vec3 MCposition = gl_Vertex.xyz;
#ifdef EYE_COORDSX = ECposition.x;Y = ECposition.y;Z = ECposition.z;
#endif
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
#endif#ifdef MODEL_COORDS
X = MCposition.x;Y = MCposition.y;Z = MCposition.z;
#endifgl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
The Fragment shader then sets the color based on the X, value.
28
varying vec4 Color;varying float X, Y, Z;varying float LightIntensity;
uniform float A;uniform float P;
Sample Frament Shader:Stripes in Model and Eye Coordinates
uniform float Tol;
voidmain( void ){
const vec3 WHITE = vec4( 1., 1., 1. );
float f = fract( A*X );
float t = smoothstep( 0.5-P-Tol, 0.5-P+Tol, f ) - smoothstep( 0.5+P-Tol, 0.5+P+Tol, f );
vec3 color = mix( WHITE, Color.rgb, t );gl FragColor= vec4( LightIntensity*color 1 );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
gl_FragColor= vec4( LightIntensity color, 1. );}
Sample Vertex Shader: Stripes in Model and Eye Coordinates
They might (momentarily) look the same but they
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
the same, but they don’t act the same !
29
Vertex Shader Example: Polar Hyperbolic Space
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
30
The basic function of a fragment shader is to take uniform
What does a Fragment Shader Do?
variables, the output from the rasterizer, and texture information and then compute the color of the pixel for each fragment. This figure illustrates this process, showing first how the distinct vertices of a primitive are processed by the rasterizer to form the set of fragments that
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
form the set of fragments that make up the primitive.
A GLSL Fragment Shader Replaces These Operations:
• Color computation
• Texturing
• Color arithmetic• Color arithmetic
• Handling of per-pixel lighting
• Fog
• Blending
• Discarding fragments
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
31
A GLSL Fragment Shader Does Not Replace These Operations:
• Stencil test
• Z-buffer test
• Stippling• Stippling
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Built-in Fragment Shader Variables You Will Use a Lot:
vec4 gl FragColorvec4 gl_FragColor
float gl_FragDepth
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
32
varying float LightIntensity;uniform vec4 Color;void main( ){
Simple Fragment Shader: Setting the Color
{gl_FragColor= vec4( LightIntensity * Color.rgb, 1. );
}
varying vec3 myColor;void main(void){
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
gl_FragColor = vec4( myColor, 1.0 );}
Fragment Shader: Discarding Fragments
varying vec4 Color;varying float LightIntensity;
uniform float Density;uniform float Frequency;
void main( ){
vec2 st = gl_TexCoord[0].st;
vec2 stf = st * Frequency;
if( all( fract( stf ) >= Density ) )discard;
gl FragColor = vec4( LightIntensity*Color rgb 1 );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
gl_FragColor vec4( LightIntensity Color.rgb, 1. );}
33
Per-vertex vs. Per-fragment Lighting
In per-vertex lighting, the normal at each vertex is turned into a lighted intensity. That intensity is then interpolated throughout the polygon. This gives splotchy polygon artifacts like this.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
In per-fragment lighting, the normal is interpolated throughout the polygon and turned into a lighted intensity at each fragment. This gives smoother results, like this.
Think carefully about what you want as a varying variable –it can make a difference!
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
34
vec4 texture1D( sampler1D sampler, float coord )4 t t 2D( l 2D l 2 d )
Use the texture coordinate coord to do a texture l k i th D t t tl b d t l
Texture-reading Functions
vec4 texture2D( sampler2D sampler, vec2 coord )vec4 texture3D( sampler3D sampler, vec3 coord )
lookup in the n-D texture currently bound to sampler.
vec4 textureCube( samplerCube sampler, vec3 coord ) Use the texture coordinate coord to do a texture lookup in the cube map texture currently bound to sampler. The direction of coord is used to select in which face to do a two-dimensional texture lookup.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
You usually call these routines from a fragment shader (that’s why we’re covering it here), but in fact you can read textures into vertex and geometry shaders as well.
Texture-reading Example
##OpenGL GLIBPerspective 90
Texture2d 7 texture.bmp
varying vec2 ST;
void
glib filevert file
Vertex texture.vertFragment texturemult.fragProgram Texture TexUnit 7
Teapot
voidmain( void ){
ST = gl_MultiTexCoord0.st;gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
uniform sampler2D TexUnit;
frag file
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
p ;varying vec2 ST;
void main( void ){
vec3 rgb = texture2D( TexUnit, ST ).rgb;gl_FragColor = vec4( rgb, 1. );
}
35
Texture Example
texture.bmp
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Using Textures as Data
##OpenGL GLIBPerspective 70
Texture2D 5 goes.visible.bmpTexture2D 6 goes.infrared.bmpTexture2D 7 goes.watervapor.bmp
glib file
g p p
Vertex multiband.vertFragment multiband.fragProgram MultiBand \
VisibleUnit 5 InfraRedUnit 6 WaterVaporUnit 7 \Visible <0. 1. 1.> InfraRed <0. 0. 1.> WaterVapor <0. 0. 1.> \VisibleThreshold <0. 1. 1.> \InfraRedThreshold <0. 0. 1.> \WaterVaporThreshold <0. 0. 1.> \Brightness <0. 1. 3.>
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
QuadXY
void main(){
gl_TexCoord[0] = gl_MultiTexCoord0;gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
vert file
36
Using Textures as Data
uniform sampler2D VisibleUnit;uniform sampler2D InfraRedUnit;uniform sampler2D WaterVaporUnit;uniform float Visible;uniform float InfraRed;
frag file, I
uniform float WaterVapor;uniform float VisibleThreshold;uniform float InfraRedThreshold;uniform float WaterVaporThreshold;uniform float Brightness;
voidmain(){
vec3 visibleColor = texture2D( VisibleUnit, gl_TexCoord[0].st ).rgb;vec3 infraredColor = texture2D( InfraRedUnit, gl_TexCoord[0].st ).rgb;infraredColor = vec3(1.,1.,1.) - infraredColor;vec3 watervaporColor = texture2D( WaterVaporUnit gl TexCoord[0] st ) rgb;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
vec3 watervaporColor texture2D( WaterVaporUnit, gl_TexCoord[0].st ).rgb;
vec3 rgb;
Using a Texture as Data
if( visibleColor.r - visibleColor.g > .25 && visibleColor.r - visibleColor.b > .25 ){
rgb = vec3( 1., 1., 0. ); // state outlines become yellow}else{
frag file, II
{rgb = Visible*visibleColor + InfraRed*infraredColor + WaterVapor*watervaporColor;rgb /= 3.;vec3 coefs = vec3( 0.296, 0.240, 0.464 );float visibleInten = dot(coefs,visibleColor);float infraredInten = dot(coefs,infraredColor);float watervaporInten = dot(coefs,watervaporColor);if( visibleInten > VisibleThreshold && infraredInten < InfraRedThreshold && watervaporInten > WaterVaporThreshold ){
rgb = vec3( 0., 1., 0. );}else{
rgb *= Brightness;b l ( b 0 1 )
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
rgb = clamp( rgb, 0., 1. );}
}
gl_FragColor = vec4( rgb, 1. );}
37
Using Textures as Data – Where is it Likely to Snow?
Visible Infrared Water vapor
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Cube Map Texture Lookup
• Let L be the texture coordinate of (s, t, and p) with the largest magnitude
• L determines which of the 6 2D texture “walls” is being hit by the vector
• The texture coordinates in that texture are
Texture Coords = (s,t,p)
• The texture coordinates in that texture are the remaining two texture coordinates divided by L: (a/L,b/L)
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
vec3 ReflectVector = reflect( vec3 eyeDir, vec3 normal );
vec3 RefractVector = refract( vec3 eyeDir, vec3 normal, float Eta );
38
Cube Map of NVIDIA’s Lobby
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
http://www.codemonsters.de/html/textures_cubemaps.html
Showing the Cube and its Seams
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
39
Cube Map of NVIDIA’s Lobby
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Using the Cube Map for Reflection
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
40
Using the Cube Map for Reflection
varying vec3 ReflectVector;
void main( ){
vec3 ECposition = vec3( gl_ModelViewMatrix * gl_Vertex );vec3 eyeDir = ECposition – vec3(0 0 0 ); // vector from eye to ptvec3 eyeDir = ECposition – vec3(0.,0.,0.); // vector from eye to ptvec3 normal = normalize( gl_NormalMatrix * gl_Normal );ReflectVector = reflect( eyeDir, normal );gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
varying vec3 ReflectVector;uniform samplerCube ReflectUnit;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
void main( ){
vec4 newcolor = textureCube( ReflectUnit, ReflectVector );gl_FragColor = newcolor;
}
Using the Cube Map for Refraction
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
41
Using the Cube Map for Refraction
varying vec3 RefractVector;varying vec3 ReflectVector;uniform float Eta;
void main( ){
vec3 ECposition = vec3( gl_ModelViewMatrix * gl_Vertex );3 Di li ( EC iti ) 3(0 0 0 ) // t f t tvec3 eyeDir = normalize( ECposition ) – vec3(0.,0.,0.); // vector from eye to pt
vec3 normal = normalize( gl_NormalMatrix * gl_Normal );RefractVector = refract( eyeDir, normal, Eta );ReflectVector = reflect( eyeDir, normal );gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
varying vec3 ReflectVector;varying vec3 RefractVector;uniform float Mix;uniform samplerCube ReflectUnit;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
p ;uniform samplerCube RefractUnit;
void main( ){
vec4 WHITE = vec4( 1.,1.,1.,1. );vec4 refractcolor = textureCube( RefractUnit, RefractVector );vec4 reflectcolor = textureCube( ReflectUnit, ReflectVector );refractcolor = mix( refractcolor, WHITE, .3 );gl_FragColor = mix( refractcolor, reflectcolor, Mix );
}
A Comparison of Reflection and Refraction
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
42
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Image Basics
Treat the image as a texture and read it into the fragment shader
Res
T
shader
To get from the current texel to a neighboring texel, add ± (1./ResS , 1./ResT) to the current (S,T)
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
ResS
43
Image Negative
uniform sampler2D ImageUnit;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
p g ;uniform float T;
void main(){
vec2 st = gl_TexCoord[0].st;vec3 irgb = texture2D( ImageUnit, st ).rgb;vec3 neg = vec3(1.,1.,1.) - irgb;gl_FragColor = vec4( mix( irgb, neg, T ), 1. );
}
Image Distortion
uniform float S, T;uniform float Power;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
uniform float Power;uniform sampler2D TexUnit;
voidmain( ){
vec2 st = gl_TexCoord[0].st;vec2 delta = st - vec2(S,T);st = vec2(S,T) + sign(delta) * pow( abs(delta), Power );vec3 rgb = texture2D( TexUnit, st ).rgb;gl_FragColor = vec4( rgb, 1. );
}
44
Image Un-Masking: Sometimes it’s easier to ask for what you don’t want than asking for what you do want !
More of what I
What I
what Ido want
What I started with
}}
Blend of what don’t want and what have
Blend of what have and what want more of
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
tdon’t want
0.0 1.0 2.0
Iout = (1.-t)*Idontwant + t*Iin
}
Brightness
Idontwant = vec3( 0., 0., 0. );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
T = 0. T = 1. T = 2.
45
Contrast
Idontwant = vec3( 0.5, 0.5, 0.5 );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
T = 0. T = 1. T = 2.
HDTV Luminance Standard
Luminance = 0.2125*Red + 0.7154*Green + 0.0721*Blue
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
46
Idontwant = vec3( luminance, luminance, luminance );
Saturation
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
T = 0. T = 1. T = 3.
Blur Convolution:
Sharpening
⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡=
121242121
.16.1B
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Idontwant = Iblur
47
Sharpening
T = 0.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
T = 1.
T = 2.
uniform sampler2D ImageUnit, BeforeUnit, AfterUnit;uniform float Ang;uniform float T;uniform float ResS, ResT;
void main(){
vec2 st = gl TexCoord[0] st;
frag file
Sharpening
vec2 st = gl_TexCoord[0].st;
vec2 stp0 = vec2(1./ResS, 0. );vec2 st0p = vec2(0. , 1./ResT);vec2 stpp = vec2(1./ResS, 1./ResT);vec2 stpm = vec2(1./ResS, -1./ResT);vec3 i00 = texture2D( ImageUnit, st ).rgb;vec3 im1m1 = texture2D( ImageUnit, st-stpp ).rgb;vec3 ip1p1 = texture2D( ImageUnit, st+stpp ).rgb;vec3 im1p1 = texture2D( ImageUnit, st-stpm ).rgb;vec3 ip1m1 = texture2D( ImageUnit, st+stpm ).rgb;vec3 im10 = texture2D( ImageUnit, st-stp0 ).rgb;vec3 ip10 = texture2D( ImageUnit, st+stp0 ).rgb;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
vec3 i0m1 = texture2D( ImageUnit, st-st0p ).rgb;vec3 i0p1 = texture2D( ImageUnit, st+st0p ).rgb;vec3 target = vec3(0.,0.,0.);target += 1.*(im1m1+ip1m1+ip1p1+im1p1);target += 2.*(im10+ip10+i0m1+i0p1);target += 4.*(i00);target /= 16.;gl_FragColor = vec4( mix( target, irgb, T ), 1. );
}
48
Horizontal and Vertical Sobel Convolutions:
Edge Detection
⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡ −−−=
121000121
H⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡
−−−
=101202101
V
22 Θ 2( )
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
VHS 22 += Θ = atan2( V, H )
Edge Detection
vec2 stp0 = vec2(1./ResS, 0. );vec2 st0p = vec2(0. , 1./ResT);vec2 stpp = vec2(1./ResS, 1./ResT);vec2 stpm = vec2(1./ResS, -1./ResT);float i00 = dot( texture2D( ImageUnit, st ).rgb, vec3(0.2125,0.7154,0.0721) );float im1m1 = dot( texture2D( ImageUnit, st-stpp ).rgb, vec3(0.2125,0.7154,0.0721) );float ip1p1 = dot( texture2D( ImageUnit, st+stpp ).rgb, vec3(0.2125,0.7154,0.0721) );float im1p1 = dot( texture2D( ImageUnit, st-stpm ).rgb, vec3(0.2125,0.7154,0.0721) );float ip1m1 = dot( texture2D( ImageUnit, st+stpm ).rgb, vec3(0.2125,0.7154,0.0721) );float im10 = dot( texture2D( ImageUnit, st-stp0 ).rgb, vec3(0.2125,0.7154,0.0721) );float ip10 = dot( texture2D( ImageUnit, st+stp0 ).rgb, vec3(0.2125,0.7154,0.0721) );float i0m1 = dot( texture2D( ImageUnit, st-st0p ).rgb, vec3(0.2125,0.7154,0.0721) );float i0p1 = dot( texture2D( ImageUnit, st+st0p ).rgb, vec3(0.2125,0.7154,0.0721) );float h = -1.*im1p1 - 2.*i0p1 - 1.*ip1p1 + 1.*im1m1 + 2.*i0m1 + 1.*ip1m1;float v = -1.*im1m1 - 2.*im10 - 1.*im1p1 + 1.*ip1m1 + 2.*ip10 + 1.*ip1p1;
float mag = sqrt( h*h + v*v );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
float mag = sqrt( h*h + v*v );vec3 target = vec3( mag,mag,mag );color = vec4( mix( irgb, target, T ), 1. );
49
Edge Detection
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
T = 0. T = 0.5 T = 1.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
50
What if you want multi-colored stripes?
Tol = 0.
And, what if you want the stripes to smoothly blend into each other?
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Tol > 0.
This is a good example of a Procedural Texture. It is like a texture that is read from a file, but instead is computed as the display is being created.
Procedural Textures are very popular because (1) you can do some amazing things with them, and (2) they don’t “run out of texels” like a fixed-size texture would.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
51
varying vec3 MCposition;varying float LightIntensity;
uniform float Tol;
vec4 Red = vec4( 1., 0., 0., 1. );
frag file, I
Here’s how to do the Colored Stripes
( , , , );vec4 Orange = vec4( 1., .5, 0., 1. );vec4 Yellow = vec4( 1., 1., 0., 1. );vec4 Green = vec4( 0., 1., 0., 1. );vec4 Cyan = vec4( 0., 1., 1., 1. );vec4 Blue = vec4( 0., 0., 1., 1. );vec4 Magenta = vec4( 1., 0., 1., 1. );vec4 White = vec4( 1., 1., 1., 1. );
float ONE16 = 1./16.;float THREE16 = 3./16.;float FIVE16 = 5 /16 ;
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
float FIVE16 = 5./16.;float SEVEN16 = 7./16.;float NINE16 = 9./16.;float ELEVEN16 = 11./16.;float THIRTEEN16 = 13./16.;float FIFTEEN16 = 15./16.;
voidmain( void ){
float X = MCposition.x;float Y = MCposition.y;float f = fract( A*X );float t = smoothstep( ONE16 - Tol, ONE16 + Tol, f );gl_FragColor = mix( White, Red, t );
frag file, II
if( f >= THREE16 - Tol ){
t = smoothstep( THREE16 - Tol, THREE16 + Tol, f );gl_FragColor = mix( Red, Orange, t );
}if( f >= FIVE16 - Tol ){
t = smoothstep( FIVE16 - Tol, FIVE16 + Tol, f );gl_FragColor = mix( Orange, Yellow, t );
}
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
}
. . .
gl_FragColor.rgb *= LightIntensity;}
52
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Noise:
• Can be 1D, 2D, or 3D
• Is a function of input value(s)p ( )
• Ranges from -1. to +1. or from 0. to 1.
• Looks random, but really isn’t
• Has continuity
• Is repeatable
• Has statistical properties that are translational and rotational invariant
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
53
Gradient Noise
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Noise Octaves
Idea: Add multiple noise waves, each one twice the frequency and half the amplitude of the previous one
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
1 Octave 4 Octaves
54
TurbulenceIdea: Take the absolute value of the noise components about
the centerline, giving the noise a “sharper” appearance
Normal
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 20091 Octave 4 Octaves
Turbulent
Image Representation of 2D Noise
4 Octaves
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
1 Octave
55
float noise1( genType x ) Returns a 1D noise value based on the input value x. At this time, this function is not available in GLSL.
vec2 noise2( genType x ) Returns a 2D noise value based on the input value x. At this time, this function is
Noise Functions
not available in GLSL.
vec3 noise3 ( genType x ) Returns a 3D noise value based on the input value x.
vec4 noise4 ( genType x ) Returns a 4D noise value based on the input value x.
Note: as of this writing, these functions don’t work on all graphics systems!
T t l h b ilt i i t t
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
To compensate, glman has a built-in noise texture.
glman automatically creates a 3D noise texture and places it into Texture Unit 3.
Y t t f t h d t t it th h th
glman has a built-in 3D Noise Texture
Your vertex, geometry, or fragment shader can get at it through the pre-created uniform variable called Noise3.
You can reference it in your shader as:
uniform sampler3D Noise3;. . .vec3 stp = ...vec4 nv = texture3D( Noise3, stp );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
56
The noise texture is a vec4 whose components have separate meanings.The [0] component is the low frequency noise.The [1] component is twice the frequency and half the amplitude of the [0] component, and so on for the [2] and [3] components.
Each component is centered around a value of .5, so that if you want a plus-or-minus
glman has a built-in 3D Noise Texture
effect, subtract .5 from each component. To get a nice four-octave noise value between 0 and 1 (useful for noisy mixing), add up all four components, subtract 1 and divide the result by 2, as shown in the following table and GLSL code:.
Component Term Term Range
0 nv[0] 0.5 ± .5000
1 nv[1] 0.5 ± .2500
2 nv[2] 0.5 ± .1250
3 nv[3] 0.5 ± .0675
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
[ ]
sum 2.0 ± ~ 1.0
sum - 1 1.0 ± ~ 1.0
(sum - 1) / 2 0.5 ± ~ 0.5
float sum = nv[0] + nv[1] + nv[2] + nv[3]; // range is 1. -> 3.sum = ( sum - 1. ) / 2.; // range is now 0. -> 1.
Have actual
Have an equation to describe color assignment
How to Apply Noise
Have actual coordinates at a pixel
Add Noise to the actual coordinates to
produce new coordinates
Changing the amplitude of the noise value
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Use the new coordinates in the old equation to assign a
color at that pixel
57
How do you change this into this?
vec4 noisevec = texture3D( Noise3, MCposition );fl i [0] i [1] i [2] i [3] // 1 3
float f = fract( A*X );
You take this line in the fragment shader:
Then add a noise call, and change the line to this:
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
float n = noisevec[0] + noisevec[1] + noisevec[2] + noisevec[3]; // 1. -> 3.n = ( n - 2. ); // -1. -> 1.float deltax = DeltaScale * n;
float X = MCposition.x;float Y = MCposition.y;float f = fract( A*(X+deltax) );
Examples
Fire EffectMore Interesting Stripe Blending
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Deciding when to Discard for Erosion
Cloud Effect
58
A Combination of Noise, Cube Mapping, and Imaging
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
59
The Geometry Shader: Where Does it Fit in the Pipeline?
Vertices
CPU
VertexProcessor
Transformed Vertices
Bus
Assembled Primitive
Create NewGeometry
Assemble NewGeometry
AssembleGeometry
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Rasterizer
FragmentProcessor
Pixels
Interpolated Values
The Geometry Shader:What Does it Do?
Points, Lines, Line Strip, Line Loop,, Lines with Adjacency, Line Strip with Adjacency, Triangles, Triangle Strip, Triangle Fan, Triangles with Adjacency, Triangle Strip with Adjacency,
Quads, Quad Strip
Application generates
these{
Geometry Shader
Point, Line, Line with Adjacency, Triangle, Triangle with Adjacency
Driver feeds theseone-at-a-time
into the Geometry Shader
Quads, Quad Strip{
{
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Points, LineStrips, TriangleStrips
Geometry Shader generates (almost) as
many of these as it wants
There needn’t be any correlation between Geometry Shader input type and Geometry Shader output type. Points can generate triangles, triangles can generate triangle strips, etc.
{
60
Additional Arguments are Now Available for glBegin( ):
GL_LINES_ADJACENCY_EXT
GL_LINE_STRIP_ADJACENCY_EXT
GL_TRIANGLES_ADJACENCY_EXT
GL TRIANGLE STRIP ADJECENCY EXT
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
GL_TRIANGLE_STRIP_ADJECENCY_EXT
New Adjacency Primitives
Lines with Adjacency0 1 2 3
N = 1
Line Strip with Adjacency1 2 3 4 50
4N vertices are given.(where N is the number of line segments to draw).A line segment is drawn between #1 and #2. Vertices #0 and #3 are there to provide adjacency information.
N = 1
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
N+3 vertices are given(where N is the number of line segments to draw).A line segment is drawn between #1 and #2, #2 and #3, …, #N and #N+1.Vertices #0 and #N+2 are there to provide adjacency information.
N = 3
61
New Adjacency Primitives
Triangles with Adjacency5
4
3
1
0 2
2 6
5
10
9
6N vertices are given(where N is the number of triangles to draw).Points 0, 2, and 4 define the triangle.Points 1, 3, and 5 tell where adjacent triangles are.
N = 1
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Triangle Strip with Adjacency 12
3
0 4
6
7
8
10
114+2N vertices are given(where N is the number of triangles to draw).Points 0, 2, 4, 6, 8, 10, …define the triangles.Points 1, 3, 5, 7, 9, 11, … tell where adjacent triangles are.
N = 4
gl_PositionIn[ ]
gl_TexCoordIn[ ] [ ]
gl FrontColorIn[ ]
If a Vertex Shader Writes Variables as:
gl_Position
gl_TexCoord[ ]
gl FrontColor
gl_Position
gl_TexCoord[ ]
gl FrontColor
then the Geometry Shader will Read Them as:
and will Write Them to the Fragment
Shader as:
gl_FrontColorIn[ ]
gl_BackColorIn[ ]
gl_PointSizeIn[ ]
gl_LayerIn[ ]
gl_FrontColor
gl_BackColor
gl_PointSize
gl_Layer
gl_FrontColor
gl_BackColor
gl_PointSize
gl_Layer
“varying” “varying in” “varying out”
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
In the Geometry Shader, the dimensions indicated by are given by the variable gl_VerticesIn, although you will already know this by the type of geometry you are inputting
GL_POINTSGL_LINESGL_LINES_ADJACENCY_EXTGL_TRIANGLESGL_TRIANGLES_ADJACENCY_EXT
12436
62
The Geometry Shader Can Assign These Variables:
gl_Position
gl_TexCoord[ ]
gl FrontColor
When the Geometry Shader calls
EmitVertex( )gl_FrontColor
gl_BackColor
gl_PointSize
gl_Layer
gl_PrimitiveID
this set of variables is copied to a slot in the shader’s Primitive Assembly step
When the Geometry Shader calls
EndPrimitive( )
the vertices that have been saved in the Primitive Assembly step are then assembled, rasterized, etc.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
y p , ,
Note: there is no “BeginPrimitive( )” routine. It is implied by (1) the start of the Geometry Shader, or (2) returning from the EndPrimitive( ) call.
Note: there is no need to call EndPrimitive( ) at the end of the Geometry Shader – it is implied.
RasterizerPrimitive Assembly
V
With just a Vertex and Fragment shader,“varying” means two different things
“varying”: per-vertex, one-at-a-time
Rasterizer
F“varying”: per-fragment, one-at-a-time
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
GLSL 1.3 introduces new declarations to remove this ambiguity
63
V “varying”: per-vertex, one-at-a-time
Primitive Assembly
With a Vertex, Geometry, and Fragment shader,“varying” means four different things
G“varying in [ ]”: per-vertex, collected into an array
“varying out”: per-vertex, one-at-a-time,latched by EmitVertex( )
Primitive Assembly
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
F“varying”: per-fragment, one-at-a-time
Rasterizer
If you have a Geometry Shader, then passing information from a Vertex Shader to a Fragment Shader can only happen via the
Geometry Shader
V varying vec4 gl_Position;varying vec4 Color;Color = gl_Color; Primitive Assembly
Gvarying in vec4 gl_PositionIn[3];varying in vec4 Color[3];
varying out vec4 gl_Position;varying out vec4 OColor;
Primitive Assembly
gl_Position = gl_PositionIn[0];OColor = Color[0];EmitVertex( );. . .
Already declared for you
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Fvarying vec4 OColor;
Rasterizer
64
Example: Shrinking Triangles
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
#version 120#extension GL_EXT_geometry_shader4: enable
uniform float Shrink;varying in vec3 Normal[3];varying out float LightIntensity;const vec3 LightPos = vec3( 0., 10., 0. );vec3 V[3];vec3 CG;
shrink.geom
;
voidProduceVertex( int v ){
LightIntensity = dot( normalize(LightPos - V[v]), Normal[v] );LightIntensity = abs( LightIntensity );LightIntensity *= 1.5;
gl_Position = gl_ModelViewProjectionMatrix * vec4( CG + Shrink * ( V[v] - CG ), 1. );EmitVertex();
}
void
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
voidmain(){
V[0] = gl_PositionIn[0].xyz;V[1] = gl_PositionIn[1].xyz;V[2] = gl_PositionIn[2].xyz;CG = ( V[0] + V[1] + V[2] ) / 3.;ProduceVertex( 0 );ProduceVertex( 1 );ProduceVertex( 2 );
}
65
Example: Silhouettes
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Example: Explosion Shader
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
66
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
VertexSh d S
VertexSh d
read attach
create
The GLSL Shader-creation Process
compile
ProgramGeometry Shader Source
Shader Source Shader
Geometry Shader attach
linkUse
create
read
compile
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Fragment Shader Source
Fragment Shader
attach
create
read
compile
67
#include "glew.h“
. . .
Initializing the GL Extension Wrangler (GLEW)
GLenum err = glewInit();if( err != GLEW_OK ){
fprintf( stderr, "glewInit Error\n" );exit( 1 );
}
fprintf( stderr, "GLEW initialized OK\n" );fprintf( stderr "Status: Using GLEW %s\n" glewGetString(GLEW VERSION) );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
fprintf( stderr, Status: Using GLEW %s\n , glewGetString(GLEW_VERSION) );
http://glew.sourceforge.net
#include <stdio.h>
Reading a Vertex, Geometry, or Fragment Shader source file into a character buffer
FILE *fp = fopen( filename, “r” );if( fp == NULL ) { . . . }
fseek( fp, 0, SEEK_END );int numBytes = ftell( fp ); // length of file
GLchar * buffer = new GLchar [numBytes+1];
rewind( fp ); // same as: “fseek( in 0 SEEK SET )”
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
rewind( fp ); // same as: fseek( in, 0, SEEK_SET )fread( buffer, 1, numBytes, fp );fclose( fp );buffer[numBytes] = ‘\0‘; // the entire file is now in a byte string
68
int status;int logLength;
GLuint vertShader = glCreateShader( GL_VERTEX_SHADER );
Creating and Compiling a Vertex Shader from that character buffer(Geometry and Fragment files work the same way)
glShaderSource( vertShader, 1, (const GLchar **)&buffer, NULL );delete [ ] buffer;glCompileShader( vertShader );CheckGlErrors( "Vertex Shader 1" );
glGetShaderiv( vertShader, GL_COMPILE_STATUS, &status );if( status == GL_FALSE ){
fprintf( stderr, “Vertex shader compilation failed.\n” );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
glGetShaderiv( vertShader, GL_INFO_LOG_LENGTH, &logLength );GLchar *log = new GLchar [logLength];glGetShaderInfoLog( vertShader, logLength, NULL, log );fprintf( stderr, “\n%s\n”, log );delete [ ] log;exit( 1 );
}CheckGlErrors( "Vertex Shader 2" );
How does that array of strings thing work?
GLchar *ArrayOfStrings[3];ArrayOfStrings[0] = “#define SMOOTH_SHADING”;ArrayofStrings[1] = “ . . . a commonly-used procedure . . . “;ArrayofStrings[2] = “ . . . the real vertex shader code . .. “;glShaderSource( vertShader, 3, ArrayofStrings, NULL );
GLchar *buffer[1];buffer[0] = “ . . . the entire shader code . . . “;glShaderSource( vertShader, 1, buffer, NULL );
These are two ways to provide a single character buffer:
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
GLchar *buffer = “ . . . the entire shader code . . . “;glShaderSource( vertShader, 1, (const GLchar **)&buffer, NULL );
69
Why use an array of strings as the shader input,instead of just a single string?
• You can use the same shader source and insert the appropriate #defines at the beginning
• You can insert a common header file (≈ a .h file)
• You can simulate a #include to re use common pieces of code• You can simulate a #include to re-use common pieces of code
if( Mode == PerVertexShading ){ . . . }else if( Mode == PerFragmentShading
#ifdef PER_VERTEX_SHADING{ . . . }#endif
If-tests versus preprocessing
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
else if( Mode == PerFragmentShading ){ . . . }
#endif
#ifdef PER_FRAGMENT_SHADING{ . . . }#endif
GLuint program = glCreateProgram( );
glAttachShader( program, vertShader );
glAttachShader( program fragShader );
Creating the Program and Attaching the Shaders to It
glAttachShader( program, fragShader );
glAttachShader( program, geomShader );
Program
VertexShader
Geometry
attach
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
ProgramyShader attach
Fragment Shader
attach
70
Linking the Program and Checking its Validity
glLinkProgram( program );CheckGlErrors( "Shader Program 1" );glGetProgramiv( program, GL_LINK_STATUS, &status );if( status == GL_FALSE ){{
fprintf( stderr, “Link failed.\n” );glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLength );log = new GLchar [logLength];glGetProgramInfoLog( program, logLength, NULL, log );fprintf( stderr, “\n%s\n”, log );delete [ ] log;exit( 1 );
}CheckGlErrors( "Shader Program 2" );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
( g );
glValidateProgram( program );glGetProgramiv( program, GL_VALIDATE_STATUS, &status );fprintf( stderr, “Program is %s.\n”, status == GL_TRUE ? “valid” : “invalid” );
Making the Program Active
glUseProgram( program );
This is now an “attribute” i e this shader combination is in
Making the Program Inactive(use the fixed function pipeline instead)
This is now an attribute , i.e., this shader combination is in effect until you change it
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
glUseProgram( 0 );
71
float lightLoc[3] = { 0., 100., 0. };
GLint location = glGetUniformLocation( program, “LightLocation” );
if( l i 0 )
Passing in Uniform Variables
if( location < 0 )fprintf( stderr, “Cannot find Uniform variable ‘LightLocation’\n” );
elseglUniform3fv( location, 3, lightLoc );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Passing in Attribute Variables
GLint location = glGetAttribLocation( program, “abArray” );
if( location < 0 ){{
fprintf( stderr, “Cannot find Attribute variable ‘abArray’\n” );}else{
glBegin( GL_TRIANGLES );glVertexAttrib2f( location, a0, b0 );glVertex3f( x0, y0, z0 );glVertexAttrib2f( location, a1, b1 );glVertex3f( x1, y1, z1 );
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
glVertexAttrib2f( location, a2, b2 );glVertex3f( x2, y2, z2 );
glEnd();}
72
voidCheckGlErrors( const char* caller ){
unsigned int glerr = glGetError();if( glerr == GL_NO_ERROR )
return;fprintf( stderr, "GL Error discovered from caller ‘%s‘: ", caller );switch( glerr ){
case GL INVALID ENUM:
Checking for Errors
case GL_INVALID_ENUM:fprintf( stderr, "Invalid enum.\n" );break;
case GL_INVALID_VALUE:fprintf( stderr, "Invalid value.\n" );break;
case GL_INVALID_OPERATION:fprintf( stderr, "Invalid Operation.\n" );break;
case GL_STACK_OVERFLOW:fprintf( stderr, "Stack overflow.\n" );break;
case GL_STACK_UNDERFLOW:f i tf( td "St k d fl \ " )
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
fprintf(stderr, "Stack underflow.\n" );break;
case GL_OUT_OF_MEMORY:fprintf( stderr, "Out of memory.\n" );break;
default:fprintf( stderr, “Unknown OpenGL error: %d (0x%0x)\n”, glerr, glerr );
}}
This is not a bad idea to do all through your OpenGL programs, even without shaders!
Writing a C++ Class to Handle Everything is Fairly Straightforward
int Polar;float K;GLSLProgram *Hyper = new GLSLProgram("hyper.vert", "hyper.geom", "hyper.frag" );
Setup:
Hyper->Use( );Hyper->SetVariable( "Polar", Polar );Hyper->SetVariable( "K", K );
Using the GPU program during display:
This loads, compiles, and links the shader.It prints error messages and returns NULL if something failed.
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009
Hyper->Use( 0 );
Reverting to the fixed-function pipeline during display:
73
Oregon State UniversityComputer Graphics
Brown CunninghamAssociatesFebruary 20, 2009