Advanced OpenGL Technique Jian Huang, CS 594, Fall 2002

advertisement
Advanced OpenGL Technique
Jian Huang, CS 594, Fall 2002
Redbook: Chapters 6.1, 9.5, 9.6, 10
List of Topics
• Blending
• Multi-texturing
• Frame buffers
– Stencil buffer
– A-buffer (accumulation buffer)
• Fragment Tests
Alpha: the 4th Color Component
• Measure of Opacity
– simulate translucent objects
• glass, water, etc.
– composite images
– antialiasing
– ignored if blending is not enabled
glEnable( GL_BLEND )
Compositing for Semi-transparency
• Requires sorting! (BTF vs. FTB)
• “over” operator - Porter & Duff 1984
• a : opacity
C(0)in
Cin
C, a
Ci, ai
Cout
Cout  Cin  (1  a)  C  a
C(N)out
C i in  C i  1out
Fragment
• Fragment in OGL: after the rasterization
stage (including texturing), the data are not
yet pixel, but are fragments
– Fragment is all the data associated with a pixel,
including coordinate, color, depth and texture
coordinates.
Blending in OGL
• If a fragment makes it to FB, the pixel is read out and
blended with the fragment’s color and then written
back to FB
• The contributions of fragment and FB pixel is
specified: glBlendFunc( src, dst )
Blending Function
• Four choices:
–
–
–
–
GL_ONE
GL_ZERO
GL_SRC_ALPHA
GL_ONE_MINUS_SRC_ALPHA
• Blending is enabled using glEnable(GL_BLEND)
• Note: If your OpenGL implementation supports the
GL_ARB_imaging extension, you can modify the
blending equation as well.
3D Blending with Depth Buffer
• A scene of opaque and translucent objects
– Enable depth buffering and depth test
– Draw opaque objects
– Make the depth buffer read only, with
glDepthMask(GL_FALSE)
– Draw the translucent objects (sort those triangles
still, but which order, FTB or BTF?)
How Many Buffers Are There?
• In OpenGL:
– Color buffers: front, back, front-left, front-right, back-left,
back-right and other auxiliaries
– Depth buffer
– Stencil buffer
– Accumulation buffer
• Exactly how many bits are there in each buffer,
depends on
– OGL implementation
– what you choose
• Each buffer can be individually cleared
Selecting Color Buffer for Writing
and Reading
• Drawing and reading can go into any of front, back,
front-left, front-right, back-left, back-right and other
auxiliaries
• glDrawBuffer: select buffer to be written or drawn into
– Can have multiple writing buffer at the same time
• glReadBuffer: select buffer as the source for
–
–
–
–
glReadPixels
glCopyPixels
glCopyTexImage (copy from FB to a texture image)
glCopyTexSubImage
Accumulation Buffer
• Problems of compositing into color buffers
– limited color resolution (e.g. 8 bits/channel)
• clamping
• loss of accuracy
• Accumulation buffer acts as a “floating point”
color buffer
– accumulate into accumulation buffer
– transfer results to frame buffer
Accumulation Buffer
• OGL don’t directly write into A-buffer
• Typically, a series of images are rendered to
a standard color buffer and then
accumulated, one at a time, into the A-buffer.
• Then, the result in A-buffer has to be copied
back to a color buffer for viewing
• A-buffer may have more bits/color
Accessing Accumulation Buffer
• glAccum(op, value ) operations
– within the accumulation buffer:
• GL_ADD, GL_MULT
– from read buffer
• GL_ACCUM, GL_LOAD
– transfer back to write buffer
• GL_RETURN
– glAccum( GL_ACCUM, 0.5) multiplies each value
in read buffer by 0.5 and adds to accumulation
buffer
– How do you average N images?!
Accumulation Buffer Applications
•
•
•
•
•
Compositing
Full Scene Anti-aliasing
Depth of Field
Filtering
Motion Blur
Full Scene Antialiasing
•
•
•
•
Jittering the view (how?? )
Each time we move the viewer, the image shifts
Different aliasing artifacts in each image
Averaging images using accumulation buffer
averages out these artifacts
• Like super-sampling in ray-tracing
Depth of Focus
• Keeping a Plane in Focus
• Jitter the viewer to keep one plane
unchanged
How do you jitter
the viewer ????
Move the camera in a plane parallel to the focal plane.
What else?
• Can you do soft shadows?
– Jitter the light sources
• What about motion blur
– Jitter the moving object in the scene
– glAccum(GL_MULT, decayFactor)
A Fragment’s Journey Towards FB
• Many Tests (on/off with glEnable)
–
–
–
–
scissor test - an additional clipping test
alpha test - a filtering test based on alpha
stencil test - a pixel mask test
depth test - fragment occlusion test
Scissor Box
• Additional Clipping test
– glScissor( x, y, w, h )
• any fragments outside of box are clipped
• useful for updating a small section of a
viewport
• affects glClear() operations
Alpha Test
• Reject pixels based on their alpha value
• glAlphaFunc(func, value)
–
–
–
–
GL_NEVER
GL_LESS
GL_EQUAL
GL_LEQUAL
GL_GREATER GL_NOTEQUAL
GL_GEUQAL
GL_ALWAYS
• For instance, use as a mask for texture
– How would you render a fence?
Stencil Test
• Used to control drawing based on values in
the stencil buffer
• Fragments that failt the stencil test are not
drawn
– Example: create a mask in stencil buffer and draw
only objects not in mask area
Stencil Buffer
• Don’t render into stencil buffer
– Control stencil buffer values with stencil
function
– Can change stencil buffer values with each
fragment passing or failing the test
Controlling Stencil Buffer
• For each pixel, what do I do? Look:
– glStencilFunc( func, ref, mask )
• compare value in buffer with (ref AND mask) and
(stencil_pixel AND mask) using func
• func is one of standard comparison functions
– glStencilOp( fail, zfail, zpass )
•
•
•
•
•
Allows changes in stencil buffer based on:
Failing stencil test
Failing depth test
Passing depth test
GL_KEEP, GL_INCR, GL_REPLACE, GL_DECR,
GL_INVERT, GL_ZERO
Creating a Mask
• Initialize Mask
glInitDisplayMode( …|GLUT_STENCIL|… );
glEnable( GL_STENCIL_TEST );
glClearStencil( 0x0 );
glStencilFunc( GL_ALWAYS, 0x1, 0x1 );
glStencilOp( GL_REPLACE, GL_REPLACE,
GL_REPLACE );
Using Stencil Mask
• glStencilFunc( GL_EQUAL, 0x1, 0x1 )
draw objects where stencil = 1
• glStencilFunc( GL_NOT_EQUAL, 0x1, 0x1 );
• glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
draw objects where stencil != 1
Dithering
• glEnable( GL_DITHER )
• Dither colors for better looking results
• Used to simulate more available colors
– Say, newspapers
• OGL will modify the color of a fragment
with a dithering table
Logical Operations on Fragments
• Combine fragment and pixel color using bitwise logical operations: glLogicOp( mode )
• Common modes
–
–
–
–
–
–
GL_CLEAR
GL_SET
GL_COPY,
GL_COPY_INVERTED GL_NOOP GL_INVERT
GL_AND
GL_NAND GL_OR
GL_NOR GL_XOR GL_AND_INVERTED
GL_AND_REVERSE GL_EQUIV
GL_OR_INVERTED
GL_OR_REVERSE
Texturing
• Texture functions: glTexEnv( ), specifies how
texture values are combined with the color
values of each fragment
• Texture environment mode: Tables 9-4,5
–
–
–
–
GL_DECAL
GL_REPLACE
GL_MODULATE
GL_BLEND
Multi-Texturing
• Should have at least 2 texture units if multitexturing is supported
• Each texture unit:
–
–
–
–
–
Texture image
Filtering parameters
Environment application
Texture matrix stack
Automatic texture-coordinate generation (doesn’t
seem obvious, but very have very creative apps)
Texture Matrix Stack
• At least 2 matrices deep
• 4x4 matrix
• Can take texture coordinates in
homogeneous space (s, t, r, q)
More extensions
•
•
[Segal 1992], need OpenGL extensions. Multi-texturing is made extremely
interesting and creative. Please check nvidia.com for white papers on these.
Not in the current redbook published in 1997.
#ifndef GL_VERSION_texture_env_combine
#define GL_COMBINE
#define GL_ADD_SIGNED
#define GL_INTERPOLATE
#define GL_CONSTANT
#define GL_PRIMARY_COLOR
#define GL_PREVIOUS
#define GL_COMBINE_RGB
#define GL_COMBINE_ALPHA
#define GL_SOURCE0_RGB
#define GL_SOURCE1_RGB
#define GL_SOURCE2_RGB
#define GL_SOURCE0_ALPHA
#define GL_SOURCE1_ALPHA
#define GL_SOURCE2_ALPHA
#define GL_OPERAND0_RGB
#define GL_OPERAND1_RGB
#define GL_OPERAND2_RGB
#define GL_OPERAND0_ALPHA
#define GL_OPERAND1_ALPHA
#define GL_OPERAND2_ALPHA
#define GL_RGB_SCALE
0x8570
0x8574
0x8575
0x8576
0x8577
0x8578
0x8571
0x8572
0x8580
0x8581
0x8582
0x8588
0x8589
0x858A
0x8590
0x8591
0x8592
0x8598
0x8599
0x859A
0x8573
OpenGL Multitexture
Extension
• Standardized and widely available
– Introduces concept of multiple texture units
• Two or more texture units
• Existing texture API extended to implicitly use
active texture unit
glActiveTextureARB(GL_TEXTUREn_ARB)
– Each unit has its own complete and independent
OpenGL texture state
• Texture image, filtering modes, texture
environment, texture matrix
OpenGL Multitexture Quick Tutorial
– Configuring up a given texture unit:
glActiveTextureARB(GL_TEXTURE1_ARB);
Sets active texture unit
glBindTexture(GL_TEXTURE_2D, texObject);
glTexImage2D(GL_TEXTURE_2D, …);
Implicitly
glTexParameterfv(GL_TEXTURE_2D, …);
update
glTexEnvfv(GL_TEXTURE_ENV, …);
state of
glTexGenfv(GL_S, …);
active
glMatrixMode(GL_TEXTURE);
texture
glLoadIdentity();
unit
– Setting texture coordinates for a vertex:
glMultiTexCoord4f(GL_TEXTURE0_ARB, s0, t0, r0 ,q0);
glMultiTexCoord2f(GL_TEXTURE1_ARB, s1, t1);
glMultiTexCoord3f(GL_TEXTURE2_ARB, s2, t2, r2);
glVertex3f(x, y, z);
OpenGL Multitexture Texture
Environments
• Chain of Texture Environment Stages
Pre-texturing color
glColor3f(r,g,b)
#0
glMultiTexCoord2f(
GL_TEXTURE0_ARB, …)
glMultiTexCoord2f(
GL_TEXTURE1_ARB, …)
Lookup
& filter
GL_MODULATE
#1
Lookup
& filter
GL_DECAL
#2
glMultiTexCoord2f(
GL_TEXTURE2_ARB, …)
Lookup
& filter
GL_BLEND
Post-texturing
color
Extending the OpenGL
Texture Environment
• ARB_multitexture is just the start
– Standard OpenGL has just GL_REPLACE,
GL_MODULATE, GL_DECAL, and GL_BLEND
– ENV_texture_env_add introduces GL_ADD
– ENV_texture_env_combine
• Powerful “(AB + C)  scale + bias”
• A, B, C variables use various color inputs
– Future texture environments even more powerful
Examples of More Powerful
Texture Environments
• NVIDIA GPU OpenGL extensions
– TNT and later GPUs support
NV_texture_env_combine4
• A * B + C * D computation
• multiple texture inputs available in a single stage
• enables single-pass emboss bump mapping
– GeForce and later GPUs support
NV_register_combiners
• dot products, signed math, much more
• register processing model for non-sequential data flows
Cube Map Texturing
• Direct Use of Cube Maps
– Latest hardware supports this
• DirectX 7 support
• OpenGL extension support
– Hardware directly performs cube map accesses
• Requires hardware support for good performance
– Cube map construction much easier
Using Cube Maps
in OpenGL
• Very easy to use ARB extension
– New texture target:
GL_TEXTURE_CUBE_MAP_ARB
• Used for manipulating cube map as a whole
– Six cube map “face” targets
•
•
•
•
•
Used for manipulating particular cube map faces
GL_TEXTURE_CUBE_MAP_dir_axis _ARB
dir is { POSITIVE, NEGATIVE }
axis is { X, Y, Z }
Use 2D texture image API (glTexImage2D, etc)
Cube Map Support
• Official OpenGL standard now
– OpenGL cube map support was introduced by NVIDIA
• GeForce drivers have EXT_texture_cube_map extension
– OpenGL Architectural Review Board (ARB) recently
accepted the extension as an ARB standard
• renamed ARB_texture_cube_map
• but same identical functionality
• semantics & enumerant values same as the EXT version
– Other vendors such as ATI planning cube map support
OpenGL Cube Map
Setup Usage
Binding to a cube map texture
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cmap);
Loading cube map faces
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
level, format, width, height, border, format, type, positiveXpixels);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
level, format, width, height, border, format, type, negativeXpixels);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
level, format, width, height, border, format, type, negativeYpixels);
•. . . similarly load other three faces . . .
OpenGL Cube Map Rendering
Usage
• Enabling a cube map texture
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
• Explicit cube map coordinates
glTexCoord3f(vx, vy, vz);
// (vx,vy,vz) is unnormalized direction vector
• Generated cube map coordinates (recommended)
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_NORMALIZE);
Advantages of Cube Maps
• Compared to Other Approaches
– View-independent
• Unlike sphere mapping
– Uses a single texture unit
• Unlike dual-paraboloid mapping
– Entire texture resolution is sampled
• Unlike sphere or dual-paraboloid approaches
– Improved environment sampling
Getting Back to Object Space
• No magic here. Just undo the transformation.
Gldouble objX, objY, objZ;
// get the modelview, project, and viewport
glGetDoublev( GL_MODELVIEW_MATRIX, mv_mat );
glGetDoublev( GL_PROJECTION_MATRIX, proj_mat );
glGetIntegerv( GL_VIEWPORT, viewport );
// get the current depth buffer
g_depth_view = new GLfloat[winWidth * winHeight];
glReadPixels( 0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT, depth_view );
for( y = 0; y < winHeight; y ++ )
// go through every pixel in frame buffer
for( x = 0; x < winWidth; x ++ ) {
if ( *depth_view < 1.00 )
gluUnProject(x, y, *depth_view, mv_mat, proj_mat, viewport, &objX, &objY, &objZ);
depth_view ++;
}
Download