Shadow Algorithms

Transcription

Shadow AlgorithmsHan-Wei Shen

Wh Shadows?WhySh d? Makes 3D Graphics more believableProvides additional cues for the shapes andrelativel ti positionsitioff objectsbj t iin 3D

Wh t isWhati shadow?h d ? Shadow: comparativedarkness given byshelter from direct light;patch of shadeprojected by a bodyintercepting light

TTerminologyi l(area) light sourceoccluder umbra – fully shadowed region penumbra – partially shadowed regionpenumbrapumbrashadowreceiver

“H d” and“Hard”d “Soft”“S ft” ShadowsSh d DDependsd on ththe ttype off lilightht sources Point or Directional (“Hard Shadows”, umbra)point directionalareaArea (“Soft Shadows”, umbra, penumbra),more difficult problem

“Hd” andd “Sft” Shd“Hard”“Soft”ShadowsHard shadowSoft shadow– point light source– area light source

Simple Approach: Ray tracing Cast ray to light(shadow rays)Surface point inshadow if the shadowrays hits an occluderobject.Ray tracing is slow, canwe do better? (perhapsat the cost of quality)

Sh dShadowAlAlgorithmsith We will first focus on hard shadows Planar ShadowsShadow MapspShadow Volume

PlPlanarShadowsSh d yThe simplest algorithm – shadowing occurswhen objects cast shadows on planarsurfaces (projection shadows)lightshadowy 0ylightshadown.x d 0

PlPlanarShadowsSh d Special case: the shadow receiver is an axisplane Just project all the polygon vertices to thatplane and form shadow polygonslightyvGiven:Gien- Light position l- Plane position y 0- Vertex position vCalculate: pshadowpy 0

PlPlanarShadowsSh d We can use similar triangles to solve plpx-lxvx-lxlightyv lyly-vyly vx – lx vypx shadowpy 0xly - vy Same principle applied to different axis planes

PlPlanarShadowsSh d How about arbitrary plane as the shadowreceiver?Plane equation: n.xnx d 0llightyorax by cz d 0where n (a,b,c) - plane normalvshadowh dn.x d 0pAgain given light position l , vAgain,Find p

PlPlanarShadowsSh d Finding pW know:Wekp l (v-l)( l) x Also we know: n.pp d 0Because p is on the planellightyWe can solve easily:vd n.lnlshadowh dp l n.x d 0p(v - l)n. (v – l)

IIssuesaboutb t planarlshadowsh d Shadow polygon generation (z fighting) Shadow polygons fall outside the receiver UsingUi stencilil bbufferff – drawdreceiveriandd updatedtheh stencililbufferShadows have to be rendered at each frame Add an offset to the shadow polygons (glPolygonOffset)Draw receivers first,, turn z-test off,, then draw the shadowpolygons. After this, draw the rest of the scene.Render into textureRestrictive to planar objects

IIssuesaboutb t planarlshadowsh d Anti shadows and false shadowsAnti-shadowscorrectanti-shadowfalse shadow

Sh dShadowVolumesV l A more general approach for receivers thathave arbitrary shapes

Wh t isWhati shadowh dvolume?l? A volume of space formed by an occluderBounded by the edges of the occluderAny object inside the shadow volume is in shadowlight source

2D Cutaway of a ShadowVolumeShadowingobjectLightsourceEye positionEiti(note thatPartiallyshadows areshadowedi dindependentd t offobjectbj tthe eye position)Surface outsideshadow volume(illuminated)Shadowvolume(infinite extent)Surface insideshadow volume(shadowed)

I ShadowInSh dor not?t? Use shadow volume to perform such a testHow do we know an object is inside the shadowvolume?11.2.3.4.5.Allocate a counterCast a ray into the sceneIncrement the counter when the ray enter a front-facingpolygon of the shadow volume (enter the shadow volume)Decrement the counter when the ray crosses a backfacing polygon of the shadow volume (leave the shadowvolume))When we hit the object, check the counter. If counter 0 ; in shadow Otherwise - not in shadow

CCountert ffor ShShadowdVolumeV lLightsourceShadowing objectzero 1zero 2Eyeposition 1 2 3In shadow

R l tiRealtime shadowh dvolumel How can we render the idea of shadow volume inreal time? Use OpenGL Stencil buffer as the counterStencil buffer? Similar to color or depth buffer, except it’s meaning iscontrolled by application (and not visible)Part of OpenGL fragment operation – after alpha testbefore depth testControl whether a fragment is discarded or not Stencil function (Stencil test) - used to decide whetherto discard a fragment Stencil operation – decide how the stencil buffer isupdatedpas the result of the test

