如何从不亮的着色器中获得Z-depth?

时间:2015-03-19 06:20:41

标签: unity3d shader

目前,我尝试将z深度效果设为图像效果,但结果图像未正确呈现。有些不对劲......

如果我使用标准着色器(单位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);
    }
}

Standar Shader(Unity5)

Unlit Shader

2 个答案:

答案 0 :(得分:2)

我找到了这个解决方案。我在渲染未点亮的对象之前使用了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
        }
    }
}

答案 1 :(得分:0)

您需要在不亮的着色器中提供后备选项,以便它可以使用此回退着色器中的其他所需的传递(深度/阴影/等)。

将以下行添加到未点亮的着色器应该有帮助。

Fallback "Diffuse"