Presentation is loading. Please wait.

Presentation is loading. Please wait.

Jittering, Introduction to Stenciling Glenn G. Chappell U. of Alaska Fairbanks CS 481/681 Lecture Notes Friday, February 6, 2004.

Similar presentations


Presentation on theme: "Jittering, Introduction to Stenciling Glenn G. Chappell U. of Alaska Fairbanks CS 481/681 Lecture Notes Friday, February 6, 2004."— Presentation transcript:

1 Jittering, Introduction to Stenciling Glenn G. Chappell CHAPPELLG@member.ams.org U. of Alaska Fairbanks CS 481/681 Lecture Notes Friday, February 6, 2004

2 6 Feb 2004CS 481/6812 Review: Accumulation Effects [1/3] Last time we covered OpenGL’s accumulation buffer (AB). The AB holds RGBA data, just like color buffers. The AB allows blending of 2-D images. We can do five operations on the AB. They are all performed on the entire buffer at once: AB = 0. Use glClear(GL_ACCUM_BUFFER_BIT | … );. AB = k*C. Use glAccum(GL_LOAD, k ); AB += k*C. Use glAccum(GL_ACCUM, k ); AB *= k. Use glAccum(GL_MULT, k ); Also AB += k, using GL_ADD. C = k*AB. Use glAccum(GL_RETURN, k );

3 6 Feb 2004CS 481/6813 Review: Accumulation Effects [2/3] Typically, code that uses the AB might look like this: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); … // Draw scene 0 glAccum(GL_LOAD, [scene 0 weight] ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); … // Draw scene 1 glAccum(GL_ACCUM, [scene 1 weight] ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); … // Draw scene 2 glAccum(GL_ACCUM, [scene 2 weight] ); glAccum(GL_RETURN, 1.); glutSwapBuffers(); The weights should all be in [0,1], and should sum to 1. The drawing of the various scenes could be inside a loop.

4 6 Feb 2004CS 481/6814 Review: Accumulation Effects [3/3] Blending of rendered images can be used to create all sorts of effects: Scene-to-scene fade. See fade.cpp. Motion blur. Fancier effects use a technique called “jittering”. Render the same scene repeatedly with small movements made in some way. Blend the resulting images. Now we look at jittering in more detail.

5 6 Feb 2004CS 481/6815 Details of Jittering: Overview Topics The basic mechanics of jittering. Code for simple jittering. Using jittering to achieve three effects: Anti-Aliasing Depth-of-Field Effect Soft Shadows Our code will be based on simplejitter.cpp, which uses jitter.h. Both are on the web page.

6 6 Feb 2004CS 481/6816 Details of Jittering: Basics Jittering, again, is: Making small, random-ish movements in a scene. We get better results from pre-computed, nicely distributed numbers than from random values. Rendering the scene for each small change. Blending the resulting images. In OpenGL, we generally use the accumulation buffer when jittering. Whatever it is that we jitter, movement in two dimensions is usually what we want. Thus, we need nice, pre-computed x & y values. Arrays of these can be found in jitter.h (from SGI). More jitters means slower, but better-looking results. So test with just a few jitters. Production code may have more. File jitter.h includes jittering arrays of various lengths (2, 3, 4, 8, 15, 24, and 66 jitters, respectively).

7 6 Feb 2004CS 481/6817 Details of Jittering: Code [1/2] The following is from the globals section of simplejitter.cpp. We want to be able to change the number of jitters without recompiling. jitter_point j1[] = { { 0., 0. } }; // Our own "no jittering" array, in // addition to SGI's arrays in jitter.h const int NUM_JITTER_ARRAYS = 8; // Number of jittering arrays const jitter_point * jitter_arrays[NUM_JITTER_ARRAYS] = { j1, j2, j3, j4, j8, j15, j24, j66 }; // Ptrs to the jittering arrays const int jitter_array_sizes[NUM_JITTER_ARRAYS] = { 1, 2, 3, 4, 8, 15, 24, 66 }; // Sizes of the jittering arrays int jsubs = 3; // subscript, selects WHICH jittering array const int maxjsubs = NUM_JITTER_ARRAYS - 1; const int minjsubs = 0;

