Deceit in Depth
文章推薦指數: 80 %
If you do not write one, then OpenGL will happily use gl_FragCoord.z as the ... is always written to, no matter what conditional branches your shader uses. DeceitinDepthPrev Chapter 13. LiesandImpostors NextDeceitinDepth Whiletheperspectiveversionlooksgreat,thereremainsoneproblem.Movethetime arounduntiltherotatinggreysphereducksunderneaththeground. Figure 13.6. BadIntersection Hmm.Eventhoughwe'vemadeitlooklikeamathematicallyperfectsphere,itdoesnot actlikeonetothedepthbuffer.Asfarasitisconcerned,it'sjustacircle (remember:discardpreventsdepthwritesandtestsaswell). Isthattheendforourimpostors?Hardly. Partofthefragmentshader'soutputisadepthvalue.Ifyoudonotwriteone,then OpenGLwillhappilyusegl_FragCoord.zasthedepthoutputfromthe fragmentshader.Thisvaluewillbedepthtestedagainstthecurrentdepthvalueand,if thetestpasses,writtentothedepthbuffer. Butwedohavetheabilitytowriteadepthvalueourselves.Toseehowthisisdone, loadupthetutorial(usingthesamecodeagain)andpresstheHkey. Thiswillcauseallimpostorstousedepth-correctshaders. Figure 13.7. DepthCorrectImpostor Thisshaderisidenticaltotheraytracedversion,exceptfortheselinesinthe fragmentshader: Example 13.4. DepthCorrectFragmentShader Impostor(cameraPos,cameraNormal); //SetthedepthbasedonthenewcameraPos. vec4clipPos=cameraToClipMatrix*vec4(cameraPos,1.0); floatndcDepth=clipPos.z/clipPos.w; gl_FragDepth=((gl_DepthRange.diff*ndcDepth)+ gl_DepthRange.near+gl_DepthRange.far)/2.0; Basically,wegothroughtheprocessOpenGLnormallygoesthroughtocomputethe depth.Wejustdoitonthecamera-spacepositionwecomputedwiththeraytracing function.Thepositionistransformedtoclipspace.Theperspectivedivisionhappens, transformingtonormalizeddevicecoordinate(NDC)space.Thedepth rangefunctionisapplied,forcingthe[-1,1]rangeinthefragmentshadertotherange thattheuserprovidedwithglDepthRange. Wewritethefinaldepthtoabuilt-inoutputvariable gl_FragDepth. FragmentsandDepth ThedefaultbehaviorofOpenGLis,ifafragmentshaderdoesnotwritetothe outputdepth,thensimplytakethegl_FragCoord.zdepthasthe depthofthefragment.Oh,youcoulddothismanually.Onecouldaddthefollowing statementtoanyfragmentshaderthatusesthedefaultdepthvalue: gl_FragDepth=gl_FragCoord.z Thisis,intermsofbehavioranoop;itdoesnothingOpenGLwouldnothavedone itself.However,intermsofperformance,thisisadrastic change. Thereasonfragmentshadersarenotrequiredtohavethislineinallofthemis toallowforcertainoptimizations.IftheOpenGLdrivercanseethatyoudonotset gl_FragDepthanywhereinthefragmentshader,thenitcan dramaticallyimproveperformanceincertaincases. Ifthedriverknowsthattheoutputfragmentdepthisthesameasthegenerated one,itcandothewholedepthtestbeforeexecutingthe fragmentshader.Thisiscalledearlydepthtestor early-z.Thismeansthatitcandiscardfragments beforewastingprecioustimeexecutingpotentiallycomplex fragmentshaders.Indeed,mosthardwarenowadayshascomplicatedearlyzculling hardwarethatcandiscardmultiplefragmentswithasingletest. Themomentyourfragmentshaderwritesanythingto gl_FragDepth,allofthoseoptimizationshavetogoaway.So generally,youshouldonlywriteadepthvalueyourselfifyou reallyneedtodoit. Also,ifyourshaderwritesgl_FragDepthanywhere,itmust ensurethatitisalwayswrittento,nomatterwhatconditional branchesyourshaderuses.Thevalueisnotinitializedtoadefault;youeither alwayswritetoitornevermention“gl_FragDepth” inyourfragmentshaderatall.Obviously,youdonotalwayshavetowritethesame value;youcanconditionallywritedifferentvalues.Butyoucannotwritesomething inonepathandnotwritesomethinginanother.Initializeitexplicitlywith gl_FragCoord.zifyouwanttodosomethinglikethat. ForkmeonGitHubPrev Up NextCorrectChicanery Home PurloinedPrimitives
延伸文章資訊
- 1View Space From gl_FragCoord - Game Development Stack ...
Space & Sound? Defying Physics? 1 · Why are normal maps in tangent space but not in normal space?...
- 2gl_FragCoord.x, y, z being 1 for all pixels and w being the depth
w be representing depth information while gl_FragCoord.z is always 1.0 for all fragments? glsl th...
- 3OpenGL Insights - 第 552 頁 - Google 圖書結果
gl_FragCoord = gl_Position; Listing 39.1. ... In the pixel shader, the z-value is multiplied by 1...
- 4OpenGL 片元着色及輸出 - 台部落
gl_FragCoord 在片元着色器階段很有用, x, y 是窗口空間的值,單位是像素。如果用戶沒有寫入gl_FragDepth, z 值將被寫入, gl_FragCoord 是 1/Wcli...
- 5(gl_FragCoord.z / gl_FragCoord.w) for quick depth calculation ...
You can refer to chapter 2.13 “Coordinate Transformations” of OpenGL specs, and to the fact, that...