420 likes | 646 Views
Clever Uses of OpenGL. Kurt Akeley CS248 Lecture 16 15 November 2007 http://graphics.stanford.edu/courses/cs248-07/. Emphasis. Is on OpenGL mechanisms and their application OpenGL is a power tool It can be applied in clever and non-obvious ways
E N D
Clever Uses of OpenGL Kurt Akeley CS248 Lecture 16 15 November 2007 http://graphics.stanford.edu/courses/cs248-07/
Emphasis Is on OpenGL mechanisms and their application • OpenGL is a power tool • It can be applied in clever and non-obvious ways Is not full coverage of useful graphics algorithms • Many will not be covered • But what we do cover will be useful
Reference Advanced Graphics Programming Using OpenGL • Tom McReynolds (NVIDIA) • David Blythe (Microsoft, Direct3D 10 architect)
Informal taxonomy of clever uses Accumulation • Z-buffer • Transparent surfaces • Multisample antialiased surfaces with pre-filtered lines • Image composition Texture • Contour mapping • Image warping • Billboards • Implementing pre-filter antialiasing with texture lookup • Volume rendering Polygon offset • Coplanar primitives • Hidden-line rendering Stencil • Capping • Shadow volumes GPGPU
Invariance On a single machine • Appendix A • Invariant enable/disable • Consistent input sequence • E.g., use glFrontFace to reverse facing direction, rather than reordering the vertexes or reflecting by scaling Cross-platform • Be careful! • OpenGL’s design emphasized cross-platform compatibility • But there are still many differences between platforms • Endian issues and support
Accumulation Basic idea: • Build up a final image in the framebuffer by depth buffering and/or blending multiple images Examples • Z-buffer • Transparent surfaces • Multisample solids with pre-filtered antialiased lines • Image composition
Z-buffer glEnable(GL_DEPTH_TEST);glDisable(GL_DEPTH_TEST); glDepthFunc(GL_NEVER | GL_LESS | GL_EQUAL | GL_LEQUAL | GL_GREATER | GL_NOTEQUAL | GL+GEQUAL | GL_ALWAYS);glDepthFunc(GL_ALWAYS); // invariant disable glDepthMask(GL_TRUE); // enable writingglDepthMask(GL_FALSE); // disable writing if (Zfrag depthfunc Zpixel) { if (Rcolormask) Rpixel Rfrag; if (Gcolormask) Gpixel Gfrag; if (Bcolormask) Bpixel Bfrag; if (Acolormask) Apixel Afrag; if (depthmask) Zpixel Zfrag;}
Transparent surfaces glEnable(GL_DEPTH_TEST);glEnable(GL_LIGHTING);draw opaque objects glDepthMask(GL_FALSE); // key OpenGL modeglEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_CULL_FACE); // optionalglCullFace(GL_BACK);draw transparent surfaces in any order glDisable(GL_DEPTH_TEST);glDisable(GL_LIGHTING);glDepthMask(GL_TRUE);glDisable(GL_BLEND);glDisable(GL_CULL_FACE);
Multisample and pre-filter antialiasing glEnable(GL_DEPTH_TEST);glEnable(GL_LIGHTING);glEnable(GL_MULTISAMPLE);draw solid objects (triangles) glDepthMask(GL_FALSE);glDisable(GL_MULTISAMPLE);glEnable(GL_LINE_SMOOTH);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE);glDisable(GL_LIGHTING); // optionaldraw pre-filter antialiased lines in any order glDisable(GL_DEPTH_TEST);glDisable(GL_LIGHTING);glDepthMask(GL_TRUE);glDisable(GL_LINE_SMOOTH);glDisable(GL_BLEND);
Image composition (fade) glEnable(GL_BLEND);glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE); glBlendColor(0, 0, 0, first weight);glDrawPixels(first image); glBlendColor(0, 0, 0, second weight);glDrawPixels(second image); glDisable(GL_BLEND);
Image composition (over) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ZERO);glDrawPixels(first image); gllendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glDrawPixels(second image); glDisable(GL_BLEND);
Texture Basic idea: • Use texture mapping mechanisms for creative purposes Examples • Contour mapping • Image warping • Billboards • Implementing pre-filter antialiasing texture lookup • Volume rendering
Contour mapping glEnable(GL_DEPTH_TEST);glEnable(GL_LIGHTING);glEnable(GL_TEXTURE_1D);glEnable(GL_TEXTURE_GEN_S);glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);glTexGenfv(GL_S, GL_EYE_PLANE, vec4f(f, 0, 10, 0, 0));draw objects without specifying texture coordinates glDisable(GL_DEPTH_TEST);glDisable(GL_LIGHTING);glDisable(GL_TEXTURE_1D);glDisable(GL_TEXTURE_GEN_S); Today a vertex shader is amore general TexGen mechanism.But the notion of generated texturecoordinates remains important.
Image warping glEnable(GL_TEXTURE_2D);for (y=0; y<(height-1); ++y) { glBegin(GL_QUAD_STRIP); for (x=0; x<width; ++x) { glTexCoord2fv(tex[index(x,y)]); glVertex2fv (vtx[index(x,y)]); glTexCoord2fv(tex[index(x,y+1)]); glVertex2fv (vtx[index(x,y+1)]); } glEnd();}
Billboards Application Poster-child application of geometry shaders! Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Advanced Graphics Programming Using OpenGLFigure 13.4 Display
The magic of machine shops Sewing machines make clothes But machine tools make machine tools • And computers are this century’s machine tools Hagley Machine Shop, Wilmington, DEPhoto by Incaz, Flickr
Pre-filter antialiasing via texture lookup Application Another ideal geometry-shader application Vertex assembly // draw pre-filtered point at (x,y)const float h = 1.5; // 3x3 filterglEnable(GL_TEXTURE_2D);glBegin(GL_QUADS);glTexCoord2f(0, 0); glVertex2f(x-h, y-h);glTexCoord2f(0, 1); glVertex2f(x-h, y+h);glTexCoord2f(1, 1); glVertex2f(x+h, y+h);glTexCoord2f(1, 0); glVertex2f(x+h, y-h);glEnd(); Vertex operations Primitive assembly Primitive operations Rasterization (0 1) (1 1) (x-h y+h) (x+h y+h) Fragment operations Framebuffer Display (0 0) (1 0) (x-h y-h) (x+h y-h)
Volume rendering Advanced Graphics Programming Using OpenGLFigure 20.12 Advanced Graphics Programming Using OpenGLFigure 20.13
Polygon offset Basic idea: • Avoid depth fighting by biasing Z values Examples • Coplanar primitives • Hidden lines • Silhouette edges
Polygon mode glPolygonMode(GLenum face, GLenum mode); GL_FILL, GL_LINE, GL_POINT Face culling happensbefore conversionto lines or points! GL_FRONT, GL_BACK, GL_FRONT_AND_BACK GL_FILL GL_LINE GL_POINT
Triangle(on edge) Line(on edge) -z View position Polygon offset Correspond to polygon modes glEnable/glDisable(GL_POLYGON_OFFSET_FILL | GL_POLYGON_OFFSET_LINE | GL_POLYGON_OFFSET_POINT); glPolygonOffset(GLfloat factor, GLfloat units); Minimum resolvable z-buffer difference
Coplanar primitives glEnable(GL_DEPTH_TEST);glEnable(GL_LIGHTING);glEnable(GL_POLYGON_OFFSET_FILL);glPolygonOffset(maxwidth/2, 1);draw planar surface glDepthMask(GL_FALSE);glDisable(GL_POLYGON_OFFSET_FILL);draw points, lines, and polygons on the planar surface glDisable(GL_DEPTH_TEST);glDisable(GL_LIGHTING);glDepthMask(GL_TRUE);
Hidden lines glEnable(GL_DEPTH_TEST);glDisable(GL_LIGHTING);glColorMask(false, false, false, false);glEnable(GL_POLYGON_OFFSET_FILL);glPolygonOffset(maxwidth/2, 1);draw solid objects glDepthMask(GL_FALSE);glColorMask(true, true, true, true);glColor3f(linecolor);glDisable(GL_POLYGON_OFFSET_FILL);glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);draw solid objects again glDisable(GL_DEPTH_TEST);glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glDepthMask(GL_TRUE);
Silhouette lines (true hidden-line drawing) glEnable(GL_DEPTH_TEST);glDisable(GL_LIGHTING);glColorMask(false, false, false, false);glEnable(GL_POLYGON_OFFSET_FILL);glPolygonOffset(maxwidth/2, 1);draw solid objects glDepthMask(GL_FALSE);glColorMask(true, true, true, true);glColor3f(1, 1, 1);glDisable(GL_POLYGON_OFFSET_FILL);glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);glEnable(GL_CULL_FACE);glCullFace(GL_FRONT);draw solid objects againdraw true edges // for a complete hidden-line drawing glDisable(GL_DEPTH_TEST);glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glDepthMask(GL_TRUE);glDisable(GL_CULL_FACE); Additions to the hidden-line algorithm (previous slide) highlighted in red
Stencil Basic idea: • Implement a simple state machine in every pixel Examples • Capping • Shadow volumes
Stencil glEnable(GL_STENCIL_TEST);glDisable(GL_STENCIL_TEST); glStencilFunc(GLenum func, GLint ref, GLuint mask); glStencilOp(GLenum fail, GLenum zfail, GLenum zpass); glStencilMask(GLuint mask); GL_NEVER, GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL, GL_EQUAL, GL_NOTEQUAL, GL_ALWAYS Bitmask, not Boolean flag GL_KEEP, GL_ZERO, GL_REPLACE (with ref), GL_INCR, GL_DECR, GL_INVERT
Z-buffer operation (again) if (Zfrag depthfunc Zpixel) { if (Rcolormask) Rpixel Rfrag; if (Gcolormask) Gpixel Gfrag; if (Bcolormask) Bpixel Bfrag; if (Acolormask) Apixel Afrag; if (depthmask) Zpixel Zfrag;}
Stencil operation if ((ref & mask) stencilfunc (Spixel & mask)) {if (Zfrag depthfunc Zpixel) { if (Rcolormask) Rpixel Rfrag; if (Gcolormask) Gpixel Gfrag; if (Bcolormask) Bpixel Bfrag; if (Acolormask) Apixel Afrag; if (depthmask) Zpixel Zfrag; StencilOp(zpass); } else { StencilOp(zfail); }}else { StencilOp(fail);} Z-buffer operation Stencil implements a state machine in each pixel .(A programmable action occurs in every cases)
Capping glEnable(GL_DEPTH_TEST); // remains enabledglEnable(GL_LIGHTING);for (int i=0; i<max; ++i) { drawWithCap(model, i); … drawWithCap(int model, int i) { setMaterial(model, i); glEnable(GL_CLIP_PLANE0); glEnable(GL_STENCIL_TEST); glEnable(GL_CULL_FACE); glStencilFunc(GL_GEQUAL, 1, 3); // don’t change capped pixels glCullFace(GL_BACK); // render frontfacing only glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); // clear stencil to 0 drawModel(model, i); glCullFace(GL_FRONT); // render backfacing only glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // set stencil to 1 drawModel(model, i); glDisable(GL_CULL_FACE); glDisable(GL_CLIP_PLANE0); glStencilFunc(GL_EQUAL, 1, 3); // draw only where stencil is 1 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // set stencil to 2 drawCap(); glDisable(GL_STENCIL_TEST);}
Shadow volumes Similar to capping: • Render the scene • Render shadow volumes • Don’t change color or depth • Use stencil to determine in/out • Reduce intensities of pixels in shadow Common game technique • E.g., Quake, Doom Simple frustum culling fails! • Must keep light sources and occluders that cast shadows on geometry within the frustum
GPGPU Basic idea: • General-purposes computing on GPUs • Take advantage of the huge compute power of modern GPUs
Multi-pass vector processing (2000) • Treat OpenGL as a very long instruction word • Compute vector style • Apply inst. to all pixels • Build up final image in many passes • Peercy, Olano, Airey, and Ungar, Interactive Multi-Pass Programmable Shading, SIGGRAPH 2000 • (Figure adapted from the SIGGRAPH paper) #include “marble.h” surface marble() { varying color a; uniform string fx; uniform float x; x = ½; fx = “noisebw.tx”; FB = texture(tx, scale(x,x,x)); repeat(3) { x = x * 0.5; FB *= 0.5; FB += texture(tx, scale(x,x,x)); } FB = lookup(FB,tab); a = FB; FB = diffuse; FB *= a; FB += environment(“env”); }
GPGPU Still operates on images • Conceptually 2-D arrays of data elements Deemphasizes VLIW thinking • Most pipeline stages are not used • What is used: • Rasterization (to generate and schedule data elements) • Fragment operations (specifically the programmable shader) • Texture lookup and filter (gather, not a stream processor) • Fragment/framebuffer operations (usually limited to write) Emphasizes data-parallel programmability Clever solutions have been developed for • Scatter • Reduction • Sorting …
Modern GPGPU Graphics APIs (OpenGL, Direct 3D) being replaced: • CUDA (NVIDIA) • CTM (AMD) Great results being achieved: • Technical: 10x performance improvement in some cases • Business: multi-billion dollars anticipated soon Coming soon: • IEEE double precision arithmetic • Greater exposure of hardware details (AMD) • Intel Larrabee • …
Summary Powerful OpenGL mechanisms (some introduced by IRIS/OpenGL): • 8-way comparison and masks (depth, stencil, alpha, …) • Texture features: • 3-D • TexGen and Texture coordinate matrix • Homogeneous coordinates • Application to all primitives (not just triangles) • glPolygonOffset • Stencil (state machine in a pixel) Shaders have devalued some of these (e.g., TexGen) but most remain valuable It’s fun and productive to devise clever uses of OpenGL
Assignments No class next week Next lecture: Color theory (Tuesday 27 November) Reading assignment: FvD 13.2 through 13.6