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