Basic Rendering

advertisement
BASIC RENDERING
CS 4363/6353
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…
V1
TRIANGLE WINDING
•
Simply means the order of the vertices you specify
• Clockwise
• Counter-Clockwise
•
V0
V2
Why is this important?
V2
• Clockwise is back facing
• Counter-clockwise is front facing
•
Long story short:
• If you specify in reverse order,
sometimes you won’t see anything
or it will be reversed
•
Can reverse using glFrontFace (GL_CW);
V0
V1
TRIANGLE STRIPS
•
Specify the first triangle (V 0, V1, V2)
V2
V0
V1
TRIANGLE STRIPS
•
Specify the first triangle (V 0, V1, V2)
•
The next vertex (V 3) creates a new triangle (V 1, V2, V3)
V2
V0
V3
V1
TRIANGLE STRIPS
•
Specify the first triangle (V 0, V1, V2)
•
The next vertex (V 3) creates a new triangle (V 1, V2, V3)
•
The next vertex (V 4) creates a new triangle (V 2, V3, V4)
V4
V2
V0
V3
V1
EXAMPLE
•
From Wikipedia…
TRIANGLE FANS
•
Can create a fan where V 0 is the central vertex
•
Specify first triangle, then each new vertex is a wedge of the fan
V2
V0
V1
TRIANGLE FANS
•
Can create a fan where V 0 is the central vertex
•
Specify first triangle, then each new vertex is a wedge of the fan
•
Still uses V 0
V3
V2
V0
V1
TRIANGLE FANS
•
Can create a fan where V 0 is the central vertex
•
Specify first triangle, then each new vertex is a wedge of the fan
•
Still uses V0
V3
V2
V4
V0
V1
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) + (C d * D)
•
Where:
• Cf is the final color, C s is the source color and C d 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);
Download