Upload
cecil-scott
View
216
Download
0
Tags:
Embed Size (px)
Citation preview
CS 450: COMPUTER GRAPHICS
VISIBLE SURFACE DETECTIONSPRING 2015
DR. MICHAEL J. REALE
INTRODUCTION
• We’ve talked about drawing surfaces, but what happens when a surface is hidden?
• E.g., at the back of an object, obscured by another surface, etc.
• We need to determine which surfaces (or parts of surfaces) are visible
• Two general categories (which sometimes overlap):
• Object-space approaches deal with objects/primitives themselves
• Image-space approaches deal with projected primitives at pixel level
OVERVIEW
• In this slide deck, we will cover the following approaches:
• Back-face detection
• Depth-buffer/Z-buffer
• A-buffer
• BSP trees
• Octrees
• Ray-casting
BACK-FACE DETECTION
BACK-FACE CULLING
• If the normal is facing away from the camera, then the surface is probably behind an object
• In other words, given a normal N and a view direction V, if:
• …the surface is pointing away from the camera and can be removed
• If we’ve already performed the view transform, we only need look at the z coordinate of the normal:
• Back-face culling = removing polygons that are facing away from the camera
0NV
0zN
BACK-FACE CULLING
• All non-overlapping, convex shapes done!
• Concave shapes may obscure themselves more work to do
• Overlapping shapes (convex or concave) still more work to do
• However, it is always a good preprocessing step to other approaches generally cuts the total number of polygons to render in half
OPENGL FACE CULLING
• To enable or disable face culling in OpenGL:
• glEnable(GL_CULL_FACE);
• glDisable(GL_CULL_FACE);
• Notice I said FACE culling (not back-face culling). In OpenGL, you can specify what you want culled with glCullFace:
• glCullFace(GL_BACK) cull back faces (default)
• glCullFace(GL_FRONT) cull front faces
• glCullFace(GL_FRONT_AND_BACK) cull front AND back faces no faces drawn (but lines/points still drawn)
• NOTE: Remember that vertices should be in COUNTERclockwise order!
DEPTH-BUFFER/Z-BUFFER
DEPTH-BUFFER/Z-BUFFER
• Depth-buffer/Z-buffer approach
• Pretty much the standard for depth sorting in almost all applications
• Implemented in graphics hardware
• Have depth buffer = separate buffer that holds depth values
• Initialize to 1.0 (remember: normalized device coordinates)
• If projected pixel z < depth[x,y]:
• Depth[x,y] = z
• Color[x,y] = pixel’s color
• Otherwise, ignore pixel
DEPTH-BUFFER/Z-BUFFER
DEPTH-BUFFER/Z-BUFFER
• Advantages:
• Very easy to implement
• For opaque surfaces, does not matter what order they are rendered in!
• Disadvantages:
• Does not work properly with transparent or semi-transparent surfaces (if drawn out of order)
• Can be a little inefficient might already have nearest pixel, but still have to check every other overlapping polygon on that pixel
DEPTH-BUFFER/Z-BUFFER IN OPENGL
• To enable/disable depth-buffer/z-buffer testing in OpenGL:
• glEnable(GL_DEPTH_TEST);
• glDisable(GL_DEPTH_TEST);
• You can also set how the z-buffer works with glDepthFunc()
• When clearing your color buffer, you should also clear out your depth buffer:
• glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
• In GLUT, you also have to make sure you have a depth-buffer, so you have to pass in GLUT_DEPTH to glutInitDisplayMode():
• glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
A-BUFFER
A-BUFFER
• A-buffer
• Extension of the z-buffer
• Unlike the z-buffer, can store multiple fragments per pixel
• Each position in A-buffer has two fields:
• Depth field = stores real-number value (positive, negative, or zero)
• Surface data field = stores surface data OR a pointer
• If (depth field >= 0):
• Depth field = depth of surface
• Surface data field = color (and other info) of fragment
• Otherwise:
• Surface data field = linked list of surface data (RGB, depth, opacity, percent of area coverage, surface identifier, etc.)
• Final rendering merge lists appropriately to get final color
ACCUMULATION BUFFER
• The buffer used for the A-buffer approach is called an accumulation buffer
• That said, accumulation buffers in OpenGL are implemented as a buffer with a single color value per pixel
• Do not draw directly into; copy/add whole color buffer into it
• Use glAccum(GLenum op, GLfloat value); values of op:
• GL_ACCUM = read from color buffer, multiply by value, and add to accumulation buffer
• GL_LOAD = same as GL_ACCUM, except it REPLACES the values in the accumulation buffer
• GL_RETURN = takes values from the accumulation buffer, multiplies them by value, and places the result in the color buffer(s) enabled for writing.
• GL_ADD /GL_MULT = simply add or multiply the value of each pixel in the accumulation buffer by value and then return it to the accumulation buffer. For GL_MULT, value is clamped to be in the range [-1.0,1.0]. For GL_ADD, no clamping occurs.
• Used for anti-aliasing and motion blur
BSP TREES
BSP TREES
• BSP Trees = Binary Space Partitioning Trees
• Used for depth sorting objects
• Also used for collision detection and intersection calculations (e.g., for ray tracing)
• Two varieties: axis-aligned and polygon-aligned
• Basic idea:
• Use plane to divide space in two
• Sort geometry into these two spaces
• Repeat process recursively
• Traverse trees in a certain way contents sorted from front-to-back from any point of view
• Sorting approximate for axis-aligned and exact for polygon-aligned BSPs
AXIS-ALIGNED BSP TREES
• Enclose whole scene in axis-aligned bounding box (AABB)
• Recursively subdivide that box into smaller boxes
• Splitting plane may split box exactly in half OR may shift a little in position
• Each child box contains some number of objects repeat splitting until some criteria met
• What plane should we use?
• Can cycle through each axis for each plane (first x, then y, then z, then x again, and so on) k-d trees
• Can pick largest side of box and split along this direction
• Want to avoid splitting objects if possible; if object is split, you can either:
• Store at current level of tree only one copy of object in tree, but not as efficient if small objects get stuck up in upper levels
• Store in both child nodes tighter bounds for larger objects, but objects in multiple locations
AXIS-ALIGNED BSP TREES
• To traverse tree:
• Start at root node
• Recursively pick branch on same side as viewer
• When you reach the bottom, go back and do other side of tree
• Effectively a depth-first traversal
• Not EXACTLY sorted front-to-back, since:
• Contents of leaf nodes may not be sorted themselves
• Objects may be in multiple nodes of the tree, depending on how splitting is done
POLYGON-ALIGNED BSP TREES• Particularly useful for rendering static/rigid
geometry in an exact sorted order
• Popular for games like Doom, back when there was no hardware Z-buffer
• Still used for collision detection
• Polygons = dividing planes
• Start with one polygon as root
• Divide all other polygons into inside and outside plane of polygon
• If other polygon intersects plane split polygon
• Choose another polygon in each half-space as divider
• Repeat process recursively until all polygons in BSP tree
• Time-consuming process usually create tree once and store for further usehttp://vignette2.wikia.nocookie.net/doom/images/b/b3/Imp.png/revision/latest/scale-to-width/256?cb=20050113171050
POLYGON-ALIGNED BSP TREES
• Challenge: ideally want balanced BSP tree i.e., depth of all branches is the same
• Useful property: for a given view, tree can be traversed in strictly back to front (or front to back) order
• Determine on which side the root plane the camera is located
• Go down branch on other side of camera
• Repeat process recursively
• Go back up to other branches when hit bottom
POLYGON-ALIGNED BSP TREES
• Example above (back to front):
• Start at A C on other side
• At C G on other side
• Output G go back up tree
• Output C go down other branch F
• Output F go back up tree
• Go back up to A
• Output A go down other branch B
• At B E on other side
• Output E go back up tree
• Output B go down other branch D
• Output D
• Final drawing order: G, C, F, A, E, B, D
OCTREES
OCTREES• Octrees
• Similar to axis-aligned BSP tree
• Enclosed entire area in minimal axis-aligned box
• Split simultaneously in all 3 axes split point at center of box makes eight new boxes
• Keep splitting recursively until max depth is reached or have certain number of objects in box
• 3D version of a quadtree:
• Example: split until box is 1) empty or 2) contains only one object
OCTREES
• What if object straddles two leaf nodes?
• Just store in both leaf nodes
• Use smallest box that contains entire object inefficient for a small object in the center of a large node
• E.g., star object in example above
• Split objects introduces more primitives
• Have pointer to object less efficient and makes editing octree more difficult
OCTREES VS. BSP TREES
• BSP tree can partition things the same way as an octree
• Octree doesn’t need to store additional plane information like BSP trees
• BSP trees can be more efficient because of better splitting
RAY-CASTING
RAY-CASTING
• Ray-casting = shooting a ray from the camera through each position in the projection plane and checking what object(s) we intersect with nearest one is used as color for a pixel
• Alternative (non-real-time) rendering approach
• Works with polygonal objects as well as implicit objects (e.g., F(x,y,z) = 0)
• Must intersect ray with ALL objects in scene and pick nearest point inefficient
• Partial solution: use BSP trees or similar approaches to reduce intersection computations
RAY-CASTING VS. RAY-TRACING
• Ray-casting = shooting ray to nearest object; special case of ray-tracing
• Ray-tracing = traces multiple ray paths to get global reflection, refraction, etc.