using UnityEngine; using System.Collections; using System.Collections.Generic; using Thousandto.Launcher.ExternalLibs; /// /// 创建一个产生实时阴影贴图的脚本 /// public class ShadowMapScript : MonoBehaviour { #region 常量定义 private const int CN_RESIZE_WIDTH = 1024; private const int CN_RTSIZE_HEIGHT = 1024; private const string DefaultShadowKeyWords = "_GONBEST_SHADOW_ON"; #endregion #region 私有变量 //是否支持阴影 private bool _supportShadow = false; //支持的阴影贴图模式 private RenderTextureFormat _texFormat = RenderTextureFormat.ARGB32; //阴影贴图深度值 private int _texDepth = 0; //阴影开关 private bool _isEnable = false; //阴影摄像机 private Camera _shadowMapCamera = null; //矩阵 private Matrix4x4 _shadowViewProj = Matrix4x4.zero; //阴影贴图 private RenderTexture _shadownMap = null; //阴影shader private Shader _depthShader = null; //摄像机裁剪层 [SerializeField] private LayerMask _Cameralayer = 1 << 28; //可接受阴影的render [SerializeField] private Renderer[] _shadowRenderers = null; //阴影强度 [SerializeField] private float _shadowStrength = 0.7f; //阴影视口大小 [SerializeField] private float _viewPortSize = 3; //是否使用深度处理 [SerializeField] private bool _useDepth = false; //是否需要刷新 [SerializeField] private bool _refresh = false; #endregion #region //重载MonoBehaviour的系统函数 // Use this for initialization void Awake() { //1.初始化 ResetShadowShaderParam(); //2.判断是否支持阴影 CheckSupportShadow(); //3.刷新摄像机 RefreshCamera(); } private void OnEnable() { EnableEx(); RefreshCamera(); } private void OnDisable() { DisableEx(); } // Update is called once per frame void Update() { if (_refresh) { _refresh = false; if (_shadowMapCamera != null) { if (_useDepth) { _depthShader = ShaderFactory.Find("Ares/SpecialEffect/MakeShadow_Depth"); if (_depthShader == null) { Debug.LogError("阴影不生效,因为没有找到Shader:Ares/SpecialEffect/MakeShadow_Depth"); } } else { _depthShader = ShaderFactory.Find("Ares/SpecialEffect/MakeShadow"); if (_depthShader == null) { Debug.LogError("阴影不生效,因为没有找到Shader:Ares/SpecialEffect/MakeShadow"); } } _shadowMapCamera.SetReplacementShader(_depthShader, "RenderType"); } } this.Render(); } private void OnValidate() { RefreshCamera(); } private void OnDestroy() { ResetMaterial(); ReleaseRenderTexture(); if (_shadowMapCamera != null) { _shadowMapCamera.enabled = false; } } #endregion //刷新摄像机的值 private void RefreshCamera() { if (!_supportShadow) return; if (_shadowMapCamera == null) { _shadowMapCamera = gameObject.GetComponent(); _shadowMapCamera.clearFlags = CameraClearFlags.Color; _shadowMapCamera.backgroundColor = Color.black; _shadowMapCamera.depth = -10f; _shadowMapCamera.useOcclusionCulling = false; _shadowMapCamera.orthographic = true; _shadowMapCamera.enabled = true; if (_useDepth) { _depthShader = ShaderFactory.Find("Ares/SpecialEffect/MakeShadow_Depth"); } else { _depthShader = ShaderFactory.Find("Ares/SpecialEffect/MakeShadow"); } if (_depthShader == null) { Debug.LogError("阴影不生效,因为没有找到Shader:Ares/SpecialEffect/MakeShadow"); } _shadowMapCamera.SetReplacementShader(_depthShader, "RenderType"); ; } if (_shadowMapCamera != null) { _shadowMapCamera.cullingMask = _Cameralayer; _shadowMapCamera.orthographicSize = _viewPortSize; } } //创建RenderTexture private void CreateRenderTexture() { if (!_supportShadow) return; ReleaseRenderTexture(); if (!_useDepth) _texDepth = 0; _shadownMap = RenderTexture.GetTemporary(CN_RESIZE_WIDTH, CN_RTSIZE_HEIGHT, _texDepth, _texFormat); _shadownMap.name = "RenderTexture86"; _shadownMap.wrapMode = TextureWrapMode.Clamp; if (_shadownMap.format != _texFormat) { _shadownMap.format = _texFormat; } _shadownMap.filterMode = FilterMode.Bilinear; _shadownMap.antiAliasing = 1; Graphics.Blit(Texture2D.blackTexture, _shadownMap); _shadowMapCamera.targetTexture = _shadownMap; _shadowMapCamera.RenderWithShader(_depthShader, "RenderType"); } //释放RenderTexture private void ReleaseRenderTexture() { if (_shadownMap != null) { RenderTexture.ReleaseTemporary(_shadownMap); _shadownMap = null; } if (_shadowMapCamera != null) _shadowMapCamera.targetTexture = null; } //判断是否支持阴影 private bool CheckSupportShadow() { _supportShadow = true; if (_useDepth) { if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32)) { _texFormat = RenderTextureFormat.ARGB32; } else { _supportShadow = false; Debug.LogError("阴影不生效,因为当前设备不支持RenderTexture的图片格式!"); } } 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; } else { _supportShadow = false; Debug.LogError("阴影不生效,因为当前设备不支持RenderTexture的图片格式!"); } } return _supportShadow; } //实时获取阴影摄像机的数据,并为Shader所需传递参数 public void Render() { if (!_supportShadow) return; if (!_isEnable) return; if (_depthShader == null) return; if (_shadowMapCamera == null) return; Matrix4x4 proj = _shadowMapCamera.projectionMatrix; Matrix4x4 view = _shadowMapCamera.worldToCameraMatrix; proj = GL.GetGPUProjectionMatrix(_shadowMapCamera.projectionMatrix, true); if (_shadowRenderers != null) { for (int i = 0; i < _shadowRenderers.Length; ++i) { var render = _shadowRenderers[i]; if (render != null && render.sharedMaterial != null) { render.sharedMaterial.SetMatrix("_MyWorld2ShadowProj", proj * view); render.sharedMaterial.SetTexture("_MyShadowMap", _shadownMap); render.sharedMaterial.SetFloat("_ShadowIntensity", _shadowStrength); } } } } //开启阴影 private void EnableEx() { _isEnable = true; if (!_supportShadow) return; ResetShadowShaderParam(); if (_shadowMapCamera != null) _shadowMapCamera.enabled = true; CreateRenderTexture(); if (_shadowRenderers != null) { for (int i = 0; i < _shadowRenderers.Length; ++i) { var render = _shadowRenderers[i]; if (render != null && render.sharedMaterial != null) { //Debug.LogError("Eanble:"+ render.name); render.sharedMaterial.EnableKeyword(DefaultShadowKeyWords); } } } } //关闭阴影 private void DisableEx() { _isEnable = false; if (!_supportShadow) return; ResetShadowShaderParam(); if (_shadowMapCamera != null) _shadowMapCamera.enabled = false; ReleaseRenderTexture(); if (_shadowRenderers != null) { for (int i = 0; i < _shadowRenderers.Length; ++i) { var render = _shadowRenderers[i]; if (render != null && render.sharedMaterial != null) { //Debug.LogError("Disable:" + render.name); render.sharedMaterial.DisableKeyword(DefaultShadowKeyWords); } } } } //重置一下阴影的shader参数 private void ResetShadowShaderParam() { if (_shadowRenderers != null) { for (int i = 0; i < _shadowRenderers.Length; ++i) { var render = _shadowRenderers[i]; if (render != null && render.sharedMaterial != null) { render.sharedMaterial.SetTexture("_MyShadowMap", Texture2D.blackTexture); render.sharedMaterial.SetFloat("_ShadowIntensity", 1); } } } } //重置一下阴影的shader参数 private void ResetMaterial() { if (_shadowRenderers != null) { for (int i = 0; i < _shadowRenderers.Length; ++i) { var render = _shadowRenderers[i]; if (render != null && render.sharedMaterial != null) { render.sharedMaterial.shader = render.sharedMaterial.shader; } } } } }