I’m curious if the built in pipeline’s Camera Normals Texture feature will be added later to the universal render pipeline. I’m mostly using it for a Sobel filter but I know its also useful for an number of other post processing effects.
I found an solution for a renderer feature that adds one here Redirecting… ,
But Going through the trouble of setting up a global texture using a shader in hidden/internal seems like an awkward solution to a problem that should probably have built in solution considering how useful Camera normal textures seem to be.
Also if any one had a more elegant solution for retrieving the normals of a pixel on camera I’d really appreciate it
If you have a renderer feature you can call ConfigureInput(ScriptableRenderPassInput.Normal);
And it will generate a prepass providing you with the texture. And then in your shader have this include: #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"
How do you use it without scripts? I have custom shader, I added “DepthNormals” pass from Lit to my custom shader. Then in another shader I sample from _CameraNormalsTexture using SampleSceneNormals, but I allways get empty data, no sceen normals (red color). Also when I use Lit shader on objects I still cant get anithing from SampleSceneNormals. Am I should enable it somewhere?
I am very happy that I found this thread. I needed access to the CameraNormalsTexture for the normal direction masking of some amplify decal projectors. I duplicated the SSAO renderer feature and stripped everything away except for the ConfigureInput line which results in a renderer feature that triggers rendering to the CameraNormalsTexture and absolutely nothing else (and does not add more draw calls or sth similar if SSAO is used).
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
[DisallowMultipleRendererFeature]
[Tooltip("The Scene Normals pass enables rendering to the CameraNormalsTexture if no other pass does it already.")]
internal class SceneNormals : ScriptableRendererFeature
{
private SceneNormalsPass m_SceneNormalsPass = null;
public override void Create()
{
if (m_SceneNormalsPass == null)
{
m_SceneNormalsPass = new SceneNormalsPass();
}
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
m_SceneNormalsPass.Setup();
renderer.EnqueuePass(m_SceneNormalsPass);
}
// The Scene Normals Pass
private class SceneNormalsPass : ScriptableRenderPass
{
public void Setup()
{
ConfigureInput(ScriptableRenderPassInput.Normal); // all of this to just call this one line
return;
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { }
}
}
One issue I’m having is that when I use this, terrain has issues with the depth buffer. This is how it should look like (water shader accesses depth buffer to render foam)
But with that feature added, the foam is gone. Would you have any idea why this happens? (only happens for terrain)
So I tried figuring that out but I think I really only have like a semi 80% ish good answer unfortunately.
I made that script based on the urp version in unity 2021.2 and I believe the depth normals texture is not really considered production ready outside of the ssao effect and maybe decals (which in that version were not final either).
I rewrote the following part 3 times now because everytime I thought “this is the reason” I realized it was something else.
Good news it does work. Bad news it’s a bit annoying.
As I noticed that the Stylized Water Asset does not support 2021 yet I hence checked this in 2020.3.34f1 in the “Water Demo” scene. First of all _CameraDepthTexture seems to be renamed to _CameraDepthAttachment in 2021.2, fine.
But switchting between Depth and DepthNormals as source for SSAO either renders a DepthPrePass or has no specific draw calls for depth normals at all… at first… until I enabled shadows on the Directional Light once and set the Floor Material to URP/Lit (instead of Unlit), since then the DepthNormalsPrePass gets executed correctly and foam and other depth effects show up.
The shadow part is probably irrelevant what isn’t is that Unlit shaders don’t have a depthNormals pass and since no shader has one the draw calls don’t show up at all. So if you want to use the depthNormals Texture all shaders that would write to it have to support it as well, there is no fallback to depthOnly.
Random side note: DepthNormals texture is not getting MSAA in 2021.2 if you don’t have Depth Priming enabled but that is by default on in lower versions it seems.
You add the renderer feature and then in your shader graph you need to sample the globally declared _CameraNormalsTexture (the name and reference needs to match this exactly).
Edit: Oh an be aware that the _CameraNormalsTexture contains worldspace normals, you might need to transform those into object / tangent space depending on what you want to do.
ehhh I know the feeling very well, hits me every day too. I guess thats normal if you work on something you haven’t done exactly like this before.
The camera normals texture stuff behaves very similarly like you would access this in the built in pipeline, having some knowledge from when I mainly used that helps. Although I always expect SRP to do everything differently.
But why shader graph has a scene depth node but no scene normal node, and in order to enable scene normals we have to write C#. This stuff should just be in there for us so we don’t have to write boiler plate code just to use a texture. And I would’ve never figured out the C# code I would have had to write to enable depth normals either. It was lucky I found this thread.
I agree in so far that generating the camera normals texture should be a toggle in the urp asset, same as depth texture.
They probably wanted to omit a normals texture from urp in the beginning (because creating it somewhat expensive because you render every object again to a separate buffer). Afaik it appeared first with the SSAO effect which absolutely needed it.
Edit: Uhh just found your post about the undocumented sample buffer node. If it works that obviously is an option as well (but still needs to renderer feature to populate the buffer first)