视频链接 Shader:
Shader "LSQ/EffectAchievement/GlobalConeOfSight"
{
Properties
{
_SightColor("SightColor",Color) = (1,1,1,1)
_SightAngle("SightAngle",Range(0, 360)) = 60
_SightRadius("SightRadius",Range(0, 0.5)) = 0.5
}
SubShader
{
Tags
{
"Queue"="Transparent"
"RenderType"="Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float4 worldPos : TEXCOORD1;
};
fixed4 _SightColor;
float _SightAngle;
float _SightRadius;
sampler2D _SightDepthTexture;
float4x4 _ViewProjectMatrix;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
return o;
}
float GetObstacle(float4 worldPos)
{
float4 posViewSpace = mul(_ViewProjectMatrix, worldPos);
float3 projCoords = posViewSpace.xyz / posViewSpace.w;
projCoords = projCoords * 0.5 + 0.5;
float sampledDepth = 1 - SAMPLE_DEPTH_TEXTURE(_SightDepthTexture, projCoords.xy);
return projCoords.z < sampledDepth;
}
fixed4 frag(v2f i) : SV_Target
{
float obstacle = GetObstacle(i.worldPos);
const float PI = 3.14159;
float2 uv = i.uv - 0.5f;
float len = length(uv);
float radius = _SightRadius > len;
float angle = atan2(uv.y, uv.x) / PI * 180;
float sightRange = smoothstep(_SightAngle, 0, angle) - smoothstep(0, -_SightAngle, angle);
float sight = sightRange * radius * obstacle;
return _SightColor * saturate(sight);
}
ENDCG
}
}
}
C# :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GlobalConeOfSight : MonoBehaviour
{
public Color sightColor = Color.red;
public float sightAngle = 60;
public float sightRadius = 5;
public float scanSpeed = 60;
public Transform headTF;
public GameObject sightGO;
public Camera sightCamera;
private Material sightMaterial;
private void Awake()
{
Initialize();
RenderTexture depthTexture = new RenderTexture(sightCamera.pixelWidth, sightCamera.pixelHeight, 24, RenderTextureFormat.Depth);
sightCamera.targetTexture = depthTexture;
sightMaterial.SetTexture("_SightDepthTexture", sightCamera.targetTexture);
}
private void Update()
{
if (headTF != null)
{
headTF.Rotate(Vector3.up, Time.deltaTime * scanSpeed * -1, Space.Self);
}
if (sightCamera != null)
{
sightCamera.Render();
sightMaterial.SetMatrix("_ViewProjectMatrix", sightCamera.projectionMatrix * sightCamera.worldToCameraMatrix);
}
}
private void OnValidate()
{
Initialize();
}
private void Initialize()
{
if (sightGO != null)
{
if (sightMaterial == null)
{
sightMaterial = sightGO.GetComponent<Renderer>().sharedMaterial;
}
else
{
sightGO.transform.localScale = Vector3.one * sightRadius * 2;
sightMaterial.SetColor("_SightColor", sightColor);
sightMaterial.SetFloat("_SightAngle", sightAngle);
sightMaterial.SetFloat("_ScanSpeed", scanSpeed);
}
}
if (sightCamera != null)
{
sightCamera.fieldOfView = sightAngle;
sightCamera.farClipPlane = sightRadius;
}
}
private void OnDrawGizmos()
{
Gizmos.matrix = Matrix4x4.TRS(transform.position, Quaternion.identity, new Vector3(1f, 0f, 1f));
Gizmos.DrawWireSphere(Vector3.zero, sightRadius);
Gizmos.matrix = Matrix4x4.identity;
}
}
|