How to render transparent objects in URP depth normals feature?

3.3k Views Asked by At

When I change the graph Inspector - > Universal - > surface type from opaque to transparent in the shader graph, I will not be able to render the depth information to _DepthNormalsTexture。

If I set it to opaque, the result is: enter image description here Change to transparent: enter image description here result is: enter image description here The two balls disappeared because they used the material above

I used URP and added a custom depth normals feature enter image description here

And c# code:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class DepthNormalsFeature : ScriptableRendererFeature {
    class RenderPass : ScriptableRenderPass {

        private Material material;
        private RenderTargetHandle destinationHandle;
        private List<ShaderTagId> shaderTags;
        private FilteringSettings filteringSettings;

        public RenderPass(Material material) : base() {
            this.material = material;

            this.shaderTags = new List<ShaderTagId>() {
                new ShaderTagId("DepthOnly"),
            };

            this.filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
            destinationHandle.Init("_DepthNormalsTexture");
        }

        public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) {
            cmd.GetTemporaryRT(destinationHandle.id, cameraTextureDescriptor, FilterMode.Point);
            ConfigureTarget(destinationHandle.Identifier());
            ConfigureClear(ClearFlag.All, Color.black);
        }

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {

            var drawSettings = CreateDrawingSettings(shaderTags, ref renderingData, renderingData.cameraData.defaultOpaqueSortFlags);

            drawSettings.overrideMaterial = material;
            context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref filteringSettings);
        }

        public override void FrameCleanup(CommandBuffer cmd) {
            cmd.ReleaseTemporaryRT(destinationHandle.id);
        }
    }

    private RenderPass renderPass;

    public override void Create() {
        Material material = CoreUtils.CreateEngineMaterial("MyShader/Internal-DepthNormalsTexture");
        
        this.renderPass = new RenderPass(material);
        renderPass.renderPassEvent = RenderPassEvent.AfterRenderingPrePasses;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) {
        renderer.EnqueuePass(renderPass);
    }
}

And shader code:

Shader "MyShader/Internal-DepthNormalsTexture"
{
    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
        
        Pass
        {
            Name "Depth-Normal"
            
            HLSLPROGRAM
            
            HLSLcc by default
            #pragma prefer_hlslcc gles
            #pragma exclude_renderers d3d11_9x
            #pragma target 2.0
            
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            
            #pragma vertex vert
            #pragma fragment frag
            
            struct Attributes
            {
                float4 positionOS: POSITION;
                float3 normalOS: NORMAL;
            };
            
            struct Varyings
            {
                float4 positionCS: SV_POSITION;
                float4 normal_depth: TEXCOORD0;
            };
            
            float2 EncodeViewNormalStereo(float3 n)
            {
                float kScale = 1.7777;
                float2 enc;
                enc = n.xy / (n.z + 1);
                enc /= kScale;
                enc = enc * 0.5 + 0.5;
                return enc;
            }
            
            float2 EncodeFloatRG(float v)
            {
                float2 kEncodeMul = float2(1.0, 255.0);
                float kEncodeBit = 1.0 / 255.0;
                float2 enc = kEncodeMul * v;
                enc = frac(enc);
                enc.x -= enc.y * kEncodeBit;
                return enc;
            }
            
            float4 EncodeDepthNormal(float depth, float3 normal)
            {
                float4 enc;
                enc.xy = EncodeViewNormalStereo(normal);
                enc.zw = EncodeFloatRG(depth);
                return enc;
            }
            
            Varyings vert(Attributes input)
            {
                Varyings output = (Varyings)0;
                
                VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
                
                output.positionCS = vertexInput.positionCS;
                output.normal_depth.xyz = mul((float3x3)UNITY_MATRIX_IT_MV, input.normalOS);
                output.normal_depth.w = - (vertexInput.positionVS.z * _ProjectionParams.w);
                
                return output;
            }
            
            half4 frag(Varyings input): SV_Target
            {
                return EncodeDepthNormal(input.normal_depth.w, input.normal_depth.xyz);
            }
            ENDHLSL
            
        }
    }
}

I don't know why shader graph set to transparent disappear when rendering depth.

How can I render transparent objects in DepthNormalsFeature?

0

There are 0 best solutions below