如何从无光照着色器获取 Z 深度?

How can I get Z-depth from unlit shader?

目前,我尝试将 z 深度效果制作为图像效果,但结果图像未正确渲染。出了点问题...

如果我使用标准着色器 (unity 5),结果图像会被正确渲染(z 深度图像没问题),但未点亮着色器不会。

发生什么事了?如果你有任何想法,告诉我为什么。

着色器

Shader "Custom/RenderDepth"
{
    Properties
    {
        _DepthLevel ("Depth Level", Range(1, 3)) = 2
    }
    SubShader
    {
        Pass
        {

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D_float _CameraDepthTexture;
            uniform fixed _DepthLevel;
            uniform half4 _MainTex_TexelSize;

            struct uinput
            {
                float4 pos : POSITION;
                half2 uv : TEXCOORD0;
            };

            struct uoutput
            {
                float4 pos : SV_POSITION;
                half2 uv : TEXCOORD0;
            };

            uoutput vert(uinput i)
            {
                uoutput o;
                o.pos = mul(UNITY_MATRIX_MVP, i.pos);
                o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, i.uv);
                return o;
            }

            fixed4 frag(uoutput o) : COLOR
            {
                float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, o.uv));
                depth = pow(Linear01Depth(depth), _DepthLevel);
                return depth;
            }

            ENDCG
        }
    }
}

CS

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
public class Test : MonoBehaviour
{
    public Camera _cam;
    public Material mat;

    public float DepthLevel = 1.0F;

    void Start ()
    {
        _cam.depthTextureMode |= DepthTextureMode.Depth;
    }

    void Update ()
    {
    }

    void OnRenderImage (RenderTexture source, RenderTexture destination)
    {
        mat.SetFloat("_DepthLevel", DepthLevel);
        Graphics.Blit(source, destination, mat);
    }
}

我找到了这个解决方案。在渲染我的未光照对象之前,我使用 VertexLit 遗留着色器的 SHADOWCASTER 通道。

那么您的着色器将如下所示:

Shader "Custom/RenderDepth"
{
    Properties
    {
        _DepthLevel ("Depth Level", Range(1, 3)) = 2
    }
    SubShader
    {
        UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"

        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D_float _CameraDepthTexture;
            uniform fixed _DepthLevel;
            uniform half4 _MainTex_TexelSize;

            struct uinput
            {
                float4 pos : POSITION;
                half2 uv : TEXCOORD0;
            };

            struct uoutput
            {
                float4 pos : SV_POSITION;
                half2 uv : TEXCOORD0;
            };

            uoutput vert(uinput i)
            {
                uoutput o;
                o.pos = mul(UNITY_MATRIX_MVP, i.pos);
                o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, i.uv);
                return o;
            }

            fixed4 frag(uoutput o) : COLOR
            {
                float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, o.uv));
                depth = pow(Linear01Depth(depth), _DepthLevel);
                return depth;
            }

            ENDCG
        }
    }
}

您需要在 unlit 着色器中提供回退选项,以便它可以使用此回退着色器中的其他所需通道 (depth/shadow/etc)。

将以下行添加到您的无光照着色器应该会有所帮助。

Fallback "Diffuse"