📅  最后修改于: 2023-12-03 14:48:13.689000             🧑  作者: Mango
在 Unity 中,该如何使用 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;
}
将该 Shader 应用到 Unity 的相机上,并添加一个 Plane 作为测试对象。
在场景中,选择 Plane,将 Shader 修改为刚刚新建的 CameraDirection
在场景窗口中,按住鼠标右键并移动,可以看到 Plane 的颜色随着相机的方向而改变:
最后,附上完整的 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
}
}
}