430 likes | 673 Views
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 4 th Color Component. Measure of Opacity
E N D
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
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 bit-wise 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 multi-texturing 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 0x8570 #define GL_ADD_SIGNED 0x8574 #define GL_INTERPOLATE 0x8575 #define GL_CONSTANT 0x8576 #define GL_PRIMARY_COLOR 0x8577 #define GL_PREVIOUS 0x8578 #define GL_COMBINE_RGB 0x8571 #define GL_COMBINE_ALPHA 0x8572 #define GL_SOURCE0_RGB 0x8580 #define GL_SOURCE1_RGB 0x8581 #define GL_SOURCE2_RGB 0x8582 #define GL_SOURCE0_ALPHA 0x8588 #define GL_SOURCE1_ALPHA 0x8589 #define GL_SOURCE2_ALPHA 0x858A #define GL_OPERAND0_RGB 0x8590 #define GL_OPERAND1_RGB 0x8591 #define GL_OPERAND2_RGB 0x8592 #define GL_OPERAND0_ALPHA 0x8598 #define GL_OPERAND1_ALPHA 0x8599 #define GL_OPERAND2_ALPHA 0x859A #define GL_RGB_SCALE 0x8573
OpenGL MultitextureExtension • Standardized and widely available • Introduces concept of multiple texture units • Two or more texture units • Existing texture API extended to implicitly useactive texture unitglActiveTextureARB(GL_TEXTUREn_ARB) • Each unit has its own complete and independent OpenGL texture state • Texture image, filtering modes, textureenvironment, texture matrix
OpenGL Multitexture Quick Tutorial • Configuring up a given texture unit:glActiveTextureARB(GL_TEXTURE1_ARB);glBindTexture(GL_TEXTURE_2D, texObject);glTexImage2D(GL_TEXTURE_2D, …);glTexParameterfv(GL_TEXTURE_2D, …);glTexEnvfv(GL_TEXTURE_ENV, …);glTexGenfv(GL_S, …);glMatrixMode(GL_TEXTURE);glLoadIdentity(); • 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); Sets active texture unit Implicitlyupdate state of active texture unit
OpenGL Multitexture Texture Environments • Chain of Texture Environment Stages Pre-texturing colorglColor3f(r,g,b) #0 Lookup & filter glMultiTexCoord2f( GL_TEXTURE0_ARB, …) GL_MODULATE #1 glMultiTexCoord2f( GL_TEXTURE1_ARB, …) Lookup & filter GL_DECAL #2 Post-texturing color glMultiTexCoord2f( GL_TEXTURE2_ARB, …) Lookup & filter GL_BLEND
Extending the OpenGLTexture 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 “(AB + C) scale + bias” • A, B, C variables use various color inputs • Future texture environments even more powerful
Examples of More PowerfulTexture 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 Mapsin 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 • diris { POSITIVE, NEGATIVE } • axisis { 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 MapSetup 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 ++; }