166 lines
5.3 KiB
C#
166 lines
5.3 KiB
C#
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);
|
||
}
|
||
}
|