8 6 Feb 2004CS 481/6818 Details of Jittering: Code [2/2] The following is based on the display function in simplejitter.cpp. Just about any sort of jittering can be done using this structure. Note the weight of each of the blended images. Also note where the instructions are drawn. const int jitters = jitter_array_sizes[jsubs]; for (int i=0; i<jitters; ++i) { const GLfloat jx = jitter_arrays[jsubs][i].x; // x & y offset const GLfloat jy = jitter_arrays[jsubs][i].y; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); … // Draw scene, jittered using jx, jy glAccum(((i > 0) ? GL_ACCUM : GL_LOAD), 1./jitters); } // Make final image glAccum(GL_RETURN, 1.); … // Draw instructions

9 6 Feb 2004CS 481/6819 Details of Jittering: Effects via Jittering In practice, we use jittering offsets ( jx, jy ) to create transformations. This is the tricky part. We need to generate the proper transformation. And we need to place the transformation correctly in the pipeline. Where? Model/view Transformation Projection Transformation Viewport Transformation World Coordinates Object Coordinates Eye Coordinates Window Coordinates Vertices (window coord’s) Vertex Operations Rasterization Fragment Operations Vertices (object coord’s) Fragments Vertex enters here To framebuffer Lighting Clipping (view-frustum) ??

10 6 Feb 2004CS 481/68110 Details of Jittering: Anti-Aliasing [1/2] Anti-aliasing means making rendered objects smoother-looking by allowing them to “partially occupy” pixels. Thus, a white line on a black background may have gray pixels on its border. Anti-aliasing is essentially a 2-D operation. So if we do anti-aliasing via jittering, then the transformation goes at the end of the projection (at the beginning in the code). We need to create the transformation in the display function (right?).

11 6 Feb 2004CS 481/68111 Details of Jittering: Anti-Aliasing [2/2] So we can do anti-aliasing by Saving window width & height (as winw, winh ) in function reshape. Putting the following code just after the computation of jx & jy : glMatrixMode(GL_PROJECTION); glLoadIdentity(); glTranslated(jx*2./winw, jy*2./winh, 0.); gluPerspective(60, double(winw)/winh, neardist, fardist); glMatrixMode(GL_MODELVIEW); The gluPerspective command gives the “standard” projection. Values 2./winw and 2./winh are width & height of a pixel. We do not push/pop because we do not need the old projection. Except for the projection, each scene rendering is identical. This is a strange use of glTranslate *, no?

12 6 Feb 2004CS 481/68112 Details of Jittering: Depth-of-Field Effect [1/3] To do the depth-of-field effect: Jitter so that a plane perpendicular to the z-axis remains stationary. Use a “shear” transformation: This is a 3-D, whole-scene effect, so the transformation goes at the beginning of the projection (at the end in the code). I suppose it could also go at the end of model/view (beginning in the code). But sending normals through a shear is a little strange. The above matrix is not quite what we need …

13 6 Feb 2004CS 481/68113 Details of Jittering: Depth-of-Field Effect [2/3] The shear transformation given by leaves the z = 0 plane stationary. We generally want to leave some other plane stationary. So we translate just before & just after the shear. Translate the fixed plane to z = 0. Then shear. Then translate back. Remember to reverse the order of these in the code. Values “a” and “b” above are something like jx and jy (probably scaled by some constant factor).

14 6 Feb 2004CS 481/68114 Details of Jittering: Depth-of-Field Effect [3/3] Here is some D.O.F. code that leaves the z = –4 plane stationary: const double fixed_plane = -4.; // We fix z = fixed_plane const double sf = … ; // Some appropriate scaling factor GLdouble mat[16] = { 1., 0., 0., 0., // Shear matrix 0., 1., 0., 0., // (appears sf*jx, sf*jy, 1., 0., // transposed!!) 0., 0., 0., 1. }; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, double(winw)/winh, neardist, fardist); glTranslated(0., 0., fixed_plane); // z = 0 -> fixed plane glMultMatrixd(mat); glTranslated(0., 0., -fixed_plane); // fixed plane -> z = 0 glMatrixMode(GL_MODELVIEW);

15 6 Feb 2004CS 481/68115 Details of Jittering: Soft Shadows To do soft shadows: We first do shadows. Somehow … Then we jitter the light source. We are jittering a single object in a scene, so the transformation goes at the beginning of model/view (at the end in the code). A simple translation will do; however, we should generally translate in directions perpendicular to the predominant light direction. No example for this one.

16 6 Feb 2004CS 481/68116 Introduction to Stenciling: Overview Next we discuss “stenciling”. Stenciling generally refers to restricting drawing to a particular region, based on previous drawing. Think: Draw a stencil. Use it to “spray paint”. As with accumulation, this idea is more versatile than you might think. Topics OpenGL tools for stenciling (today). Stenciling effects (next week) “Ordinary” stenciling. Capping. Shadows via shadow volumes. Etc. ?

17 6 Feb 2004CS 481/68117 Introduction to Stenciling: OpenGL’s Buffer & Test The stencil buffer and its associated test, the stencil test, can be used for a variety of yes/no, pass/fail-type effects. The stencil buffer holds an integer for each viewport pixel. The value in the buffer can be affected by several things, including the depth test. You can place values in the stencil buffer and then test them to determine whether to draw pixels. Allocate the stencil buffer using GLUT_STENCIL in your glutInitDisplayMode call. Clear the stencil buffer using glClear(GL_STENCIL_BUFFER_BIT); after setting the clearing value with glClearStencil. Enable the stencil test using glEnable(GL_STENCIL_TEST);

18 6 Feb 2004CS 481/68118 Introduction to Stenciling: OpenGL Functions The two major functions used in stenciling are glStencilFunc and glStencilOp. glStencilFunc determines what the stencil test does. glStencilOp determines what happens to the stencil buffer if the stencil test passes or fails. If the stencil test passes, then you can also have different outcomes based on the depth test.

19 6 Feb 2004CS 481/68119 Introduction to Stenciling: glStencilFunc glStencilFunc takes three parameters: A GLenum : what comparison the stencil test will do. A GLint used as a “reference value” in the stencil test. A GLuint used as a mask (an “and” mask). Think: REF COMPARE (buffer pixel & mask) Examples Stencil test passes if bit in SB is on: glStencilFunc(GL_EQUAL, 0x1, 0x1); Stencil test passes if bit in SB is off: glStencilFunc(GL_NOTEQUAL, 0x1, 0x1); Test passes if 20 < low 8 bits in SB: glStencilFunc(GL_LESS, 20, 0xff);

20 6 Feb 2004CS 481/68120 Introduction to Stenciling: glStencilOp glStencilOp takes three parameters, all GLenum ’s: Operation to perform if stencil test fails. Op. to perform if stencil test passes and depth test fails. Op. to perform if stencil test passes and depth test passes. Examples Replace the SB value with the reference value (from glStencilFunc ): glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); Do not modify the SB: glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); Replace SB value with zero, the reference value, or the bitwise inversion of the current SB value, respectively: glStencilFunc(GL_ZERO, GL_REPLACE, GL_INVERT); Increment or decrement the SB value, as appropriate: glStencilFunc(GL_DECR, GL_INCR, GL_INCR);


Download ppt "Jittering, Introduction to Stenciling Glenn G. Chappell U. of Alaska Fairbanks CS 481/681 Lecture Notes Friday, February 6, 2004."

Similar presentations


Ads by Google