StStencilil FunctionFti Comparisonptest between reference and stencil value GL NEVER always fails GL ALWAYS always passes GL LESS passes if reference value is less than stencil buffer GL LEQUALGL LEQUAL passes if reference value is less than or equal to stencilbuffer GL EQUAL passes if reference value is equal to stencil buffer GL GEQUAL passes if reference value is greater than or equal tostencil buffer GL GREATER passes if reference value is greater than stencil buffer GL NOTEQUAL passes if reference value is not equal to stencil bufferIf the stencil test fails, the fragment is discarded and the stencil operationsassociated with the stencil test failingfis applied to the stencil valueIf the stencil test passes, the depth test is applied If the depth test passes, the fragment continue through the graphicsg ispipeline, and the stencil operation for stencil and depth test passingapplied If the depth test fails, the stencil operation for stencil passing but depthfailing is applied

StStencilil OperationOti Stencil Operation: Results of Operation on StencilValues GL KEEP stencil value unchangedGL ZERO stencil value set to zeroGL ZEROGL REPLACE stencil value replaced by stencil referencevalueGL INCR stencil value incrementedGL INCRGL DECR stencil value decremented GL INVERT stencilvalue bitwise invertedRemember you can set different operations for Stencil failsStencil passes, depth failsStencil passespasses, depth passes

OOpenGLGL forf shadowh dvolumesl Z-passZpass approachZ-fail approachIdeas used by both of the algorithms are similar Z-pass: see whether the number of visible front-facingshadow volume polygons and the number of visible backfacing polygons are equal. If yes – objects are not in shadowZ-fail: see whether the number of invisible back-facingshadow volume ppolygonsygand the number of invisible frontfacing polygons are equal. If yes – objects are not in shadow

ZZ-passapproachh Render visible scene with only ambient and emssion andupdate depth bufferTurn off depth and color write, turn on stencil (but still keepthe depth test on)Init. stencil bufferDraw shadow volume twice using face culling 1st1 t pass: renderd frontf t facesfandd incrementit stenciltil bbufferffwhen depth test passes 2nd pass: render back faces and decrement when deptht t passesteststencil pixels ! 0 in shadow, 0 are litRender the scene again with diffuse and specular whenstencil pixels 0

P blProblemsoff Z-passZalgorithmlith1 When the eye is in the shadow volume1. Counter 0 does not imply out of shadowanymoreIn this case, the stencil buffer should be init. withthe number of shadow volumes in which the eyeyis in (instead 0)2. When the near pplane intersects with theshadow volume faces (and thus will clip thefaces)

ZZ-passalgorithmlith problembl illustrationlightneareyeyfarMistakenly determined as not in shadow

Z f il approachZ-failh RenderRd visiblei ibl scene tto ddepthth bbufferffTurn off depth and color, turn on stencilInit. stencil buffer given viewpointDraw shadow volume twice using face culling 1st pass: render back faces and increment whendepth test fails2nd pass: render front faces and decrement whendepth test failsstenciltil pixelsi l !! 0 iin shadow,h d 0 are lit

P blProblemoff z-failf il algorithmlith Shadow volume can penetrate the far planeDepth clamping Solution: depth clamping - close up the shadowvolume

Sh dShadowMapM Basic idea: objects that are not visible to thelight are in shadowHHowtto determined ti whetherh th an objectbj t arevisible to the eye? Use zz-bufferbuffer algorithm,algorithm but now the “eye” is lightlight,i.e., the scene is rendered from light’s point ofviewThis particular z-buffer for the eye is calledshadow map

Sh dShadowMMap AlAlgorithmith illustration

