opengl - Bind pre rendered depth texture to fbo or to fragment shader? -
in deferred shading framework, using different framebufer objects perform various render passes. in first pass write depth_stencil_attachment whole scene texture, let's call depthstenciltexture. access depth information stored in depthstenciltexture different render passes, use different framebuffer objects, know 2 ways:
1) bind depthstenciltexture shader , access in fragment shader, depth manually, this
uniform vec2 winsize; //windows dimensions vec2 uv=gl_fragcoord.st/winsize; float depth=texture(depthstenciltexture ,uv).r; if(gl_fragcoord.z>depth) discard; i set gldisable(gl_depth_test) , gldepthmask(gl_false)
2) bind depthstenciltexture framebuffer object depth_stencil_attachment , set glenable(gl_depth_test) , gldepthmask(gl_false) (edit: in case won't bind depthstenciltexture shader, avoid loop feedback, see answer nicol bolas, , if need depth in fragment shader use gl_fragcorrd.z)
in situations, such drawing light volumes, need stencil test , writing stencil buffer, going solution 2). in other situations, in ignore stencil, , need depth stored in depthstenciltexture, option 1) gives advantages on more "natural" option 2) ?
for example have (silly, think) doubt . in fragment shaders icompute worldposition depth. in case 1) this
uniform mat4 invpv; //inverse pv matrix vec2 uv=gl_fragcoord.st/winsize; vec4 worldposition=invpv*vec4(uv, texture(depthstenciltexture ,uv).r ,1.0f ); worldposition=worldposition/worldposition.w; in case 2) (edit: wrong, gl_fragcoord.z current fragment's depth, not actual depth stored in texture)
uniform mat4 invpv; //inverse pv matrix vec2 uv=gl_fragcoord.st/winsize; vec4 worldposition=invpv*vec4(uv, gl_fragcoord.z, 1.0f ); worldposition=worldposition/worldposition.w; i assuming gl_fragcoord.z in case 2) same texture(depthstenciltexture ,uv).r in case 1), or, in other words, depth stored in the depthstenciltexture. true? gl_fragcoord.z read bound depth_stencil_attachment gldisable(gl_depth_test) , gldepthmask(gl_false) ?
going strictly opengl specification, option 2 is not allowed. not if you're reading texture.
yes, realize you're using write masks prevent depth writes. doesn't matter; opengl specification quite clear. in accord 9.3.1 of opengl 4.4, feedback loop established when:
an image texture object t attached bound draw framebuffer object @ attachment point a
the texture object t bound texture unit u, and
the current programmable vertex and/or fragment processing state makes possible (see below) sample texture object t bound texture unit u
that case in code. technically have undefined behavior.
one reason undefined changing write masks won't have things clearing framebuffer and/or texture caches.
that being said, can away option 2 if employ nv_texture_barrier. which, despite name, quite available on amd hardware. main thing here issue barrier after of depth writing, subsequent reads guaranteed work. barrier of cache clearing , such need.
otherwise, option 1 choice: doing depth test manually.
i assuming gl_fragcoord.z in case 2) same texture(depthstenciltexture ,uv).r in case 1), or, in other words, depth stored in the depthstenciltexture. true?
neither true. gl_fragcoord coordinate of fragment being processed. fragment generated rasterizer, based on data primitive being rasterized. has nothing contents of framebuffer.
Comments
Post a Comment