- Home /
Setting depth buffer per-fragment
Hi, what I'm trying to do is simple in theory, but in practice I do not know how to go about it.
I wrote a nice steep parallax mapping shader that allows me to make materials that make a basic Unity cylinder look like this:
My issue is that the parallax mapping is so steep that when I try to place things next to the surface (especially if I am using this shader for the ground and need to place, say, chairs or other objects "on the ground"), the things start to intersect the surface's base geometry instead of my displaced surface.
The standard pipeline for shaders is, as far as I know:
Vertex Shader -> Depth Write/Test -> Fragment Shader
Is there any way, short of disabling all depth test and making my own depth buffer out of a render texture (with blackjack and hookers) that I can write to the depth buffer per-fragment in the second stage so that my bumpy wall can properly intersect other objects in the scene? I'm using a Surface Shader but I do not mind going back to the old shader model to do this.
-edit-
Here is the intersection problem I am facing (for which I am trying to find a way to draw to the depth buffer):
for Futurama reference and stunning effect. Hope you are going to share/sell this.
I will share/sell this at some point, perhaps. I'm actually looking to write a series of tutorials for Unity shader-writing so that people can learn to do this sort of thing themselves too.
Would love to have those tutorial on Unity Gems if you want to post/cross post there - a lot of traffic...
Answer by whydoidoit · Apr 20, 2013 at 09:13 PM
This is one of those examples of why we need geometry shaders I guess. I concur, it's not easy to do that.
The only thing I can think of is rendering the depth as a render texture and then reading from that with your shader very late in the queue.
Answer by DemianSPb · Mar 28, 2017 at 07:18 AM
at least in Unity 5.4+ it's possible:
// inside CGPROGRAM
struct FragmentOutput
{
fixed4 color : COLOR;
half depth : DEPTH;
};
FragmentOutput frag(VertexOutput i) {
FragmentOutput output;
output.color = ...;
output.depth = (1.0 / worldSpaceDepth - _ZBufferParams.w) / _ZBufferParams.z;
return output;
}