Document 7678563
Download
Report
Transcript Document 7678563
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
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 …
CS248 Lecture 13
Kurt Akeley, Fall 2007
Sorting difficulties
Topological
CS248 Lecture 13
Interpenetrating
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
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)
CS248 Lecture 13
Kurt Akeley, Fall 2007
Outline
Z-buffering example
Culling
Other approaches to the hidden surface problem
Numerical issues
Selected topics
CS248 Lecture 13
Kurt Akeley, Fall 2007
Pipeline Example
CS248 Lecture 13
Kurt Akeley, Fall 2007
Walk through the vertex pipeline
Z-buffering enabled
Multi-sample antialiasing enabled
This is simple to setup:
glutInitDisplayMode(GLUT_DOUBLE |
GLUT_RGBA |
GLUT_DEPTH |
GLUT_MULTISAMPLE);
…
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
Application
Vertex assembly
Vertex operations
Primitive assembly
Primitive operations
Rasterization
Fragment operations
Framebuffer
Display
CS248 Lecture 13
Kurt Akeley, Fall 2007
Vertex operations
Application
Vertex assembly
Vertex operations
Primitive assembly
Primitive operations
Rasterization
Fragment operations
Framebuffer
Display
CS248 Lecture 13
Kurt Akeley, Fall 2007
Perspective projection
Specify a frustum:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
n and f are distances,
not coordinates. Both
must be positive.
glFrustum(l,r,b,t,n,f);
æxc ö÷
æxe ö÷
çç ÷
çç ÷
çç yc ÷
çç ye ÷
÷
÷
÷
÷
çç ÷
ç
÷
=
P
×
ç
÷
÷
çç zc ÷
ç
÷
z
e÷
÷
ç
çç ÷
çç ÷
÷
÷
çèwc ø÷
çèwe ø÷
CS248 Lecture 13
æ 2n
çç
çç r - l
çç
çç 0
P ¢= P ×ççç
çç
çç 0
çç
çç
çè 0
ö
r+ l
÷
0
0 ÷
÷
r- l
÷
÷
÷
÷
2n
t+ b
÷
0 ÷
÷
÷
t- b
t- b
÷
÷
f+n
2 fn ÷
÷
÷
0
÷
f- n
f - n÷
÷
÷
÷
0
- 1
0 ÷
ø
Kurt Akeley, Fall 2007
The frustum
æ f
ççl ×
çè n
wc = - ze
f
t×
n
ö
- f÷
÷
÷
ø
ye
zc is projected
f+n
2 fn
- we ×
f- n
f- n
= C ×ze + D
zc = - ze ×
(l b - n)
xe
(r t - n)
Assuming we is 1.0
CS248 Lecture 13
ze
Kurt Akeley, Fall 2007
Primitive operations
Application
Vertex assembly
Vertex operations
Primitive assembly
Primitive operations
Rasterization
Fragment operations
Framebuffer
Display
CS248 Lecture 13
Kurt Akeley, Fall 2007
Homogenization of Z
æ f
ççl ×
çè n
wc = - ze
f
t×
n
ö
- f÷
÷
÷
ø
f+n
2 fn
- we ×
f- n
f- n
= C ×ze + D
ye
zc = - ze ×
(l b - n)
zc
zd =
wc
=
xe
C ×ze + D
- ze
= - C - D ×ze
CS248 Lecture 13
(r t - n)
- 1
ze
Kurt Akeley, Fall 2007
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);
æxw ö
çç ÷
÷
çç yw ÷
÷=
çç ÷
÷
÷
÷
çè zw ø
æw
çç
çç 2
çç
çç 0
çç
çç
çç
çç 0
è
0
0
h
2
0
0
f2
(10 6 1)
ö
æ w ö÷
÷
çç l + ÷
÷
÷
çç
2÷
÷
÷
æ
ö
x
÷
÷
d
ç
÷
÷
çç ÷
ç
÷
÷
÷
h
÷
ç
÷
ç
÷
÷
+ çç b + ÷
çç yd ÷
÷
÷
÷
÷
÷
÷
2
ç
ç
÷
÷
÷
ç
÷
ç
÷
÷
zd ø ç
è
÷
÷
n÷
f
+
n
ç
÷
ç
÷
÷
÷
÷
ç
÷
ç
ø
è 2 ø÷
glViewport(0, 0, 10, 6);
glDepthRange(0.0, 1.0);
(0 0 0)
CS248 Lecture 13
One pixel
Kurt Akeley, Fall 2007
Z arithmetic
zd =
zc
wc
= - C - D ×ze- 1
æf vp - nvp ö÷
æf vp + nvp ö÷
ç
÷
÷
zw = ç
×zd + çç
÷
÷
çè 2 ø÷
çè 2
ø÷
æf vp - nvp ö÷
æf vp + nvp ö÷
- 1
ç
÷
÷
=ç
×C - D ×ze )+ çç
(
÷
÷
çè 2 ø÷
çè 2
ø÷
= Cˆ + Dˆ ×ze- 1
CS248 Lecture 13
dzw
ˆ -2
= - Dz
e
dze
This will be a
problem!
Kurt Akeley, Fall 2007
Rasterization
Application
Vertex assembly
Vertex operations
Primitive assembly
Primitive operations
Rasterization
Fragment operations
Framebuffer
Display
CS248 Lecture 13
Kurt Akeley, Fall 2007
Perspective-correct attribute evaluation
f0
f1
f2
b0
+ b1 + b2
w0
w1
w2
f =
1
1
1
b0
+ b1 + b2
w0
w1
w2
All w’s are wc’s
(x0 y0 w0 f0)
(x1 y1 w1 f1)
(x y f )
a2
a0
a1
(x2 y2 w2 f2)
a = (y0 x1 - x0 y1 )+ (y1 x2 - x1 y2 )+ (y2 x0 - x2 y0 )
a0 = ( yx1 - xy1 )+ ( y1 x2 - x1 y2 )+ ( y2 x - x2 y ), b0 = a0 a
a1 = ( yx2 - xy2 )+ ( y2 x0 - x2 y0 )+ ( y0 x - x0 y ), b1 = a1 a
a2 = ( yx0 - xy0 )+ ( y0 x1 - x0 y1 )+ ( y1 x - x1 y ), b2 = a2 a
CS248 Lecture 13
Kurt Akeley, Fall 2007
Perspective-correct zw evaluation
(x1 y1 zw1)
zw was projected during
homogenization
zw = b0 zw0 + b1 zw1 + b2 zw2
(x0 y0 zw0)
(x y zw)
a2
a0
a1
(x2 y2 zw2)
a = (y0 x1 - x0 y1 )+ (y1 x2 - x1 y2 )+ (y2 x0 - x2 y0 )
a0 = ( yx1 - xy1 )+ ( y1 x2 - x1 y2 )+ ( y2 x - x2 y ), b0 = a0 a
a1 = ( yx2 - xy2 )+ ( y2 x0 - x2 y0 )+ ( y0 x - x0 y ), b1 = a1 a
a2 = ( yx0 - xy0 )+ ( y0 x1 - x0 y1 )+ ( y1 x - x1 y ), b2 = a2 a
CS248 Lecture 13
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
Fragment / pixel operations
Application
Vertex assembly
Vertex operations
Primitive assembly
Primitive operations
Rasterization
Fragment operations
Framebuffer
Display
CS248 Lecture 13
Kurt Akeley, Fall 2007
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 color
5/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;
CS248 Lecture 13
Resolved color
3/8, 1/4, 0, 1
Kurt Akeley, Fall 2007
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 …
CS248 Lecture 13
Kurt Akeley, Fall 2007
Culling
CS248 Lecture 13
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
Culling
Application
Frustum culling
Occlusion culling
Portal culling
Vertex assembly
Vertex operations
Primitive assembly
Back-face culling
Primitive operations
Hierarchical
Z culling
Rasterization
Fragment operations
Framebuffer
Display
CS248 Lecture 13
Kurt Akeley, Fall 2007
Frustum culling
CS248 Lecture 13
Kurt Akeley, Fall 2007
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);
CS248 Lecture 13
Kurt Akeley, Fall 2007
Back-face culling
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
Could compute plane equation in eye
coordinates and substitute (0, 0, 0, 1)
So cannot compute dot product with eyeto-vertex vector
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
CS248 Lecture 13
Application
Vertex assembly
Vertex operations
Primitive assembly
Primitive operations
Rasterization
Fragment operations
Framebuffer
Display
Kurt Akeley, Fall 2007
Signed area calculation
(x1 y1)
(x0 y0)
(x2 y2)
a = (y0 x1 - x0 y1 )+ (y1 x2 - x1 y2 )+ (y2 x0 - x2 y0 )
Usual rule: CCW vertex rotation on outside of solid volume
CS248 Lecture 13
Kurt Akeley, Fall 2007
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);
CS248 Lecture 13
Kurt Akeley, Fall 2007
Hierarchical Z culling
Application
Fragment ops build a multi-resolution,
conservative z-buffer
Vertex assembly
Much like a MIPmap
But max value rather than
filtered value
Vertex operations
Entire primitives are culled against
this multi-resolution z-buffer
Primitive assembly
Optimal use requires front-to-back
rendering order
Primitive operations
Opposite of painter’s
algorithm
Will be covered again in Dave
Oldcorn’s Tuning and Debugging
lecture
Hierarchical
Z culling
Rasterization
Fragment operations
Framebuffer
Display
CS248 Lecture 13
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
Numerical Issues
CS248 Lecture 13
Kurt Akeley, Fall 2007
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 nearparallel red and green surfaces:
CS248 Lecture 13
Kurt Akeley, Fall 2007
Z arithmetic
zd =
zc
wc
= - C - D ×ze- 1
æf vp - nvp ö÷
æf vp + nvp ö÷
ç
÷
÷
zw = ç
×zd + çç
÷
÷
çè 2 ø÷
çè 2
ø÷
æf vp - nvp ö÷
æf vp + nvp ö÷
- 1
ç
÷
÷
=ç
×C - D ×ze )+ çç
(
÷
÷
çè 2 ø÷
çè 2
ø÷
= Cˆ + Dˆ ×ze- 1
CS248 Lecture 13
dzw
ˆ -2
= - Dz
e
dze
Kurt Akeley, Fall 2007
Z-buffer mapping (eye-to-window coords)
zw
CS248 Lecture 13
Normalized to
Zfar = 1
ze
Kurt Akeley, Fall 2007
Z-buffer mapping (log10 ze)
zw
CS248 Lecture 13
ze
Kurt Akeley, Fall 2007
Difference between adjacent
zw representations near the
specified ze, mapped back to
eye coordinates
Bad
Normalized to
Zfar = 1
Good
Zfar = 50 miles
Znear = 26 feet
CS248 Lecture 13
ze
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
CS248 Lecture 13
Kurt Akeley, Fall 2007
16-bit integer
z-buffer
Bad
16-bit reverse mapped,
floating-point z-buffer
24-bit integer
z-buffer
Good
Zfar = 50 miles
Znear = 26 feet
CS248 Lecture 13
ze
Kurt Akeley, Fall 2007
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-totriangle separations
If possible use reversed-mapped (complementary) floatingpoint 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
CS248 Lecture 13
Kurt Akeley, Fall 2007
Selected Topics
CS248 Lecture 13
Kurt Akeley, Fall 2007
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
–
CS248 Lecture 13
Disable z-buffer write so all tests are of the opaque z-buffer
Kurt Akeley, Fall 2007
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 …
CS248 Lecture 13
Kurt Akeley, Fall 2007
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);
CS248 Lecture 13
Kurt Akeley, Fall 2007
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
CS248 Lecture 13
Kurt Akeley, Fall 2007
Outlined polygons
Why is this a problem?
What are possible solutions?
CS248 Lecture 13
Kurt Akeley, Fall 2007
Summary
Use Z-buffer as a backstop, cull earlier if at all possible
Visibility cull (frustum, occlusion)
Back-face cull
Z-cull (optimize by rendering front-to-back, prepass)
Arithmetic precision is a critical Z-buffer issue
Minimize far/near ratio
Prefer floating-point Z-buffer with reverse mapping
Use back-face cull and model LOD to avoid punch through
Z-buffer mechanism is an imperative “tool”
Render transparent tris last: Z compare, blend, no Z write
Blend model LODs with SAMPLE_COVERAGE
CS248 Lecture 13
Kurt Akeley, Fall 2007
Assignments
Next lecture: Graphics Hardware
Reading assignment for Thursday’s class
David Blythe, Rise of the Graphics Processor, to be
published.
CS248 Lecture 13
Kurt Akeley, Fall 2007
End
CS248 Lecture 13
Kurt Akeley, Fall 2007