Files
Main/Assets/GameAssets/Resources/GameUI/Common/ARShadow/VRShadow.cs

166 lines
5.3 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
using UnityEngine;
using System.Collections;
using Thousandto.Core.Base;
using PathUtils = UnityEngine.Gonbest.MagicCube.PathUtils;
using CoroutinePool = UnityEngine.Gonbest.MagicCube.CoroutinePool;
using StringUtils = UnityEngine.Gonbest.MagicCube.StringUtils;
public class VRShadow : MonoBehaviour {
public Camera ShadowCamera;
public Transform TargetShadowPlane;
private RenderTexture RT;
private Material ShadowMat;
private Transform TargetTrans;
private int Depth = 0;
public void Initialize(Transform roleTrans, Transform plane, string shadowLayer = "ARLayer")
{
if (ShadowCamera != null) return;
TargetTrans = roleTrans;
var parent = plane.parent;
//设置渲染阴影的材质球替换shader
ShadowMat = plane.GetComponent<Renderer>().material;
ShadowMat.shader = FindShader();
//创建阴影相机
ShadowCamera = CreateShadowCamera(parent);
ShadowCamera.cullingMask = 1 << LayerMask.NameToLayer(shadowLayer);
//创建用于渲染阴影的RenderTexture
RT = CreateRenderTexture();
RT.name = "RenderTexture1";
RT.antiAliasing = 1;
ShadowCamera.targetTexture = RT;
if (Depth > 0)
{
ShadowMat.EnableKeyword("_USE_DEPTH_ON_");
ShadowMat.DisableKeyword("_USE_DEPTH_OFF_");
}
else
{
ShadowMat.EnableKeyword("_USE_DEPTH_OFF_");
ShadowMat.DisableKeyword("_USE_DEPTH_ON_");
}
}
private Shader FindShader()
{
string shaderAB = PathUtils.GetResourcePath("Shader/Ares/Special/VRShadow.unity3d");
if(System.IO.File.Exists(shaderAB))
{
//var ab =AssetBundle.LoadFromFile(shaderAB);
//if (ab != null)
//{
// var shader = ab.LoadAsset<Shader>("Shader/Ares/Special/VRShadow");
// ab.Unload(false);
// UnityEngine.Debug.Log("shader load from bundle success");
// return shader;
//}
//UnityEngine.Debug.Log("shader load from bundle failed");
}
return ShaderEx.Find("Ares/Special/VRShadow");
}
private void Render()
{
if (ShadowCamera == null) return;
Matrix4x4 proj = ShadowCamera.projectionMatrix;
Matrix4x4 view = ShadowCamera.worldToCameraMatrix;
proj = GL.GetGPUProjectionMatrix(ShadowCamera.projectionMatrix, true);
ShadowMat.SetMatrix("_VRWorld2ShadowProj", proj * view);
ShadowMat.SetTexture("_VRShadowMap", RT);
ShadowMat.SetFloat("_VRShadowIntensity", 0.7f);
ShadowCamera.transform.position = TargetTrans.position;
}
private Camera CreateShadowCamera(Transform parent)
{
GameObject go = new GameObject("VRShadowCamera");
go.transform.parent = parent;
go.transform.position = new Vector3(0, 3, 0);
go.transform.rotation = Quaternion.Euler(15, 9, 0);
go.transform.localScale = Vector3.one;
Camera camera = go.AddComponent<Camera>();
SetCameraParams(camera);
//SetReplacementShader(camera);
return camera;
}
private RenderTexture CreateRenderTexture()
{
var format = GetRenderTextureFormat();
return RenderTexture.GetTemporary(512, 512, Depth, format);
}
private void SetCameraParams(Camera camera)
{
camera.clearFlags = CameraClearFlags.SolidColor;
camera.backgroundColor = Color.black;
camera.orthographic = true;
camera.orthographicSize = 3.0f;
camera.nearClipPlane = -100;
camera.farClipPlane = 100;
camera.depth = 2;
camera.cullingMask = 1 << LayerMask.NameToLayer("Role");
}
private void SetReplacementShader(Camera camera)
{
//渲染对象显示在视口中是白色
var _depthShader = ShaderEx.Find("Ares/SpecialEffect/MakeShadow");
camera.SetReplacementShader(_depthShader, "RenderType");
}
private RenderTextureFormat GetRenderTextureFormat()
{
var texFormat = RenderTextureFormat.RGB565;
if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.Depth))
{
Depth = 24;
texFormat = RenderTextureFormat.Depth;
}
else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGB565))
{
texFormat = RenderTextureFormat.RGB565;
}
else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB4444))
{
texFormat = RenderTextureFormat.ARGB4444;
}
else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB1555))
{
texFormat = RenderTextureFormat.ARGB1555;
}
else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32))
{
texFormat = RenderTextureFormat.ARGB32;
}
//UnityEngine.Debug.Log("VRShadow: RT format = " + texFormat);
return texFormat;
}
// Update is called once per frame
void Update () {
Render();
}
//在编辑器中对脚本的值做改变会触发这个函数
void OnValidate()
{
if (TargetShadowPlane == null) return;
Initialize(TargetShadowPlane.parent, TargetShadowPlane);
}
}