   A question about pixel shader and z-test
  Hi all,just a question. I'm using a pixel shader which implies a large amount of computations. Is the z-buffer test performed BEFORE entering the pixel shader code, of AFTER having computed the pixel color ?Because if it's done before, it has sense to do a render without lights, in order to later perform many computations only to the visible pixels.thanks, -Nicola   
  Direct3D doesn’t define the exact position for the Z test at the pipeline. But real hardware will do the z-test as soon as possible for performances reasons.  Therefore some games render most or all first in the z buffer only. The actual benefit of such a technique depends on your overdraw factor.   ;Quote:Original post by NiGoeaBecause if it's done before, it has sense to do a render without lights, in order to later perform many computations only to the visible pixels.You're right, you can optimize things by doing this. People apply this technique in two ways:1) Perform a render pass of the whole scene with z tests and z writes enabled as usual, but with color writes disabled. After this the actual rendering is done by enabling color writes, having z tests still on, but now disabling z writes (redundant). This is often called the 'depth pre-pass' method.2) In some cases, especially when doing traditional multi-pass rendering of several lights, the above method can be considered as being too much extra work. So some combine this depth pre-pass stage to also do the rendering of the ambient color of each object, and they don't disable color writes, but run the (very light) ambient shader in the depth prepass instead. The assumption being that the reduced draw calls and vertex shader invocations will outweigh any wasted shading of pixels in the presence of overdraw.As Demirug said, the actual stage when Z tests are done is not specified. For example, there's a D3D feature that you can choose to output a custom depth value from the pixel shader in addition to the pixel color. If your shader writes to the oDepth register, the pipeline can not compare the depths before invoking your PS, and must execute it. So what I think practically all cards do is that they run the per-pixel depth test before the PS if no oDepth is written, and afterwards if it is. This is why there can be a slight performance hit when using oDepth. I'd imagine that all cards do additional depth testing on triangle-level as well, right after invoking the vertex shader. The triangle z extents are compared against a hierarchical z pyramid of sorts. But that's just guessing, there's nothing really that would affect the "best practices" there..   ;  The Z test can be done anyway the IHV likes to do it, as long as it appears as if it happens after the shader as per my pipeline poster.So, as long as everything comes out with the same result as if the depth/stencil test happened after colors were computed, then everything is fine.  In practice, this means that IHVs have pipelines that are smart enough to notice that you don't do anything with depth in your pixel shader and therefore just take the depth generated by the rasterization stage.  This means that the Z test can take place before or concurrently with the pixel shader execution and if the depth test fails, the pixel shader execution can be aborted or skipped.If your pixel shader outputs depth for the source pixel, then you can't take this approach because the depth value used in the depth test is computed by the shader and therefore the shader must be executed.   ;  Thanks guys.So one can suppose the ztest is done after the rasterization stage, before calling the pixel shader.Quote:Original post by clbI'd imagine that all cards do additional depth testing on triangle-level as well, right after invoking the vertex shader. The triangle z extents are compared against a hierarchical z pyramid of sorts. But that's just guessing, there's nothing really that would affect the "best practices" there..The triangle-level test is something desirable. I implemented a similar algorithm called Hierarchical ZBuffer Visibility in my last software render engine. It worked very well. There, the hierarchic zbuffer is called Z-Pyramid.I read something about this as a native feature of  DirectX, but actually I dont now if it exists, neither how to use it.   ;Quote:Original post by NiGoea... There, the hierarchic zbuffer is called Z-Pyramid.I read something about this as a native feature of  DirectX, but actually I dont now if it exists, neither how to use it.I'm sure most GPUs do something like this. On older AMD cards I think it was marketed as the 'HyperZ' feature, or something similar (they had a few buzzwords for that).But yeah, it's not a feature that is exposed by D3D in any way to the programmer. The only mention about the z pyramids I've ever seen is that both nVidia and AMD recommend that you use the d3ddevice->Clear() instead of drawing a fullscreen quad to clear the depth buffer, since the former will clear the z pyramid (or whatever internal depth query acceleration structures they have) as well.   ;  Z testing is done after shading at least in the D3D pipeline. If you notice the minimum requirement for a fragment shader output is color, but it can also output Z value (DEPTH semantic) and fog (FOG semantic). This is why calculation intensive shaders use a Z-Pass to minimize pixel overwrite.   ;Quote:Original post by cgrantZ testing is done after shading at least in the D3D pipeline. If you notice the minimum requirement for a fragment shader output is color, but it can also output Z value (DEPTH semantic) and fog (FOG semantic). This is why calculation intensive shaders use a Z-Pass to minimize pixel overwrite.I wouldn't be that sure... today I did some tests using z-prepass, and they demonstrated that without z pass, the more overdraw the slow the rendering. With it, no matter how is the overdraw because the speed remains the same.And that observation can hold only if the z-test is done before to compute it's color via custom pixel shader.Anyway, I could be wrong.   