700 likes | 870 Views
2. Repetitorium. CG2LU SS2009. Institute of Computer Graphics and Algorithms Vienna University of Technology. Program. Frame buffer object (FBO) G ünther Voglsam (Vogi) Shadows Martin Knecht (Damartin) Animation basics Peter Houska (Husky) AI Mihał Domanski (Sulik).
E N D
2. Repetitorium CG2LU SS2009 Institute of Computer Graphics and Algorithms Vienna University of Technology
Program • Frame buffer object (FBO) • Günther Voglsam (Vogi) • Shadows • Martin Knecht (Damartin) • Animation basics • Peter Houska (Husky) • AI • Mihał Domanski (Sulik) <insert your name here>
Frame Buffer Object Günther Voglsam
What is an FBO? • FBO = Frame Buffer Object • “Normal” rendering: render to the screen • With FBO: render to a texture (with color and depth attachments) • This texture can be used in further passes, i.e., for shadow mapping, displaying a mini-map, showing different views of the scene, etc.
What is an FBO? (cont.) • FBO is an encapsulation of attachments • Attachments can be color- or renderbuffers • Renderbuffers are objects that support off-screen rendering without an assigned texture • Depth- and stencil-buffer • There can be up to 8 color attachments: • More than one is advanced stuff! • Number depends on your HW • Won’t deal with it too much
Setting up an FBO • Generating an FBO is done as usual in OpenGL: • First generate OpenGL-”name” • Then bind it to do something with it • GLuint fbo; // this will store our fbo-name • // generate fbo • glGenFramebuffersEXT(1, &fbo); • // bind FBO • glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
Setting up a renderbuffer • An FBO on it’s own isn’t much • Therefore: Attach renderable objects • So we want to add a depth buffer • Again, create name and bind it: • GLuint depthbuffer; // this will store our db-name • // create a depth-buffer • glGenRenderbuffersEXT(1, &depthbuffer); • // bind our depth-buffer • glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);
Creating storage-space • We didn’t create any storage for our render-buffer yet, so create it… • …and attach it to our FBO • // create storage for our renderbuffer • glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); • // attach renderbuffer to FBO • glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbuffer);
Attaching a texture to the FBO • To render to a texture, we first need one • We create it as usual • Note: width and height are the same as those for the FBO and renderbuffers! • // create a texture • GLuint img; • glGenTextures(1, &img); • glBindTexture(GL_TEXTURE_2D, img); • glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
Attaching a texture to the FBO (cont.) • Simply attach the texture to the FBO • // attach texture to fbo • glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0);
Status checking • Check, if the creation worked out correctly • See specification for detailed error-codes • // fbo-creation error-checking • GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); • if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { • // error • }
Rendering to texture • Bind FBO – render scene – unbind FBO • Note: need to set viewport for FBO (and restore old one if needed)! • // bind fbo • glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); glPushAttrib(GL_VIEWPORT_BIT); • glViewport(0, 0, width, height); • // render something here • // unbind fbo • glPopAttrib(); • glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
Using the rendered to texture • Just bind it like a regular texture • Note: If you want to create MIP-maps from it, use glGenerateMipmapEXT(...)! (For more see GameDev[1].) • // bind texture • glBindTexture(GL_TEXTURE_2D, img);
Cleaning up • If FBO is not needed anymore, delete it • Delete also all with the FBO associated renderbuffers and textures! • // delete fbo • glDeleteFramebuffersEXT(1, &fbo); • // delete renderbuffer • glDeleteRenderbuffersEXT(1, &depthbuffer); • // delete texture • glDeleteTextures(1, &img);
That’s all? • With an FBO, you can render into more than one texture simultaneously • For more check the tutorials at www.gamedev.net • [1] http://www.gamedev.net/reference/programming/features/fbo1/ • [2] http://www.gamedev.net/reference/programming/features/fbo2/
Shadows Martin Knecht
Why shadows? • Shadows tell us about the relative locations and motions of objects • and about light positions
Shadow mapping • 1st pass: render from light; save depth in texture (“shadow map”) • 2nd pass: render fromeye: • Transform all fragments to light space • Compare zeye and zlight (both in light space!!!) • zeye> zlight fragment in shadow
1st Pass: Render Shadow Map • Create a FBO and setup as Rendertarget • Setup the “view” matrix for the light – similar to the view matrix of the camera • //createthetexturewe'llusefortheshadowmapglBindTexture(GL_TEXTURE_2D, shadow_tx);glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, SMwidth, SMheight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); • glGenFramebuffersEXT(1, &framebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D,shadow_tx, 0);glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); • //BeforerenderingglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fb);
1st Pass: Render Shadow Map • Note: No projection matrix used up to now! • Turn off all effects when rendering the shadow map • No textures, lighting, etc. • p‘ = Plight * Vlight * M * p = Plight * ModelViewlight * p
2st Pass: Render scene from Camera • We also need the coordinates in the light space • Several ways to get them! • One way: Use inverse view matrix of camera: Vcam-1!
2st Pass: Render scene from Camera • Calculate p‘ (camera view) as usual • p‘ = Pcam * Vcam * M * p = Pcam * ModelViewcam * p • Also transform vertices into light space and save them in texture coordinates • plightspace = (Plight * Vlight * Vcam-1) * ModelViewcam * p
2st Pass: Render scene from Camera • plightspace is in the interval [-1…..+1] • Shadowmap coordinates in range [0….+1] • Scaling/Translation necessary (*0.5, +0.5) • SMtexcoords = (Mtranslate*Mscale*Plight*Vlight*Vcam-1)* ModelViewcam * p
Shadow Mapping: Vertex Shader • Vertex Shader: gl_TextureMatrix = (Mtranslate*Mscale*Plight*Vlight*Vcam-1) voidmain(void) { //standardtransformation gl_Position = ftransform(); //shadowtexturecoordinates in lightfragmentspace gl_TexCoord[0] = gl_TextureMatrix*gl_ModelViewMatrix* gl_Vertex; }
Shadow Mapping: Fragment Shader • Fragment Shader: uniform sampler2D texShadow; voidmain(void) { //Note theperspectivedivision! vec3 texCoords = gl_TexCoord[0].xyz/gl_TexCoord[0].w; floatdepth = tex2D(texShadow, texCoords.xy).x; floatinShadow = (depth < texCoords.z) ? 1.0 : 0.0; //do somethingwiththatvalue…… }
gl_TextureMatrix generation • Generation of the texture matrix: thx 2 rodriguez glMatrixMode(GL_TEXTURE); glLoadIdentity(); glTranslatef(.5f, .5f, .5f); glScalef(.5f, .5f, .5f); glMultMatrixf(Plight); glMultMatrixf(Vlight); glMultMatrixf(Vcam-1);
Artifacts • Add Offset to polygons when rendering shadow map glPolygonOffset(1.1, 4.0); //works well
Artifacts • Decrease ambient term • Filter shadow map
Filter shadow map • Nvidia does depth compare in hardware • and also PCF! glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Shadow Mapping: Fragment Shader • Fragment Shader for Hardware PCF: uniform sampler2DShadowtexShadow; voidmain(void) { floatshadow = shadow2DProj(texShadow, gl_TexCoord[0]).x; //do somethingwiththatvalue…… }
Character Animation Basics Peter Houska
Character Animation • Key-Frame • “snapshot” of the character at some moment • Key-Frame based animation • Which parameter is interpolated ? • Skeletal animation • Vertex animation • Vertex Skinning (a.k.a. matrix palette blending)
Key-Frame Interpolation 39 • 3D artist models “key frames” • Key frames are important poses • standing, running, firing, dying etc. • Application then interpolates poses in between • Always 2 key frames involved • Several types of interpolation • linear, quadratic, ... • Linear interpolation fast and usually good enough
Key-Frame Interpolation 41 • All key frames must have • Same number of vertices • Same vertex connectivity
Key-Frame Interpolation 42 • Basic steps: • Determine two “current” key frames A and B • Determine weighting factor w [0,1] • Whenever w >= 1.0 • w -= 1.0 • make key frame B new “start key frame” • determine new “end key frame” • Blend the corresponding key frames • Per-vertex • Don’t forget the normal vectors!
Key-Frame Interpolation • uniform float weightingFact; • void main() • { • vec4 keyFrameA_vert = gl_Vertex; • vec3 keyFrameA_norm = gl_Normal; • // use built-in “vertex attribute-slots” to pass • // necessary data • vec4 keyFrameB_vert = gl_MultiTexCoord6; • vec3 keyFrameB_norm = gl_MultiTexCoord7; • ... 43 • Vertex Shader:
Key-Frame Interpolation • ... • // linear interpolation: • // blendedPos_vert = • // (1.0 – weightingFact) * keyFrameA_vert + • // weightingFact * keyFrameB_vert • vec4 blendedPos_vert = mix(keyFrameA_vert, keyFrameB_vert, • weightingFact); • vec4 blendedPos_norm = mix(keyFrameA_norm, keyFrameB_norm, • weightingFact); • ... 44 • Vertex Shader:
Key-Frame Interpolation • ... • // normalize blended normal and maybe • // perform some light computation with the • // normal (here, the normal is still in object • // space!) • vec3 normal = normalize(blendedPos_norm); • // pass texture coordinates as always • gl_TexCoord[0] = gl_MultiTexCoord0; • // transform blended vertex to homogeneous clip space • gl_Position = • gl_ModelViewProjectionMatrix*blendedPos_vert; • } 45 • Vertex Shader:
Key-Frame Interpolation 46 • Advantages • Simple to implement • Disadvantages • High storage requirements • No dynamic “arbitrary” poses
Vertex Skinning • Character model consists of • Single default pose • A polygonal mesh (made of vertices) • ...the “skin“ • Several “bones“ • Matrices that translate and rotate default pose‘s vertices • Define coarse character structure • Like a stick-figure
Vertex Skinning • Real life analogy: • As bones move, skin moves appropriately • But: influence of bones locally bounded • Moving left arm does not affect right leg • Bone set • Matrices that actually influence a vertex • Typically contains <= 4 matrices • Each matrix Mi has associated weight wi
Vertex Skinning • Matrix-weight determines how much it influences a vertex‘s position Bone Polygonal mesh = „skin“ At this vertex, 3 matrices in bone set with corresponding weights: 60% forearm matrix 30% elbow matrix 10% upper arm matrix