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().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/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(); 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); } }