This document discusses algorithms for hidden surface elimination and visibility determination in 3D computer graphics. It covers several techniques including back-face culling, the painter's algorithm, depth sorting, the z-buffer algorithm, and incremental scanline algorithms. The key topics are determining what parts of 3D objects are visible and hidden when projecting onto a 2D viewport or image.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0 ratings0% found this document useful (0 votes)
62 views22 pages
Visibility
This document discusses algorithms for hidden surface elimination and visibility determination in 3D computer graphics. It covers several techniques including back-face culling, the painter's algorithm, depth sorting, the z-buffer algorithm, and incremental scanline algorithms. The key topics are determining what parts of 3D objects are visible and hidden when projecting onto a 2D viewport or image.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22
Visibility Determination
• AKA, hidden surface elimination
Visibility Algorithms Roger Crawfis CIS 781 This set of slides reference slides used at Ohio State for instruction by Prof. Machiraju and Prof. Han-Wei Shen. Hidden Lines Hidden Lines Removed Hidden Surfaces Removed Topics Backface Culling Hidden Object Removal: Painters Algorithm Z-buffer Spanning Scanline Warnock Atherton-Weiler List Priority, NNA BSP Tree Taxonomy Where Are We ? Back-face Culling Canonical view volume (3D image space) Clipping done division by w z > 0 y y clipped line Problems ? clipped line x 1 x near 1 far Conservative algorithm z 0 1 z image plane Real job of visibility never solved near far Back-face Culling Back-face Culling • If a surface’s normal is pointing in the same general direction as our eye, then this is a back face • Only handles faces oriented • The test is quite simple: if N * V > 0 then we reject the away from the viewer: surface – Closed objects – Near clipping plane does not intersect the objects • If test is in eye- • Gives complete solution for a single convex space, then if polyhedron. Nz > 0 reject. • Still need to sort, but we have reduced the number of primitives to sort. Painters Algorithm Sort objects in depth order Point sorting vs Polygon Sorting Draw all from Back-to-Front (far-to-near) Simply overwrite the existing pixels. • What does it mean to sort two line segments? Is it so simple? – Zmin? at z = 22, at z = 18, at z = 10, – Zmax? – Slope? X – Length? z Y 1 2 3 3D Cycles Form of the Input How do we deal with cycles? Object types: what kind of objects does it handle? How do we deal with intersections? convex vs. non-convex How do we sort objects that overlap in Z? polygons vs. everything else - smooth curves, non- continuous surfaces, volumetric data Z Form of the output Object Space Algorithms Volume testing – Weiler-Atherton, etc. Precision: image/object space? input: convex polygons + infinite eye pt output: visible portions of wireframe edges Object Space Image Space Geometry in, geometry out Geometry in, image out Independent of image resolution Visibility only at Followed by scan pixel centers conversion Image-space algorithms Conservative Visibility Algorithms Traditional Scan Conversion and Z-buffering Viewport clipping Hierarchical Scan Conversion and Z-buffering Back-face culling input: any plane-sweepable/plane-boundable Warnock's screen-space subdivision objects preprocessing: none output: a discrete image of the exact visible set Z-buffer Z-buffer: Scanline Z-buffer is a 2D array that stores a depth value for each pixel. I. for each polygon do for each pixel (x,y) in the polygon’s projection do InitScreen: z := -(D+A*x+B*y)/C; for i := 0 to N do DrawZpixel(x, y, z, polygon’s color); for j := 1 to N do II. for each scan-line y do Screen[i][j] := BACKGROUND_COLOR; Zbuffer[i][j] := ∞; for each “in range” polygon projection do for each pair (x1, x2) of X-intersections do DrawZpixel (x, y, z, color) for x := x1 to x2 do if (z <= Zbuffer[x][y]) then z := -(D+A*x+B*y)/C; Screen[x][y] := color; Zbuffer[x][y] := z; DrawZpixel(x, y, z, polygon’s color); If we know zx,y at (x,y) then: zx+1,y = zx,y - A/C Incremental Scanline Incremental Scanline (contd.) Ax + By + Cz + D = 0 All that was about increment for pixels on each scanline. − ( Ax + By + D ) z= ,C ≠ 0 How about across scanlines for a given pixel ? C On a scan line Y = j, a constant Assumption: next scanline is within polygon Thus depth of pixel at (x1=x+∆x,j) − ( Ax + Bj + D ) − ( Ax + Bj + D ) − ( Ax + By 1 + D ) ( Ax + By + D ) z1 − z = 1 + z1 − z = + C C C C A( x − x1 ) A( y − y1 ) z1 − z = z1 − z = C C A B z1 = z − ( )∆x , since ∆x = 1, z1 = z − ( )∆y , since ∆y = 1, C C A B z =z− 1 z1 = z − C C Z-buffer - Example Non-Planar Polygons ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ P3 ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ( y1 − y s ) ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ Z-buffer za = z1 + ( z4 − z1 ) ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ( y1 − y 4 ) ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ( y1 − y s ) ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ zb = z1 + ( z2 − z1 ) ( y1 − y 2 ) ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ P4 P2 ( xa − x p ) zp = za + ( zb − za ) ys za zp zb ( xa − x b ) Screen P1 Bilinear Interpolation of Depth Values [0,7,5] [6,7,5] 5 5 5 5 5 5 5 [0,6,7] 5 5 5 5 5 5 7 5 5 5 5 5 6 7 5 5 5 5 5 6 7 5 5 5 4 5 6 7 5 5 3 4 5 6 7 5 2 3 4 5 6 7 [0,1,5] [0,1,2] [5,1,7] 5 5 5 5 5 5 5 ∞ 5 5 5 5 5 5 5 ∞ 5 5 5 5 5 5 ∞ ∞ 5 5 5 5 5 5 ∞ ∞ 5 5 5 5 5 ∞ ∞ ∞ 5 5 5 5 5 ∞ ∞ ∞ 5 5 5 5 ∞ ∞ ∞ ∞ 5 5 5 5 ∞ ∞ ∞ ∞ 5 5 5 ∞ ∞ ∞ ∞ ∞ 4 5 5 7 ∞ ∞ ∞ ∞ 5 5 ∞ ∞ ∞ ∞ ∞ ∞ 3 4 5 6 7 ∞ ∞ ∞ 5 ∞ ∞ ∞ ∞ ∞ ∞ ∞ 2 3 4 5 6 7 ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ Non Trivial Example ? Example Rectangle: P1(10,5,10), P2(10,25,10), P3(25,25,10), P4(25,5,10) Triangle: P5(15,15,15), P6(25,25,5), P7(30,10,5) Frame Buffer: Background 0, Rectangle 1, Triangle 2 Z-buffer: 32x32x4 bit planes Z-Buffer Advantages Z-Buffer Disadvantages Does not do transparency easily Simple and easy to implement Aliasing occurs! Since not all depth questions can be Amenable to scan-line algorithms resolved Can easily resolve visibility cycles Anti-aliasing solutions non-trivial Handles intersecting polygons Shadows are not easy Higher order illumination is hard in general Spanning Scan-Line Spanning Scan Line Algorithm Can we do better than scan-line Z-buffer ? • Use no z-buffer Scan-line z-buffer does not exploit • Each scan line is subdivided into several "spans" Scan-line coherency across multiple scan-lines • Determine which polygon the current span belongs to Or span-coherence ! • Shade the span using the current polygon’s color Depth coherency • Exploit "span coherence" : How do you deal with this – scan-conversion algorithm and a little • For each span, only one visibility test needs to be done more data structure – Assuming no intersecting polygons. Spanning Scan Line Algorithm Spanning Scan Line Algorithm • A scan line is subdivided into a sequence of spans • Each span can be "inside" or "outside" polygon areas – "outside“: no pixels need to be drawn (background color) – "inside“: can be inside one or multiple polygons • If a span is inside one polygon, the pixels in the span will be drawn with the color of that polygon • If a span is inside more than one polygon, then we need to compare the z values of those polygons at the scan line edge intersection point to determine the color of the pixel When there are multiple Determine a span is inside or polygons outside (single polygon) • When a scan line intersects an edge of a • Each polygon will have its own in/out flag polygon • There can be more than one polygon having – for a 1st time, the span becomes "inside" of the polygon from that intersection point on the in/out flags to be "in" at a given instance – for a 2nd time, the span becomes "outside“ of the • We want to keep track of how many polygons polygon from that point on the scan line is currently in • Use a "in/out" flag for each polygon to keep • If there is more than one polygon "in", we track of the current state need to perform z value comparison to • Initially, the in/out flag is set to be "outside" determine the color of the scan line span (value = 0 for example). Invert the tag for “inside”. Z value comparison Many Polygons ! ET x y max ∆x poly-ID • When the scan line intersects an edge, leaving the top-most polygon, we use the color of the remaining polygon if there is now only 1 polygon "in". PT poly-ID A,B,C,D color in/out flag • If there is still more than one polygon with an "in" flag, we need to perform z comparison, but only when the Use a PT entry for each polygon scan line leaves a non-obscured polygon. When polygon is considered, Flag is true Multiple polygons can have their flags set to true Use IPL as active In-Polygon List ! Example Spanning Scan-Line: Example 1 Y AET IPL BG a I x0, ba , bc, xN BG, BG+S, BG IV II x0, ba , bc, 32, 13, xN BG, BG+S, BG, BG+T, BG S T III x0, ba , 32, ca, 13, xN BG, BG+S, BG+S+T, BG+T, BG 2 III IV x0, ba , ac, 12, 13, xN BG, BG+S, BG, BG+T, BG c 1 II BG a 3 IV I S T b 2 III c X0 XN II 3 I Think of ScanPlanes to understand ! b X0 XN Some Facts ! Spanning Scan-Line build ET, PT -- all polys+BG poly Scan Line I: Polygon S is in and flag of S=true AET := IPL := Nil; for y := ymin to ymax do ScanLine II: Both S and T are in and flags are e1 := first_item ( AET );IPL := BG; disjointly true while (e1.x <> MaxX) do e2 := next_item (AET); Scan Line III: Both S and T are in simultaneously poly := closest poly in IPL at [(e1.x+e2.x)/2, y] draw_line(e1.x, e2.x, poly-color); Scan Line IV: Same as Scan Line II update IPL (flags); e1 := e2; end-while; IPL := NIL; update AET; end-for; Penetrating Polygons Depth Coherence Y AET IPL • Depth relationships may not change I x0, ba , 23, ad, 13, xN BG, BG+S, S+T, BG+T,BG between polygons from one scan-line to the next scan-line. I’ x0, ba , 23, ec, ad, 13, xN BG, BG+S, BG+S+T, BG+S+T, BG+T, BG • These can be kept track using the 1 BG a (active edge table) AET and the (polgon table) PT. False edges and new polygons! S T 2 e • How about penetrating polygons? d I c b 3 Area Subdivision 1 Warnock : One Polygon (Warnock’s Algorithm) if it surrounds then draw_rectangle(poly-color); Divide and conquer: the relationship of a display area and a polygon after projection is one of the four basic else begin cases: if it intersects then poly := intersect(poly, rectangle); draw_rectangle(BACKGROUND); draw_poly(poly); end else; What about contained and disjoint ? surround intersect contained disjoint Warnock’s Algorithm At A Single Pixel Level • Starting with the entire display, we check the following • When the recursion stops and none of the four cases. If none hold, we subdivide the area and repeat, otherwise, we stop and perform the action four cases hold, we need to perform a depth associated with the case sort and draw the polygon with the closest Z 1. All polygons are disjoint wrt the area -> draw the background color value 2. Only 1 intersecting or contained polygon -> draw background, and then draw the contained portion of the polygon • The algorithm is done at the object space 3. There is a single surrounding polygon -> draw the entire area in level, except scan conversion and clipping the polygon’s color 4. There are more than one intersecting, contained, or surrounding are done at the image space level polygons, but there is a front surrounding polygon -> draw the entire area in the polygon’s color • The recursion stops at the pixel level 0 1 0 0 1 M M 1 1 1 M M 0 0 0 0 Warnock : Zero/One Polygons Warnock(rectangle, poly-list) warnock01(rectangle, poly) new-poly := clip(rectangle, poly); new-list := clip(rectangle, poly-list); if length(new-list) = 0 then if new-poly = NULL then draw_rectangle(BACKGROUND); return; draw_rectangle(BACKGROUND); if length(new-list) = 1 then draw_rectangle(BACKGROUND); else draw_poly(poly); return; draw_rectangle(BACKGROUND); draw_poly(new-poly); return; if rectangle size = pixel size then poly := closest polygon at rectangle center draw_rectangle(poly color); return; warnock(top-left quadrant, new-list); warnock(top-right quadrant, new-list); warnock(bottom-left quadrant, new-list); surround intersect contained disjoint warnock(bottom-right quadrant, new-list); 1-polygon 0-polygon 1 1 0 0 M M M 1 1 M M 1 M M M M M M M M 1 1 1 M M M M M M M M 0 0 1 1 1 Area Subdivision 2 Weiler -Atherton Algorithm Object space Like Warnock Output – polygons of arbitrary accuracy Weiler-Atherton Clipping Weiler-Atherton Clipping • General polygon clipping algorithm • First, find all of the intersection points • Allows one to clip a concave polygon between edges of the two polygons. against another concave polygon. D S: A,B,C,D,E B 4 2 b T: a,b,c,d,e a 6 C 5 1 c d T A S 3 e E Weiler-Atherton Clipping Weiler-Atherton Clipping • Now, rebuild the polygon’s such that they • Find an intersecting vertex of the polygon to be include the intersection points in their clipped that starts outside and goes inside the clock-wise ordering. clipping region. D S: A,1,4,B,2,6,C,D,5,3,E • Traverse the polygon until another D intersection B B 2 b T: a,4,2,b,6,c,5,d,e,3,1 point is 2 b a 4 a 4 S: A,1,4,B,2,6,C,D,5,3,E 6 C found. 6 C 1 c 5 d 1 c 5 d T: a,4,2,b,6,c,5,d,e,3,1 Clip: 6,c,5,… T T A A S 3 S 3 e e E E Weiler -Atherton Algorithm Weiler-Atherton Clipping • Subdivide along polygon boundaries (unlike Warnock’s rectangular boundaries in image space); • Switch from walking around the polygon 1, to • Algorithm: walking around polygon 2, when an intersection is 1. Sort the polygons based on their minimum z distance detected. 2. Choose the first polygon P in the sorted list • Stop when we reached the initial point. 3. Clip all polygons left against P, create two lists: B b – Inside list: polygon fragments inside P (including P) 2 a 4 S: A,1,4,B,2,6,C,D,5,3,E – Outside list: polygon fragments outside P 6 C 1 c 5 d T: a,4,2,b,6,c,5,d,e,3,1 4. All polygon fragments on the inside list that are behind P are discarded. If there are polygons on the inside list that are Clip: 6,c,5,3,1,4,2,6 T in front of P, go back to step 3), use the ’offending’ A S 3 polygons as P e 5. Display P and go back to step (2) E t Weiler -Atherton Algorithm r WA_display(polys : ListOfPolygons) t sort_by_minZ(polys); r while (polys <> NULL) do WA_subdiv(polys->first, polys) end; WA_subdiv(first: Polygon; polys: ListOfPolygons) inP, outP : ListOfPolygons := NULL; for each P in polys do Clip(P, first->ancestor, inP, outP); for each P in inP do if P is behind (min z)first then discard P; for each P in inP do if P is not part of first then WA_subdiv(P, inP); for each P in inP do display_a_poly(P); 2 1 3 polys := outP; end; 0 .2 0 .8 0 .3 List Priority Algorithms 0 .5 • Find a valid order for rendering. • Only consider cases where the sort matters. x/y List Priority Algorithms 1 2 4 If objects do not overlap in X or in Y there is no need 3 4 for hidden object removal process. z If they do not overlap in the Z dimension they can be sorted by Z and rendered in back (highest priority)-to- x/y front (lowest priority) order (Painter’s Algorithm). ? 1 It is easy then to implement transparency. How do we sort ? – different algorithms differ 2 z Newell, Newell, Sancha Algorithm Newell, Newell, Sancha Algorithm 1. Sort by [minz..maxz] of each polygon rearrange(P, Q, flag) 2. For each group of unsorted polygons G if (P and Q do not have overlapping x-extents, return P, Q resolve_ambiguities(G); if (P and Q do not have overlapping y-extents, return P, Q 3. Render polygons in a back-to-front order. resolve_ambiguities is basically a sorting algorithm that relies on if all Q is on the opposite side of P from the eye return P, Q the procedure rearrange(P, Q): if all P is on the same side of Q from the eye return P, Q if not overlap-projection(P, Q) return P, Q resolve_ambiguities(G) not-yet-done := TRUE; flag := TRUE; // more work is needed while (not-yet-done) do if all Q is on the same side of P from the eye return Q, P not-yet-done := FALSE; if all P is on the opposite side of Q from the eye return Q, P for each pair of polygons P, Q in G do --- bubble sort split(P, Q, p1, p2); -- split P by Q L := rearrange(P, Q, not-yet-done); insert L into G instead of P,Q return (p1, p2, Q); Newell-Newell-Sancha Sorting Newell-Newell-Sancha Sorting • Q is on the opposite side of P. • P is on the same side of Q. • Means, all of Q’s vertices are behind the • Means, all of P’s vertices are in front of the half-plane defined by P. half-plane defined by Q. P P Q Q P P Q Q True False False True Taxonomy A characterization of 10 Hidden Surface Algorithm: Spatial Subdivision Sutherland, Sproull, Schumaker (1974) • Uniform grid Image Space • Octrees Object space List priority • K-d Trees • BSP-trees edge volume Area Point • Non-overlapping polyhedra – Axis-Aligned Bounding Boxes (AABB’s) A’priori Dynamic – Oriented Bounding Boxes (OBB’s) – Useful for non-static scenes Roberts Newell Warnock Apel, Weiler-Atherton Span-line Algorithms Back-to-front Traversals Sorting for Uniform Grid • For the first four, you can develop either a • Parallel Projection front-to-back or back-to-front traversal – Can always proceed along the x-axis, then y- order explicitly. axis then z-axis or any combination. – Simply need to decide whether to go forward or • Thereby, solving the visibility sort backward on each axis. efficiently. • Look at the z-value of the transformed x-axis, … • For the polyhedra, use a Newell-Newell- • Positive, go forward for back-to-front sort. Sancha sort. – Better ordering would choose the axis most parallel to the viewing direction to traverse last. Sorting for Uniform Grid K-d Trees • Alternate splits in each direction • Perspective projection – May need to proceed forward for part of the grid and backwards for the other. Split X axis Split Y axis X K-d Trees K-d Trees • Extend to any dimension d • A subset of BSP-trees. • In 3D, the splits are done with axis-aligned • Sorting is the same. planes. • More efficient storage representation. – Test is simple, is x-value (for nodes splitting the x-axis) greater than the node value? p Binary Space-Partitioning Tree back front B p F Given a polygon p B F Two lists of polygons: those that are behind(p) :B p those that are in-front(p) :F Bf Bb B F If eye is in-front(p), right display order is B, p, F Otherwise it is F, p, B Bb Bf Display a BSP Tree Generating a BSP Tree struct bspnode { if (polys is empty ) then return NULL; p: Polygon; back, front : *bspnode; rootp := first polygon in polys; } BSPTree; for each polygon p in the rest of polys do if p is infront of rootp then BSP_display ( bspt ) add p to the front list BSPTree *bspt; else if p is in the back of rootp then { if (!bspt) return; add p to the back list if (EyeInfrontPoly( bspt->p )) { else split p into a back poly pb and front poly pf BSP_display(bspt->back);Poly_display(bspt->p); add pf to the front list BSP_display(bspt->front); add pb to the back list } else { end_for; BSP_display(bspt->front); Poly_display(bspt->p); bspt->back := BSP_gentree(back list); BSP_display(bspt->back); bspt->front := BSP_gentree(front list); } bspt->p = rootp;return bspt; } 5 3 2 a b 3 1 1, 2, 5a 4, 5b 4 5 3 2 a b 3 2 1 4, 5b 4 1 5a 5 3 2 a b 3 2 4 1 4 1 5a 5b