📜  Unlit shader 获取相机 UNity 的方向 - C# (1)

📅  最后修改于: 2023-12-03 14:48:13.689000             🧑  作者: Mango

使用 Unlit shader 获取相机 Unity 的方向 - C#

在 Unity 中,该如何使用 Unlit shader 来获取相机的方向呢?本文将带你一步步实现该功能。

目录
  • 准备工作
  • 获取相机方向
  • 应用到 Unlit shader 上
  • 示例代码
准备工作

在开始之前,我们需要新建一个 Unlit shader,用于展示相机的方向。

在 Unity 中,打开 Create / Shader / Unlit Shader,并命名为 CameraDirection.

打开该 Shader 文件,首先我们需要设置 Shader 的一些属性:

Shader "Custom/CameraDirection"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return tex2D(_MainTex, i.uv);
            }
            ENDCG
        }
    }
}
获取相机方向

接下来,我们需要在 Shader 中获取相机方向。

Properties 中添加一个 _CameraDirection 属性:

Properties
{
    _MainTex ("Texture", 2D) = "white" {}
    _CameraDirection ("Camera Direction", Vector) = (0,0,0,0)
}

vert 函数中,增加一个参数 float4 worldPos,将该参数转换为视口坐标,并输出到 v2f 结构体中:

v2f vert (appdata v, float4 worldPos)
{
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv;
    o.worldPos = UnityObjectToWorldPos(worldPos);
    o.viewPos = UnityObjectToViewPos(worldPos);
    o.screenPos = ComputeScreenPos(o.vertex);
    return o;
}

v2f 中,并添加以下成员变量:

float4 worldPos : TEXCOORD1;
float4 viewPos : TEXCOORD2;
float4 screenPos : TEXCOORD3;

最后,在 frag 函数中获得相机方向并输出即可:

fixed4 frag (v2f i) : SV_Target
{
    float4 cameraDirection = normalize(_WorldSpaceCameraPos - i.worldPos);
    return cameraDirection;
}
应用到 Unlit shader 上

将该 Shader 应用到 Unity 的相机上,并添加一个 Plane 作为测试对象。

在场景中,选择 Plane,将 Shader 修改为刚刚新建的 CameraDirection

在场景窗口中,按住鼠标右键并移动,可以看到 Plane 的颜色随着相机的方向而改变:

CameraDirection

示例代码

最后,附上完整的 Shader 代码:

Shader "Custom/CameraDirection"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _CameraDirection ("Camera Direction", Vector) = (0,0,0,0)
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 worldPos : TEXCOORD1;
                float4 viewPos : TEXCOORD2;
                float4 screenPos : TEXCOORD3;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _CameraDirection;

            v2f vert (appdata v, float4 worldPos)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.worldPos = UnityObjectToWorldPos(worldPos);
                o.viewPos = UnityObjectToViewPos(worldPos);
                o.screenPos = ComputeScreenPos(o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float4 cameraDirection = normalize(i.worldPos - _WorldSpaceCameraPos);
                return cameraDirection;
            }
            ENDCG
        }
    }
}