cs 4363/6353 basic rendering. the graphics pipeline overview vertex processing coordinate...
TRANSCRIPT
CS 4363/6353
BASIC RENDERING
THE GRAPHICS PIPELINE OVERVIEW• Vertex Processing
• Coordinate transformations
• Compute color for each vertex
• Clipping and Primitive Assembly
• Assemble sets of vertices into lines and polygons
• Clipping volume culls out geometry outside, and clips geo that straddles
• Rasterization
• Determine which pixels are inside each polygon (primitive)
• The output is a set of fragments for each primitive
• Fragment Processing
• Fills in the pixels in the frame buffer (what you’re seeing right now!)
SHADERS(FROM 100,000 FEET. WELL, MAYBE 10,000 FEET)
• Shaders:
• Expose the programmable pipeline !
• Allow us to manipulate vertices and pixel colors
• Look very similar to C
• void main()
• Must be compiled and linked from source
• Generally have two shaders:
• Vertex shader (to handle vertex transformations and lighting)
• Fragment shaders (to handle per-pixel operations like lighting to determine color)
• Hundreds (or thousands) of GPUs are available
SHADERS AND PASSING DATA• Must feed shaders some data! Three ways to pass.
• Attributes (vertex shaders only):
• data that changes per vertex
• A four component vector (regardless if you use it or not)
• Copied from your OpenGL program into a buffer
• Uniforms (vertex/fragment shaders):
• A single value that is shared for all attributes
• Common for transformation matrices (vertex shader)
• Texture (mostly fragment shaders):
• Used for texture data
SIMPLE VERTEX EXAMPLE#version 150
in vec4 vPosition; // This data is from your OpenGL code
void main () {
gl_Position = vPosition;
}
SIMPLE FRAGMENT SHADER#version 150
out vec4 fColor;
void main () {
fColor = vec4(1.0, 0.0, 0.0, 1.0);
}
// Hard-coded red!
SHADERS AND PASSING DATA• outs/ins
• Used for passing data between shaders
• Client (OpenGL code) has no access to these variables
• Vertex shader’s out variable corresponds to the fragment shader’s in variable.
RENDERING OPTIONS• We typically create a single batch of vertices to draw
• We generally set up all “features” before drawing anything
• State machine mentality
• We always have vertices, but we can render them in 7 different ways
• GL_POINTS
• GL_LINES
• GL_LINE_STRIP
• GL_LINE_LOOP
• GL_TRIANGLES**
• GL_TRIANGLE_STRIP
• GL_TRIANGLE_FAN
RENDERING OPTIONS(GL_POINTS)
• Can change the point sizes, but not important right now
• Points are always square unless anti-aliased
RENDERING OPTIONS(GL_LINES)
• Connects in pairs (line segments), so should have an even number of points
• Change line width with glLineWidth (GLfloat width);
RENDERING OPTIONS(GL_LINE_STRIP)
• In a connect-the-dots fashion, draw from one vertex to another
• How would you do this with GL_LINES?
RENDERING OPTIONS(GL_LINE_LOOP)
• Closes the loop
• Is typically what you would use for outlines/tracing
RENDERING OPTIONS(OTHERS)
• Some of these are allowed…
RENDERING OPTIONS(OTHERS)
• Some of these aren’t…
• NO QUADS! Triangles only…
TRIANGLE WINDING• Simply means the order of the vertices you specify
• Clockwise
• Counter-Clockwise
• Why is this important?
• Clockwise is back facing
• Counter-clockwise is front facing
• Long story short:
• If you specify in reverse order, sometimes you won’t see anythingor it will be reversed
• Can reverse using glFrontFace (GL_CW);V0 V1
V2
V0 V2
V1
TRIANGLE STRIPS• Specify the first triangle (V0, V1, V2)
V0 V1
V2
TRIANGLE STRIPS• Specify the first triangle (V0, V1, V2)
• The next vertex (V3) creates a new triangle (V1, V2, V3)
V0 V1
V2 V3
TRIANGLE STRIPS• Specify the first triangle (V0, V1, V2)
• The next vertex (V3) creates a new triangle (V1, V2, V3)
• The next vertex (V4) creates a new triangle (V2, V3, V4)
V0 V1
V2 V3
V4
EXAMPLE
• From Wikipedia…
TRIANGLE FANS• Can create a fan where V0 is the central vertex
• Specify first triangle, then each new vertex is a wedge of the fan
V0 V1
V2
TRIANGLE FANS• Can create a fan where V0 is the central vertex
• Specify first triangle, then each new vertex is a wedge of the fan
• Still uses V0
V0 V1
V2
V3
TRIANGLE FANS• Can create a fan where V0 is the central vertex
• Specify first triangle, then each new vertex is a wedge of the fan
• Still uses V0
V0 V1
V2
V3
V4
EXAMPLE OF TRIANGLE FAN
CULLING AND DEPTH TESTING• You’re going to be drawing a lot of triangles
• What happens if you draw one triangle on top of another?
• What if the second triangle is far away?
• Sort triangles of an object (painter’s algorithm)?
• What about several objects on the screen?
• Also, should you be able to see the inside of geometry?
• Basically, there are two problems:
• Unseen triangles are unlit
• The depth of the triangles is important
HOUSTON, WE HAVE A PROBLEM(IMAGE FROM OPENGL SUPERBIBLE)
• Sometimes rendering the far-side triangles (which are unlit)
BACKFACE CULLING• Simply means “Don’t draw triangles that don’t face the camera”
• Two steps in OpenGL
• glEnable (GL_CULL_FACE);
• glCullFace (GL_BACK);
• glCullFace could also use:
• GL_FRONT
• GL_FRONT_AND_BACK
CULLING THE BACKFACE(S)• Problem solved?
BUT WAIT!(IMAGES FROM OPENGL SUPERBIBLE)
DEPTH TESTING• Just because we culled the back-facing triangles doesn’t mean they’re sorted!
• Depth testing:
• Removes hidden surfaces
• Each pixel has a depth (z-value)
• Higher values mean closer to the camera
• This value is stored in the depth buffer
• glEnable (GL_DEPTH_TEST);
• Is this starting to make sense?
glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
POLYGON RENDERING MODES• Polygons do not have to be filled
• We have 3 modes to draw polygons:
• GL_FILL – what we’ve been using
• GL_LINE – 3D wireframe
• GL_POINT – just the vertices
• Call glPolygonMode() to change rendering value:
// renders front and back facing polys in wireframe
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
GL_LINE
• Backface culling and depth testing are turned on
A NOTE ABOUT POLYGON OFFSET• You can skip it
• Sometimes draw two triangle very close to the same depth (called decaling)
• This creates “z-fighting”
• Part of the further polygon shows
• Before rendering closer triangle:
glEnable (GL_POLYGON_OFFSET_LINE);
glPolygonOffset(-1.0f, -1.0f);
SCISSOR TEST• We won’t be using this in our code, but:
• Used to increase performance
• Updates only the portion within a defined area(i.e. doesn’t update anything outside of that area)
• By default, scissor test is the size of the window
• Use glScissor (int x, int y, int width, int height):
glEnable (GL_SCISSOR_TEST);
glScissor (100, 100, 600, 400); // only render in that area
BLENDING• Without depth testing, color values overwrite one another
• With depth testing, new fragments may replace old ones
• Discards further fragments
• This no longer happens with OpenGL blending:
glEnable (GL_BLENDING);
• Remember, each color has a red, green, blue and alpha!
SPECIFYING HOW TO BLEND• We must specify how the blending occurs
• Destination color is the color already in the color buffer
• Source color is the one we’re about to write into the color buffer
Cf = (Cs * S) + (Cd * D)
• Where:
• Cf is the final color, Cs is the source color and Cd is the destination color
• S is the source blending factor
• D is the destination blending factor
MOST COMMON METHOD• glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
• Take source and multiply rgb (colors) by its alpha value
• Take destination and multiply rgb by (1-source alpha)
• Example:
• Cd = (1.0f, 0.0f, 0.0f, 1.0f) //Red
• Cs = (0.0f, 0.0f, 1.0f, 0.6f) // Blue, with source alpha 0.6
• D = 1.0f – 0.6 == 0.4f
• Cf = (Blue*0.6) + (Red*0.4)
EXAMPLE
ONE FINAL NOTE• We can change the underlying equation as well using glBlendEquation():
• GL_FUNC_ADD Cf = (Cs*S)+(Cd*D)
• GL_FUNC_SUBTRACT Cf = (Cs*S)-(Cd*D)
• GL_FUNC_REVERSE_SUBTRACT Cf = (Cd*D) - (Cs*S)
• GL_MIN Cf = min(Cs,Cd)
• GL_MAX Cf = max(Cs,Cd)
ANTIALIASING• We have square pixels, which make the image look computer-generated
• The visual aspect of this is called “the jaggies”
• To eliminate, OpenGL uses blending of source with surrounding destination pixels
• So:
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
• Then:
glEnable (GL_POINT_SMOOTH); // and/or
glEnable (GL_LINE_SMOOTH); // and/or
glEnable (GL_POYGON_SMOOTH); // **
// ** outdated or not supported at all!
EXAMPLE
MULTISAMPLING• Helps to smooth out polygons
• Creates another buffer (color, depth and stencil)
• All primitives are sampled multiple times, then “averaged”
• You take a performance hit here, but looks good!
• Point/Line antialiasing is disable when multisampling is enabled
• First:
glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH|GLUT_MULTISAMPLE);
• Then:
glEnable (GL_MULTISAMPLE);