1 / 54

Z-buffer

Z-buffer. Kurt Akeley CS248 Lecture 13 6 November 2007 http://graphics.stanford.edu/courses/cs248-07/. Painter’s algorithm. Initial OpenGL behavior is “painter’s algorithm” Fragment color values overwrite sample color values Sequence is guaranteed

Télécharger la présentation

Z-buffer

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Z-buffer Kurt Akeley CS248 Lecture 13 6 November 2007 http://graphics.stanford.edu/courses/cs248-07/

  2. Painter’s algorithm Initial OpenGL behavior is “painter’s algorithm” • Fragment color values overwrite sample color values • Sequence is guaranteed • Result at each sample is the color of the last fragment Painter’s algorithm (ordered rendering) is useful: • 2-D rendering (especially pre-filter triangle antialiasing) • Volumetric rendering (future lecture) But painter’s algorithm puts a huge burden on the application for general 3-D rendering • Want “nearest” geometry to be visible • But sorting in the application is difficult, sometimes very difficult …

  3. Sorting difficulties Topological Interpenetrating

  4. Z-buffer Vertex operations • Project ze to zc Primitive operations • Homogenize • Z viewport (glDepthRange) generates zw Rasterization • Assign a zw value to each fragment sample Fragment / framebuffer operations • Conditionally replace pixel sample values (color and depth) with fragment sample values • Depth comparison specified by glDepthFunc • Typically replace if fragment is nearer to viewer than pixel

  5. Naming conventions Depth buffer and Z-buffer have the same meaning OpenGL uses “depth” rather than “z” • Emphasized notion of depth attribute rather than 3-D window coordinates • Resulted in nice name syntax I’ve reverted to “z” • I prefer to think of window coordinates as a 3-D system • Z-buffer is in more common usage (maybe)

  6. Outline Z-buffering example Culling Other approaches to the hidden surface problem Numerical issues Selected topics

  7. Pipeline Example

  8. Walk through the vertex pipeline Application Z-buffering enabled Multi-sample antialiasing enabled This is simple to setup: Vertex assembly Vertex operations Primitive assembly glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE); … glEnable(GL_DEPTH_TEST);glEnable(GL_MULTISAMPLE); Primitive operations Rasterization Fragment operations Framebuffer Display

  9. Vertex operations Application Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display

  10. Perspective projection Specify a frustum: n and f are distances, not coordinates. Both must be positive. glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(l,r,b,t,n,f);

  11. The frustum ye zc is projected xe Assuming we is 1.0 ze

  12. Primitive operations Application Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display

  13. Homogenization of Z ye xe ze

  14. Viewport transformation Transform the [-1,1] range device coordinates to window coordinates: glViewport(int l, int b, int w, int h); glDepthRange(double n, double f); glViewport(0, 0, 10, 6); glDepthRange(0.0, 1.0); One pixel

  15. Z arithmetic This will be a problem!

  16. Rasterization Application Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display

  17. a2 a0 a1 Perspective-correct attribute evaluation (x1 y1 w1 f1) (x y f ) All w’s are wc’s (x0 y0 w0 f0) (x2 y2 w2 f2)

  18. a2 a0 a1 Perspective-correct zw evaluation (x1 y1 zw1) zw was projected during homogenization (x y zw) (x0 y0 zw0) (x2 y2 zw2)

  19. Perspective-correct zw evaluation zw is not linearly related to ze • We’ll plot the relationship later when considering precision But this doesn’t matter for hidden-surface calculations • zw has been projected • So it interpolates linearly • So comparison yields the nearest fragment sample • We don’t care about the actual distances

  20. Mask generation Mask bits Two triangles, first red, second green: 7 6 5 4 3 2 1 0 struct { short x,y; bool mask[n]; // 01110110 float depth[n]; // as required float r,g,b,a; // 1,0,0,1} fragment; struct { short x,y; bool mask[n]; // 00110110 float depth[n]; // as required float r,g,b,a; // 0,1,0,1} fragment; Single Pixel

  21. Fragment / pixel operations Application Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display

  22. Fragment / pixel operations All samples initially black, farthest: 7 6 5 4 3 2 1 0 struct { short x,y; bool mask[n]; // 01110110 float depth[n]; // as required float r,g,b,a; // 1,0,0,1} fragment; Resolved color5/8, 0, 0, 1 struct { short x,y; bool mask[n]; // 00110110 float depth[n]; // as required float r,g,b,a; // 0,1,0,1} fragment; Resolved color3/8, 1/4, 0, 1

  23. Multi-sample antialiasing Requires a lot of state: • Fragment • Mask • Full depth value for each sample (but this can be optimized) • Pixel • Full color and depth values for each sample • Additional front and back resolved color values But it works really well: • Handles arbitrary fragment sequences • Handles interpenetrating triangles • Satisfies rule 1 (no frame-to-frame discontinuities) • Has no unpredictable or ill-mannered behaviors Other less expensive (and more clever) antialiasing approaches are not so well behaved …

  24. Culling

  25. Culling Culling: elimination of primitives or fragments that will not affect the final image Andrew discussed culling last week • Frustum culling • Portal culling (a special case of occlusion culling) Basic idea: eliminate work as early in the sequence as possible • But with a reasonable pay-off for the effort

  26. Culling Application Frustum culling Occlusion culling Portal culling Vertex assembly Vertex operations Primitive assembly Back-face culling Primitive operations HierarchicalZ culling Rasterization Fragment operations Framebuffer Display

  27. Frustum culling

  28. Occlusion culling Active research topic • Difficult for sparse scenes (e.g., oil refinery) Introduces notion of “depth complexity” • Average number of fragments generated per pixel Portal culling is a special case of occlusion culling OpenGL includes acceleration support • “reduction” query (any pixel samples modified?) glBeginQuery(GL_SAMPLES_PASSED, id); // render proxy object (e.g., a bounding cuboid) glEndQuery(GL_SAMPLES_PASSED, id); glGetQueryObjectiv(id, GL_QUERY_RESULT, *params);

  29. Back-face culling Application Eliminate triangles that face away from the point of projection • Such triangles are never visible if they compose proper solids How to identify? • OpenGL has no facet normals • So cannot compute dot product with eye-to-vertex vector • Could compute plane equation in eye coordinates and substitute (0, 0, 0, 1) • But no other area computations are done in eye coordinates • Compute signed area in window coordinates • Shares math with rasterization setup • Compute in order of vertex specification Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display

  30. Signed area calculation (x1 y1) (x0 y0) (x2 y2) Usual rule: CCW vertex rotation on outside of solid volume

  31. OpenGL triangle facing commands glFrontFace(GL_CW | GL_CCW); glEnable(GL_CULL_FACE);glDisable(GL_CULL_FACE);glCullFace(GL_FRONT | GL_BACK | GL_FRONT_AND_BACK); glMaterialfv(GL_FRONT | GL_BACK | GL_FRONT_AND_BACK, …);glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE | GL_FALSE);

  32. Hierarchical Z culling Application Fragment ops build a multi-resolution, conservative z-buffer • Much like a MIPmap • But max value rather than filtered value Entire primitives are culled against this multi-resolution z-buffer Optimal use requires front-to-back rendering order • Opposite of painter’s algorithm Will be covered again in Dave Oldcorn’s Tuning and Debugging lecture Vertex assembly Vertex operations Primitive assembly Primitive operations HierarchicalZ culling Rasterization Fragment operations Framebuffer Display

  33. Z-buffer as a back stop Ideal goal: • z-buffer rejects no samples Practical goal: • z-buffer sees a minimal depth complexity • e.g., 2-3 Z-buffer back stop allows efficient, conservative culling

  34. Other hidden-surface algorithms Application level • Binary space partition (BSP) tree • Various analytical approaches Application/OpenGL • Convex solids • Sort at application level using plane equations • Render each solid with back-facing triangles culled • Hidden-line rendering • Future lecture

  35. Z-buffering is a brute-force technique And this is good! Never solves the “hidden-surface” problem Instead resolves visibility one sample (ray) at a time

  36. Numerical Issues

  37. Z-buffer punch through When surfaces are too close, the z-buffer may not sort them accurately Here’s an example of the resulting “punch through” for near-parallel red and green surfaces:

  38. Z arithmetic

  39. Z-buffer mapping (eye-to-window coords) zw Normalized to Zfar = 1 ze

  40. Z-buffer mapping (log10ze) zw ze

  41. Bad Normalized to Zfar = 1 Good Zfar = 50 milesZnear = 26 feet Difference between adjacent zw representations near the specified ze, mapped back to eye coordinates ze

  42. Resolution loss Rules of thumb: • log2(f/n) bits are lost in the far field • There are roughly 216 inches in a mile Solutions: • Minimize f/n ! • Push n as far away as possible (draw vehicle separately) • Pull f in (e.g., fog) • Adjust n and f dynamically • Use a different • ze to zw mapping and/or • zw representation

  43. Bad 16-bit integerz-buffer Good Zfar = 50 milesZnear = 26 feet 16-bit reverse mapped, floating-point z-buffer 24-bit integerz-buffer ze

  44. Z-buffer resolution summary This is a rich topic • We’ve just scratched the surface  • May return to this topic in one of the last lectures Good practice: • Minimize f/n ! • Use back-face cull and model LOD to avoid tiny triangle-to-triangle separations • If possible use reversed-mapped (complementary) floating-point z-buffer • There are problems with this in OpenGL • zc is clipped to +/- wc, rather than 0 <= zc <= wc • I believe it works well in Direct3D 10

  45. Selected Topics

  46. Transparent surfaces and the z-buffer Z-buffer finds the nearest surface • It cannot sort front-to-back or back-to-front for blending • A-buffer can do this, but is expensive to implement • I know of no hardware that does so Two good solutions: • Depth peeling • Multi-pass sort, renders one transparent surface per pass • Can use occlusion reduction to terminate the loop • Or just render a fixed number of passes • Pre-filtered point and line antialiasing algorithm • Render all opaque triangles first • Builds opaque z-buffer • Then render all transparent triangles in arbitrary order • Disable z-buffer write so all tests are of the opaque z-buffer

  47. Fade model LOD Switching suddenly from one model LOD to another violates rule 1 • Viewers will see a jarring transition Need to fade between model LODs over several frames But blending and z-buffering don’t cooperate in this case • Cannot render in-place in the scene • Need to resolve visibility within each LOD model • But blend between the resulting “images” Solutions: • Render separate off-screen images, then composite to scene • Morph geometrically between two models • Fade “spatially” rather than blending …

  48. OpenGL sample-coverage fade Use standard z-buffer semantics for each sample Allocate a fraction of the samples to one model, and the remaining fraction to the other Fade by transitioning the allocation frame-to-frame Works best with multi-sample antialiasing: glSampleCoverage(value, invert); glEnable(GL_SAMPLE_COVERAGE);

  49. Sample coverage example Mask bits 7 6 5 4 3 2 1 0 glSampleCoverage(0.25, GL_FALSE); // possible mask is 00100100 glSampleCoverage(0.25, GL_TRUE); // corresponding mask is 11011011 Single Pixel

More Related