Buffers and Processing Fragments 2017 Autumn Animação e Visualização Tridimensional 2017/2018 1
OGL Framebuffer Color Buffers: (front back)- (left right) Depth Buffer Stencil Buffer 2
Buffers Intro Buffer n x m elements of k bits 3
Buffers Intro Clearing Buffers Define the clearing values: void glclearcolor(glclampf red, GLclampf green, GLclampf blue, Glclampf alpha); void glcleardepth(glclampd depth); void glcleardepthf(glclampf depth); void glclearstencil(glint s); Glclampf and Glclampd: [0, 1] Default values: depth-clearing is 1 and 0 for all the others Clear the specified buffer: void glclear(glbitfield mask); GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, and GL_STENCIL_BUFFER_BIT 4
Buffers Intro Masking the buffers: void glcolormask(glboolean r, GLboolean g, GLboolean b, GLboolean alpha); void gldepthmask(glboolean flag); void glstencilmask(glboolean mask); 5
OpenGL Pipeline Application GPU Data Flow Framebuffer Vertices Vertices Fragments Fragments Vertex Processing Assembly Rasterizer Interpolator Fragment Processing Tests and Blending Pixels Vertex Shader Fragment Shader 6
Fragments Operations Fragment tests Blend operations After these operations we get the pixels 8
Fragments tests In this order: Scissor test Culls fragments in a 2D box on screen Stencil test Restrict drawing to certain portions of the screen Compares value of stencil buffer with reference constant Culls fragments conditionally Can apply different operation to stencil value based on: Stencil-fail / S-pass & Z-fail / S-pass & Z-pass Operations: Set, increment, decrements, Depth test (visibility/occlusion test) Compares Z value with value from Z-buffer Culls fragments conditionally, otherwise updates Z-buffer 9
Blend Operations Merge fragments with color buffer content (pixels) Order of operations: Blending operations (aka. compositing) Weighted combination of fragment and pixel values Dithering operation Approximation of color by spatial averaging Different rounding based pixel location Half-Toning Logical operations 16 combinations of fragment and pixel values (NOT, AND, OR, XOR) 10
Scissor Test Window Coordinates (OpenGL API) void glscissor (GLint x, GLint y, GLsizei width, GLsizei height) GLint x, GLint y: lower left position 11
How to use stencil buffer? 1. glutinitdisplaymode(glut_stencil); 2. glenable(gl_stencil_test); 3. glclearstencil(0); 4. glclear(gl_stencil_buffer_bit); 12
Stencil Testing 1/2 void glstencilfunc( GLenum func, GLint ref, GLuint mask ); sets the function and reference value for stencil testing. func: test function, see next page. ref: reference value mask:a mask that is ANDed with both the reference value and the stored stencil value when the test is done. 13
Stencil Testing 2/2 param GL_NEVER GL_LESS GL_LEQUAL GL_GEQUAL GL_NOTEQUAL GL_ALWAYS Meaning Always fails. Passes if ( ref & mask) < ( stencil & mask). Passes if ( ref & mask) ( stencil & mask). Passes if ( ref & mask) ( stencil & mask). Passes if ( ref & mask)!= ( stencil & mask). Always passes. 14
Modify stencil buffer 1/2 void glstencilop( GLenum fail, GLenum zfail, GLenum zpass ); sets the actions to change the stencil buffer. fail: The action to take when the stencil test fails zfail: Stencil action when the stencil test passes, but the depth test fails. zpass: both the stencil test and the depth test pass 15
Modify stencil buffer 2/2 param GL_KEEP GL_ZERO GL_REPLACE GL_INCR GL_DECR GL_INVERT Meaning keep the current value set the value in stencil buffer to zero set the value in stencil buffer to ref in glstencilfunc() increase the current value in stencil buffer decrease the current value in stencil buffer bitwise inverse the current value in stencil buffer 16
Stencil buffer + Z buffer 17
Stencil buffer example 1/2 Void display(){ glenable(gl_depth_test); glenable(gl_stencil_test); glclearstencil(0x0); glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT); glstencilfunc(gl_always, 1, 1); glstencilop(gl_replace, GL_REPLACE, GL_REPLACE); DrawCube(16.0); // draw a blue cube glclear(gl_depth_buffer_bit); // init z_buffer glstencilop(gl_keep, GL_KEEP, GL_KEEP); glstencilfunc(gl_equal, 1, 1); DrawTeapot(8); // White Teapot glswapbuffers(); } 18
Stencil buffer example 2/2 19
Other example 1/2 Void display(){ glenable(gl_depth_test); glenable(gl_stencil_test); glclearstencil(0x0); glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT); glstencilfunc(gl_always, 0x1, 0x1); glstencilop(gl_replace, GL_REPLACE, GL_REPLACE); DrawCube(16.0); //Blue Cube desenhado glclear(gl_depth_buffer_bit); // incializa o z-buffer glstencilop(gl_keep, GL_KEEP, GL_INVERT); glstencilfunc(gl_equal, 0x1, 0x1); DrawTeapot(8); //White Teapot glstencilfunc(gl_notequal, 0x1, 0x1); glstencilop(gl_keep, GL_KEEP, GL_KEEP); PushMatrix(); gltranslatef(10, 0, 0); DrawSphere(); //Yellow Sphere PopMatrix(); glswapbuffers(); } 20
Other example 2/2 21
How to Use Blending? Remember to enable glenable(gl_blend); Set up blend function glblendfunc(, ) 22
Blending Equation We can define source and destination blending factors for each RGBA component s = [s r, s g, s b, s a ] d = [d r, d g, d b, d a ] Suppose that the source and destination colors are b = [b r, b g, b b, b a ] c = [c r, c g, c b, c a ] Blend as c = [b r s r + c r d r, b g s g + c g d g, b b s b + c b d b, b a s a + c a d a ] 23
OpenGL Blending and Compositing Must enable blending and pick source and destination factors glenable(gl_blend) glblendfunc(source_factor, destination_factor) Only certain factors supported GL_ZERO, GL_ONE GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA See Redbook for complete list 24
Blend Function 2/2 Constant RGB Blend Factor Alpha Blend Factor GL_ZERO (0, 0, 0) 0 GL_ONE (1, 1, 1) 1 GL_SRC_COLOR (Rs,Gs, Bs) As GL_ONE_MINUS_SRC_COLOR (1, 1, 1) (Rs,Gs, Bs) 1 As GL_DST_COLOR (Rd,Gd, Bd) Ad GL_ONE_MINUS_DST_COLOR (1, 1, 1) (Rd,Gd, Bd) 1 Ad GL_SRC_ALPHA (As, As, As) As GL_ONE_MINUS_SRC_ALPHA (1, 1, 1) (As,As,As) 1 As GL_DST_ALPHA (Ad,Ad, Ad) Ad GL_ONE_MINUS_DST_ALPHA (1, 1, 1) (Ad, Ad,Ad) 1 Ad GL_CONSTANT_COLOR (Rc,Gc, Bc) Ac GL_ONE_MINUS_CONSTANT_COLOR (1, 1, 1) (Rc,Gc, Bc) 1 Ac GL_CONSTANT_ALPHA (Ac, Ac,Ac) Ac GL_ONE_MINUS_CONSTANT_ALPHA (1, 1, 1) (Ac,Ac, Ac) 1 Ac 25
Example Suppose that we start with the opaque background color (R 0,G 0,B 0,1) This color becomes the initial destination color We now want to blend in a translucent polygon with color (R 1,G 1,B 1,a 1 ) Select GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA as the source and destination blending factors R 1 = a 1 R 1 +(1- a 1 ) R 0, Note this formula is correct if polygon is either opaque or transparent 26
Order Dependency Is this image correct? Probably not Polygons are rendered in the order they pass down the pipeline Blending functions are order dependent 27
Billboard texture mapping A billboard is a textured rectangle Sometimes called impostors Always aligned with the viewing direction Texture is static Fast to render: a single textured polygon versus many 28
Billboard texture mapping Need to remove texture background Two ways: Masking Alpha blending 29
Using Masking Billboard fragments alpha values are 0 or 1 (very rare) Draw billboard fragments with alpha equal to 1 in the fragment shader check the alpha channel of the fragment s color tell the fragment shader it shouldn't write any pixel: use discard statement. uniform float alpha_threshold; void main() { vec4 color =...; if(color.a <= alpha_threshold) // Or whichever comparison here discard; } colorout = color; 30
Using Blending Billboard fragments alpha values between [0, 1] 1. Discard fragments with alpha values equal to 0 (optional) 2. Blend the other fragments glblendfunc(gl_src_alpha, GL_ONE_MINUS_SRC_ALPHA) glenable(gl_blend) 31
Opaque and Translucent Polygons Suppose that we have a group of polygons some of which are opaque and some translucent. How do we use hidden-surface removal? Opaque polygons block all polygons behind them and affect the depth buffer Translucent polygons should not affect the depth buffer Render with gldepthmask(gl_false) which makes depth buffer read-only Sort polygons first to remove order dependency 32
3D Blending with the Depth Buffer Steps: Enable Depth Buffering Draw all the opaque objects (how?) Make the depth-buffer read-only (why?) Draw the translucent objects with blending. Figure out the correct order of rasterization 33
How to implement Fog? Classic OpenGL 2.0: glenable(gl_fog); Set up fog function glfogf(, ) Fog deprecated in OpenGL 3.1 Use shaders 34
Classic Fog Function 1/2 glfog{f,i}[v]{glenum pname, param} Pname param GL_FOG_MODE GL_LINEAR, GL_EXP, GL_EXP2 GL_FOG_DENSITY default : 1.0 GL_FOG_START default : 0.0 GL_FOG_END default : 1.0 GL_FOG_INDEX default : 0.0 GL_FOG_COLOR default : (0,0,0,0) 35
Fog Function 2/2 ColorOut = f C i + (1 - f ) C f where C i represents the incoming fragment's RGBA values and C f the fog-color values assigned with GL_FOG_COLOR. f fog amount: LINEAR: EXP: EXP2: 36
Exponential fog-density 37
Fog Implementation http://in2gpu.com/2014/07/22/createfog-shader/ Exponential Fog: vec3 applyfog( in vec3 rgb, // original color of the fragment in float distance ) // camera to point distance { float fogamount = exp( -distance*0.05 ); // clamp(fogamount, 0, 1.0); necessary only if linear vec3 fogcolor = vec3(0.5,0.6,0.7); vec 3 final_color = return mix(fogcolor, rgb, fogamount ); out_color = vec4(final_color, 1); } 38
Distance: Z-depth versus length Solution: use the length Plane-based: z-depth Fog start 39
Distance in Fog shader Vertex Shader: pos = view * model * vertex_position //in eye coordinates Fragment shader: //compute distance used in fog equations if(depthfog == 0)//select plane based vs range based { //plane based dist = abs(pos.z); //fragment depth in eye coordinates //dist = (gl_fragcoord.z / gl_fragcoord.w); } else { //range based dist = length(pos) //use it; } 40