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