Sh dShadowMMap AlAlgorithmith11.2.3.Render the scene using the light as thecamera and perform z-bufferingGGeneratet a lightli ht z bufferb ff (called( ll d shadowh dmap)R d thRenderthe scene usingi ththe regularl camera,perform z-buffering, and run the followingsteps: (next slide)

Sh dShadowMMap AlAlgorithmith (cont’d)For each visible fragment with [x[x,y,z]y z] inloccal space, perform a transformation tothe light’slight s clip space (light as the eye)[x1,y1,z1]3 2 Compare z1 with z shadow3.2shadow map[x1,y1]map[x1 y1]313.1- If z1 z (closer to light), then the pixel inquestion is not in shadow; otherwise thefragment is shadowed

1st PassView from lightDepth Buffer (shadow map)

2nd PassVisible surface depth

2nd PassFinal ImageNon-green in shadow

Shadow Maps WithOpenGL/GLSL Render scene using the light as a cameraRender the depth buffer into a 2D texture.We now have a depth texture.Render the scene using the real camera Pass the transformation matrices as before to yourshader (modelview, modelview projection, etc) Pass one more matrix: ShadowMatrix ShadowMatrix is to transform the vertices fromlocal space to light’s clip space Multiplyp y yyour vertex ppositions byy the ShadowMatrixto get the texture coordinates into the shadow map

R d depthRenderd th intoi t a texturet tvoid Init FBO() {glTexParameterfv(GL TEXTURE 2D,lT Pt f (GL TEXTURE 2DGL TEXTURE BORDER COLOR, border);glGenFramebuffers(1, &shadowFBO);glBindFramebuffer(GL FRAMEBUFFER, shadowFBO);glTexParameteri(GL TEXTURE 2D,GL TEXTURE COMPARE MODE,GL COMPARE REF TO TEXTURE);glTexParameteri(GL TEXTURE 2D,GL TEXTURE COMPARE FUNC, GL LESS);GLfloat border[] {1.0f, 0.0f, 0.0f, 0.0f};GLuint depthTex;glGenTextures(1, &depthTex);glActiveTexture(GL TEXTURE0);glBindTexture(GL TEXTURE 2D, depthTex);glDrawBuffer(GL NONE);glReadBuffer(GL NONE);glTexImage2D(GL TEXTURE 2D, 0, GL DEPTH COMPONENT24,512,512, 0, GL DEPTH COMPONENT, GL FLOAT, NULL);glTexParameteri(GL TEXTURE 2D, GL TEXTURE MAG FILTER,GL NEAREST);glTexParameteri(GL TEXTURE 2D, GL TEXTURE MIN FILTER,GL NEAREST);glTexParameteri(GL TEXTURE 2D, GL TEXTURE WRAP S,GL CLAMP TO BORDER);glTexParameteri(GL TEXTURE 2D, GL TEXTURE WRAP T,GL CLAMP TO BORDER);glFramebufferTexture2D(GL FRAMEBUFFER,GL DEPTH ATTACHMENT, GL TEXTURE 2D, depthTex, 0);// check FBO statusGLenum FBOstatus glCheckFramebufferStatusEXT(GL FRAMEBUFFER);glCheckFramebufferStatusEXT(GL FRAMEBUFFER);if(FBOstatus ! GL FRAMEBUFFER COMPLETE)printf("GL FRAMEBUFFER COMPLETE failed,CANNOT use FBO\n");glBindFramebuffer(GL FRAMEBUFFER, 0); // go back to the defaultframebuffer}

Sh dShadowMatrixM ti Shadow Matrix B * PL * VL * MPL : Light’s projection matrixVL: Light’s view matrixM: Object’s model matrixB: change the range from [-1,1] to [0,1]

Sh dShadowMapM LookL k up Multiply the shadow matrix to the vertex’svertex slocal coordinate position - [s,t,r,w]PPasstheth resultlt tot theth fragmentft shaderh dIn the fragment shader Perform perspective division [s,t,r,w]/wUse (s/w, t/w) to look up the shadow mapCComparer/w/ withi h theh valuel stores iin theh shadowh dmapIf r/w is closer (smaller),(smaller) fragment is not in shadowOtherwise it is in shadow

Generate texture coordinatest llooktok up shadowh dmap Goal: compare the fragment’sfragment s distance to the light to thevalue stored in the corresponding position in the shadowmapMajor steps: Map the fragment’s position to the light’s projection (clip) spaceGenerate texture coordinates (s(s,t,r)t r) to look up the shadow mapCompare the fragment’s depth value in the light’s clip space tothe value stored in the shadow mapThe fragment is not in shadow if the depth value is less than orequal to the value stored in the shadow mapuniform sampler2DShadow ShadowMap;vec4 texC ShadowCoord;float shadow shadow2DProj(ShadowMap, texC).x;gl FragColor v color*shadow;

Sh dShadowmap issuesi Shadow quality depends on Shadow map resolution – aliasing problemZ resolution – the shadow map is often stored inone channel of texture, which used to be only 8bits,, but now most of hardware supportspp24 bitsSelf-shadow aliasing – caused by different samplepositions in the shadow map and the screen

Sh dShadowmap aliasingli iproblembl The shadow looks blocky – when one singleshadow map pixel covers several screenpixelsThis is a problem similar to texturemagnification

Percentage Closer Filtering Could average binary results of all depth mappixels coveredSoft anti-aliased shadows

Increment the counter when the ray enter a front-facing polygon of the shadow volume (enter the shadow volume)polygon of the shadow volume (enter the shadow volume) 4. Decrement the counter when the ray crosses a back-facing polygon of the shadow volume (leave the sha