EDIT: I found another post that fixed it: Depth normals pre-pass as an option, separate from SSAO, more details at bottom.
I’m having a bit of trouble understanding the new system, I’m trying to get the normal and/or depth output and copy it to a render texture to use later for a custom billboard shader. I’ve figured out how to pass in an existing render texture and copy the default color output to it but I can’t get a version using normals to work. I’ve also gotten depth using the color format but not through depth format.
None of the documentation I can find show how to use depth or normals. I’ve also looked at some of the samples including DepthNormalOnlyPass.cs but what I can find for the documentation doesn’t really cover much of it. I’ve been stuck on this for an entire week and would really appreciate a pointer or two.
//this is how I setup pass in my ScriptableRenderFeature
public override void SetupRenderPasses(ScriptableRenderer renderer,
in RenderingData renderingData)
{
if (renderingData.cameraData.cameraType == CameraType.Game)
{
CustomNormalPass.ConfigureInput(ScriptableRenderPassInput.Normal);
//CustomNormalPass.SetTarget(renderer.cameraColorTargetHandle);
//I haven't noticed if this actually does anything
CustomNormalPass.SetTarget(renderer.cameraDepthTargetHandle);
}
}
//renderPassEvent is also set to RenderPassEvent.AfterRenderingPrePasses which I think is correct
//which renders right after draw depth
//this part is in my ScriptableRenderPass
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
string passName = "DepthNormals To RenderTexture";
UniversalRenderingData renderingData = frameData.Get<UniversalRenderingData>();
UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
UniversalLightData lightData = frameData.Get<UniversalLightData>();
using (var builder = renderGraph.AddRasterRenderPass<PassData>(passName,
out var passData))
{
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
RTHandle rtHandle = RTHandles.Alloc(_outputRenderTexture);
TextureHandle textureToWrite = renderGraph.ImportTexture(rtHandle);
RenderTextureDescriptor desc = cameraData.cameraTargetDescriptor;
desc.msaaSamples = 1;
desc.depthStencilFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R32_SFloat;
desc.depthBufferBits = 32;
//using activeDepthTexture gives me "multisampled texture bound to non-multisampled sampler" error
//changing msaaSamples doesnt fix the multisampled error
//I dont know how to use cameraNormalsTexture
//I've only figured out how to use cameraDepthTexture
//passData.copySourceTexture = resourceData.cameraNormalsTexture;
//passData.copySourceTexture = resourceData.activeDepthTexture;
passData.copySourceTexture = resourceData.cameraDepthTexture;
builder.UseTexture(passData.copySourceTexture, AccessFlags.Read);
//I got depth color working with this earlier but not with SetRenderAttachmentDepth
//builder.SetRenderAttachment(textureToWrite, 0, AccessFlags.Write);
builder.SetRenderAttachmentDepth(textureToWrite, AccessFlags.Write);
builder.AllowPassCulling(false);
builder.AllowGlobalStateModification(true);
// Set the ExecutePass method as the rendering function that render graph calls
// for the render pass.
builder.SetRenderFunc((PassData data, RasterGraphContext context)
=> ExecutePass(data, context));
}
}
static void ExecutePass(PassData data, RasterGraphContext context)
{
Blitter.BlitTexture(context.cmd, data.copySourceTexture,
new Vector4(1, 1, 0, 0), 0, false);
}
And here is where im using the depthNormal texture in my shader
float depthValue; float3 normalValues;
DecodeDepthNormal(tex2D(_NormalTex, i.uv), depthValue, normalValues);
fixed4 testNormal = tex2D(_NormalTex, i.uv);
float4 depthColors = float4(depthValue, depthValue, depthValue, 1.0f);
float4 normalColors = float4(normalValues, 1.0f);
//all three just return black
return depthColors;
return normalColors;
return testNormal;
Here’s how I set up the render texture, I can have color or depth enabled but not both
I just found the solution, the problem was that depth pass was being used by default instead of the normal pass. If anyone else is having the same problem, add this code to the respective functions in your ScriptableRenderFeature
// Private Fields
private EnableDepthNormalsPass m_SSAOPass = null;
/// <inheritdoc/>
public override void Create()
{
// Create the pass...
if (m_SSAOPass == null)
{
m_SSAOPass = new EnableDepthNormalsPass();
}
}
/// <inheritdoc/>
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
bool shouldAdd = m_SSAOPass.Setup(renderer);
if (shouldAdd)
{
renderer.EnqueuePass(m_SSAOPass);
}
}
// The SSAO Pass
private class EnableDepthNormalsPass : ScriptableRenderPass
{
internal bool Setup(ScriptableRenderer renderer)
{
ConfigureInput(ScriptableRenderPassInput.Normal);
return true;
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
// Do Nothing - we only need the DepthNormals to be configured in the Setup method
}
}
This fixed the normals but now im getting “EnableDepthNormalsPass does not have an implementation of the RecordRenderGraph method” warning spammed, if anyone knows how to disable this warning or bypass it, let me know.