Visibility Joshua Barczak CMSC 435 UMBC Some material
Visibility Joshua Barczak* CMSC 435 UMBC *Some material “appropriated” from Drs Olano, Rheingans
“Visibility” is about two things: Correctness Efficiency Primitives can occlude one another. How do I figure out what’s in front? How can I tell what I can’t see, so I can skip it?
Visibility Zoo • Distinctions: – Object/Image order – When the depth comparison happens • At the pixel level (last) or earlier Object-Order Painter’s Raycast Sort last BSP Scanline Sort first Sort last Image-Order ZBuffer
Painter’s Algorithm • Draw in back to front order – Foreground paints over background • Microsoft Outlook is doing this RIGHT NOW…
Painter’s Algorithm • Given List of polygons {P 1, P 2, …. Pn) An array of Intensity [x, y] • Begin Sort polygon list on minimum Z (largest z-value comes first in sorted list) For each polygon P in selected list do For each pixel (x, y) that intersects P do Intensity[x, y] = intensity of P at (x, y) Display Intensity array Fast and easy. If only it worked…
Painter’s Algorithm • Problem #1: Visibility Cycles
Painter’s Algorithm • Solution #1 – Split geometry
Worse yet… • Interpenetrating primitives – Must clip one polygon plane against the other • Possibly many times… • Frought with precision peril…
Painter’s Algorithm • Problem #2: Sorting isn’t as easy as it sounds…. Minimum Z won’t work… Maximum Z won’t work… Average Z won’t work…
Painter’s Algorithm • Solution #2: Exact testing – If bounding boxes overlap, then… – S’ is “in front” S if: • All vertices of S are “outside” S’ – OR • All vertices of S’ are “inside” S
Painter’s Algorithm • Problem #3: You can’t just use a comparison sort – “In. Front” is nontransitive… • In. Front(a, b) && In. Front(b, c) – BUT !In. Front(a, c) • QSort will break… c a b Solution #3: Don’t use the painter’s algorithm…
BSP Trees • Binary Space Partitioning Trees: – Each node stores a plane, and polygons in that plane – Left and right subtrees are opposite sides of the plane – Can traverse in back to front order for a given view position
Binary Space Partitioning
Building a BSP Tree • Use pgon 3 as root, split on its plane • Pgon 5 split into 5 a and 5 b
Building a BSP Tree • Split left subtree at pgon 2
Building a BSP Tree • Split right subtree at pgon 4
Building a BSP Tree • Alternate tree if splits are made at 5, 4, 3, 1
BSP Tree: Building the Tree BSPTree Make. BSP ( Polygon list ) { if ( list is empty ) return null else { root = some polygon ; remove it from the list backlist = frontlist = null for ( each remaining polygon in the list ) { if ( p in front of root ) add. To. List ( p, frontlist ) else if ( p in back of root ) add. To. List ( p, backlist ) else { split. Polygon (p, root, frontpart, backpart) add. To. List ( frontpart, frontlist ) add. To. List ( backpart, backlist ) } } return (combine. Tree(Make. BSP(frontlist), root, Make. BSP(backlist))) } }
BSP Tree: Displaying the Tree Display. BSP ( tree ) { if ( tree not empty ) { if ( viewer in front of root ) { Display. BSP ( tree -> back ) Display. Polygon ( tree -> root ) Display. BSP ( tree -> front ) } else { Display. BSP ( tree -> front ) Display. Polygon ( tree -> root ) Display. BSP ( tree -> back ) } } }
BSP Tree Display • Built BSP tree structure
BSP Tree Display C in front of 3
BSP Tree Display C in front of 3 (<3) C behind 4 (>4) none
BSP Tree Display C in front of 3 (<3) C behind 4 (>4) none (=4) display 4
BSP Tree Display C in front of 3 (<3) C behind 4 (>4) none (=4) display 4 (<4) display 5 b
BSP Tree Display C in front of 3 (<3) C behind 4 (>4) none (=4) display 4 (<4) display 5 b (=3) display 3
BSP Tree Display C in front of 3 (<3) C behind 4 (>4) none (=4) display 4 (<4) display 5 b (=3) display 3 (>3) C behind 2
BSP Tree Display C in front of 3 (<3) C behind 4 (>4) none (=4) display 4 (<4) display 5 b (=3) display 3 (>3) C behind 2 (>2) display 5 a
BSP Tree Display C in front of 3 (<3) C behind 4 (>4) none (=4) display 4 (<4) display 5 b (=3) display 3 (>3) C behind 2 (>2) display 5 a (=2) display 2
BSP Tree Display C in front of 3 (<3) C behind 4 (>4) none (=4) display 4 (<4) display 5 b (=3) display 3 (>3) C behind 2 (>2) display 5 a (=2) display 2 (<2) display 1
BSP Tree Considerations • Splitting bloats scene size – Good construction algorithms try to minimize splits • Doesn’t necessarily need to be balanced • Lots of other applications: – Point location – Ray tracing – Collision detection
Scanline Algorithm • Simply problem by considering only one scanline at a time • intersection of 3 D scene with plane through scanline
Scanline Algorithm Image z Top-down view in XZ plane x
Scanline Algorithm • Identify points where visibility may change – “Events” – At edges – Intersection points • if interpenetrating z x
Scanline Algorithm • Split scanline into ‘spans’ – Sort visibility events on x axis – Constant visibility in each span z x
Scanline Algorithm • Data structures: – Sorted surface table • SST[y] Polygons that start on scanline Y – Active surface table • Polygons being scanned z x
Scanline Algorithm 1. Sort polygons into sorted surface table (SST) based on first Y 2. Initialize y and active surface table (AST) Y = first nonempty scanline AST = SST[y] 3. Repeat until AST and SST are empty x) Identify spans for this scanline (sorted on For each span determine visible element (based on z) fill pixel intensities with values from element Update AST remove exhausted polygons y++ update x intercepts (DDA) add entering polygons from SST[y]
Scanline Algorithm • Pro: – Little memory required – Progressive • Can display each scanline when its ready – Can antialias within scanline – Fast and dynamic
Scanline Algorithm • Con: – Hard to antialias across scanlines – Complicated – Awkward to implement
Z Buffer For each polygon P do For each pixel (x, y) that intersects P do Calculate z-depth of P at (x, y) If z-depth < z-buffer[x, y] then Intensity[x, y] = intensity of P at (x, y) Z-buffer[x, y] = z-depth
Z Buffer 4 3 1 2
Z Buffer 4 3 1 2
Z Buffer 4 3 1 2
Z Buffer 4 3 1 2
Z Buffer 4 3 1 2
Z Buffer 4 3 1 2
Z Buffer 4 3 1 2
Hierarchical Z buffering • Coarser levels store max(z) over Nx. N tiles – Test covered cells coarse to fine 0 1 1 0 2 4 4 1 1 2 4 4 2 4 0 1 1 2 2 4 4 4 1 2 2 4 0 1 2 2 2 1 4 4 2 2 1 4 0 0 0 2 1 1 1 4 2 0 3 3 0 0 0 1 1 4 2 2 2 0 0 0 1 3 2 2 0 0 0 3 3 3
Hierarchical Z buffering • Example: – Cull entire quad with 1 depth lookup 0 1 1 0 2 4 4 1 1 2 4 4 2 4 0 Depth 1 1 2 0 Range: 1 2 >22 2 4 4 4 1 2 2 4 2 1 4 4 2 2 1 4 0 0 0 2 1 1 1 4 2 0 3 3 0 0 0 1 1 4 2 2 2 0 0 0 1 3 2 2 0 0 0 3 3 3
Hierarchical Z Buffering • Cost/Benefit – More memory/bookeeping – Can reject whole primitives prior to rasterization • Based on bounding rect/Z range – Can reject whole Nx. N stamps during rasterization • Incremental update of Z range
Z Fighting • Coplanar polygons will “fight” due to interpolation error • Polygons that differ by less than Z precision will fight due to quantization Wikipedia
Perspective Projection • Our desired transform… • Q: How do we trick a matrix into dividing? – Matrices don’t work this way…
Perspective Projection • A: Use a projective transform – Homogeneous coordinates again…
Perspective Projection • Each homogeneous point projects to a w=1 point “Equivalent” points, different coordinates -w 1 w
Perspective Projection • Perspective Transform After homogeneous divide… Z isn’t quite right…
Z Fighting and Perspective • At near plane, z=n • At far plane, z=f • In between, z is nonlinear…
Z Fighting • Corollaries: – Z fighting gets worse with distance – Moving nearplane out has much more impact than moving farplane in
Z Buffer • Pros: – Easy to implement – Order-independent • Just throw triangles at it – Intersecting triangles “just work” • No nasty splitting – O(1) memory in prim count • Can stream/tessellate on the fly – Easy to bake into hardware
Z Buffer • Cons – Extra memory per-pixel • No big deal nowadays – Extra lerp/comparison per pixel • No big deal – Memory read/write per pixel • Much bigger deal – Transparency is hard • More on this later
And the winner is… Z-Buffered Rasterization Dominant visibility algorithm for production 3 D: - Robust - Simple - So much so that we’ve built ASICs for it - No preprocessing - Fully dynamic scenes - On the fly streaming/generation of geometry - Scales well with scene size - O(N) time, O(1) space* - ASIC Absurdly Small Implied Constant * No extra per-triangle storage for rendering. You may still need to store the geometry
Runners Up… • Raytracing – Useful for reflection/shadows/etc – Rasterizer often used for eye rays • Sorted Spans – Common in software rasterizers – Sorted. Span + BSP used in original Quake • ZBuffer too
- Slides: 60