CS 450: COMPUTER GRAPHICS VISIBLE SURFACE DETECTION SPRING 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: V N 0 • …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: Nz 0 • Back-face culling = removing polygons that are facing away from the camera 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 use http://vignette2.wikia.nocookie.net/doom/imag es/b/b3/Imp.png/revision/latest/scale-towidth/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.
© Copyright 2026 Paperzz