GDC2K ShadowsTransparencyFog
GDC2K ShadowsTransparencyFog
Reflections, Shadows,
Transparency, and Fog
March 8, 2000
Mark J. Kilgard
Graphics Software Engineer
NVIDIA Corporation
Quick Tutorial on
Stencil Testing
An extra test for fine -grain pixel control
fine-grain
•• Standard
Standard OpenGL
OpenGL and
and DirectX
DirectX 66 feature
feature
•• Per-pixel test
Per-pixel test similar
similar to
to depth
depth buffering
buffering
–– Tests
Tests fragment
fragment against
against pixel’s
pixel’s stencil
stencil value,
value, rejects
rejects
fragments
fragments that
that fail
fail
–– Also,
Also, can
can modify
modify pixel’s
pixel’s stencil
stencil buffer
buffer value
value based
based on
on
stencil/depth
stencil/depth test
test results
results
•• Hardware
Hardware accelerates
accelerates stencil
stencil testing
testing
–– Typically
Typically free
free when
when depth
depth testing
testing too
too
Stencil Testing in the
Fragment Pipeline
Fragment Pixel
+ Scissor Alpha
Ownership
Test Test
Associated Test
Data
Depth Stencil
Test Test
•• Stencil
Stencil compare
compare & & write
write masks
masks allow
allow stencil
stencil values
values to
to be
be
treated
treated as
as sub -fields
sub-fields
OpenGL Stencil API
Stencil -related Routines
Stencil-related Routines
•• glEnable/glDisable(GL_STENCIL_TEST);
glEnable/glDisable(GL_STENCIL_TEST);
•• glStencilFunc(function,
glStencilFunc(function, reference,
reference, mask);
mask);
•• glStencilOp(stencil_fail,
glStencilOp(stencil_fail,
depth_fail,
depth_fail, depth_pass);
depth_pass);
•• glStencilMask(mask);
glStencilMask(mask);
•• glClear(…
glClear(… || GL_STENCIL_BUFFER_BIT);
GL_STENCIL_BUFFER_BIT);
Requesting a
Stencil Buffer
Have to request one to use one!
•• IfIf using
using stencil,
stencil, request
request sufficient
sufficient bits
bits of
of stencil
stencil
•• Implementations
Implementations may
may support
support from
from zero
zero to
to 32
32 bits
bits of
of stencil
stencil
•• 8,
8, 4,
4, or
or 11 bit
bit are
are common
common possibilities
possibilities
•• Easy
Easy for
for GLUT
GLUT programs:
programs:
glutInitDisplayMode(GLUT_DOUBLE
glutInitDisplayMode(GLUT_DOUBLE || GLUT_RGB
GLUT_RGB ||
GLUT_DEPTH || GLUT_STENCIL
GLUT_DEPTH );
GLUT_STENCIL);
glutCreateWindow(“stencil
glutCreateWindow(“stencil example”);
example”);
Stencil Performance
Cheaper than you think
•• With
With today’s
today’s 32 -bit graphics
32-bit graphics accelerator
accelerator modes,
modes, 24 -bit depth
24-bit depth
and
and 88-bit
-bit stencil
stencil packed
packed in
in same
same memory
memory word
word
•• TNT2
TNT2 and
and GeForce
GeForce are
are examples
examples
•• Performance
Performance implication:
implication:
ifif using
using depth
depth testing,
testing, stenciling
stenciling is
is at
at
NO
NO PENALTY
PENALTY
Planar Reflections
Dinosaur reflected in the floor
Easy hack.
Draw dino twice,
second time has
glScalef(1, -1, 1)
to reflect through
the floor.
Confining the Reflection
Reflection should be limited to reflective surface
where P = Lx A + Ly B + Lz C + Lw D
Projected Planar
Shadow Issues
•• Shadow
Shadow must
must be
be cast
cast on
on infinite
infinite planes
planes
–– Stencil
Stencil can
can limit
limit shadow
shadow to
to finite
finite planar
planar region
region
•• “Pile
“Pile of
of polygons”
polygons” creates
creates ZZ-fighting
-fighting artifacts
artifacts
–– Polygon
Polygon offset
offset fixes
fixes this,
this, but
but disturbs
disturbs ZZ values
values
–– Stencil
Stencil testing
testing is
is better
better solution
solution
•• Difficult
Difficult to
to blend
blend shadow
shadow with
with ground
ground texture
texture
–– Just
Just blending
blending creates
creates “double
“double blends”
blends”
–– But
But stencil
stencil testing
testing can
can eliminate
eliminate “double
“double blends”
blends”
–– Specular
Specular highlights
highlights can
can show
show in
in shadow
shadow
Planar Projected
Shadow Artifacts
Bad Good
extends off
ground region
eye
position surface inside
partially
shadowed shadow volume
object (shadowed)
Tagging Pixels as
Shadowed or Unshadowed
Using stencil testing
•• High -level algorithm
High-level algorithm does
does not
not say
say how
how to
to update
update only
only either
either pixels
pixels
in
in or
or out
out of
of the
the shadow
shadow volume!
volume!
•• The
The stenciling
stenciling approach
approach
–– Clear
Clear stencil
stencil buffer
buffer to
to zero
zero and
and depth
depth buffer
buffer to
to 1.0
1.0
–– Render
Render scene
scene to
to leave
leave depth
depth buffer
buffer with
with closest
closest Zs
Zs
–– Render
Render shadow
shadow volume
volume into
into frame
frame buffer
buffer with
with depth
depth testing
testing but
but
without
without updating
updating color
color and
and depth, but inverting
depth, but inverting aa stencil
stencil bit
bit
–– This
This leaves
leaves stencil
stencil bit
bit set
set within
within shadow!
shadow!
Stencil Inverting of
Shadow Volume
Why it works
shadowing
light object
source
two inverts, left zero
zero +1
zero
+2 +2
eye +1 +3
position
Shadow Volume
Issues
Practical considerations [Bergeron 86]
•• IfIf eye
eye is
is in
in shadow
shadow volume,
volume, need
need to
to determine
determine this
this and
and flip
flip
enabled
enabled & & disabled
disabled lighting
lighting passes
passes
•• Shadow
Shadow volume
volume only
only as
as good
good as
as its
its tessellation
tessellation
–– Shadows
Shadows tend
tend to
to magnify
magnify limited
limited tessellation
tessellation of
of curved
curved
surfaces
surfaces
•• Must
Must cap
cap the
the shadow
shadow volume’s
volume’s intersection
intersection with
with the
the near
near
clipping
clipping plane
plane
•• Open
Open models
models and
and non -planar polygons
non-planar polygons
Reconstructing Shadow
Volume From a Depth Buffer
Very clever idea [McCool 98]
•• Render
Render scene
scene from
from light
light source
source with
with depth
depth testing
testing
•• Read
Read back
back the
the depth
depth buffer
buffer
•• Use
Use computer
computer vision
vision techniques
techniques to
to reconstruct
reconstruct the
the shadow
shadow
volume geometry
volume geometry from
from the
the depth buffer image
depth buffer image
•• Very
Very reasonable
reasonable results
results for
for complex
complex scenes
scenes
Multiple Lights and
Shadow Volumes
Requires
Requires still
still more
more rendering
rendering passes,
passes,
but
but can
can work!
work!
18% 25%
56% 25%
93% 25%
f = e--(d
(d z)
z)
•• Intuition:
Intuition: Clarity
Clarity is
is 100%
100% atat 00 meters
meters,, but at xx ++ 10
but at 10 meters
meters is
is
99%
99% of of the
the clarity at xx meters
clarity at meters
at 30
–– at 30 meters
meters,, the
the clarity
clarity is (0.99 ×× 0.99
is (0.99 0.99 ×× 0.99)%
0.99)%
–– continuous
continuous version
version of
of this
this idea
idea is
is an
an exponential
exponential drop -off
drop-off
Standard
OpenGL Fog Models
Fog factor equations
2
GL_EXP2 f = e-(d z)
f GL_EXP f = e-(d z)
Zeye
B planar
eye-distance
A
radial
eye
eye-distance
position view
frustum
•• The
The extension rate α
extension rate α (density)
(density) is
is integrated
integrated over
over the
the optical
optical
path
path from
from point
point AA to
to point
point B
B
–– This
This integral
integral is
is the
the optical
optical depth
depth
Assume α
•• Assume α varies
varies solely
solely with
with height
height (altitude)
(altitude)
Height-based Fog
Scenario
Consider the optical depth from A to B
Y2 A = eye position
C B
B = fogged position
∆Y
C = position above A
Y1 at height of B
A
D1 D1
∆D
Y2 Y2 Y1
∫ α(y) dy = ∫ α(y) dy -
-∞
∫ α(y) dy
Y1 -∞