I’m using the built-in render pipeline and command buffers and I’m familiar with all the those setups.
My setup:
I am rendering in forward with a single directional light with shadows. Because of that, Unity starts by rendering a depth pass, no matter what setting I choose, because it needs it for shadows. In that setup, the frame debug tool says Unity renders the depth during DepthPass.Job which uses the ShadowCaster pass of the material with the SHADOWS_DEPTH keyword. However, for some reason, the actual return value of the function seems irrelevant – SHADOW_CASTER_FRAGMENT always returns 0 if we are simply rendering a directional light. Thus the return value is not the depth. I’m not sure where the depth value comes from.
What I want:
I’d like to get high-definition normals data, but I also want to avoid enabling DepthNormals, because that causes Unity to render the scene a third time, and I can’t live with the performance cost.
I’d also like to avoid normals reconstruction from depth in post, because it causes too many artifacts. This is what I currently do, but it causes noticeable faceting on smooth surfaces and edge artifacts on sharp depth changes.
My attempt: (Doesn’t work)
I tried to render normals in the ShadowCaster pass, which is according to the debugger the hook where Unity renders the depth, by setting up a secondary render target using command buffers.
To do so, I put this in CameraEvent.BeforeDepthTexture:
myCommandBuffer.SetRenderTarget(new RenderTargetIdentifier[] { BuiltinRenderTextureType.Depth, myNormalsTexture }, BuiltinRenderTextureType.Depth);
And in my shader, roughly:
struct f2a
{
float4 depth : SV_TARGET0;
fixed4 normals : SV_TARGET1;
};
f2a frag(v2f i)
{
f2a o;
o.depth = 0; // SHADOW_CASTER_FRAGMENT(i) returns 0 anyway for directional
o.normals = fixed4(0,1,1,1); // Test, can't see this being rendered in the frame debugger
return o;
}
First, the command buffer call registers as a clear, and I’m not too sure why:
Then, and main problem, the render targets don’t seem to actually have been assigned during DepthPass.Job:
Can I make this work somehow? Should I envision a different approach completely?