using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; namespace Thousandto.Launcher.ExternalLibs { /// /// 这个脚本用于专门写alpha通道信息,属于OpaqueBloom的配套脚本 /// public class OnlyWriteAlphaScript : MonoBehaviour { public List _renderList; private CommandBuffer _cmd; private Shader _shader; private List _freeMats = new List(); private List _usedMats = new List(); // Start is called before the first frame update void Start() { RefreshCmd(); } private void OnDestroy() { FreeMaterials(); for (int i = 0; i < _freeMats.Count; i++) { if (_freeMats[i] != null) { GameObject.Destroy(_freeMats[i]); } } _freeMats.Clear(); } public void OnSetRenderList(List rlist) { //Debug.LogError("OnlyWriteAlphaScript:OnSetRenderList:" + rlist.Count); _renderList = rlist; CheckRenders(_renderList); RefreshCmd(); } private void RefreshCmd() { if (_cmd == null) { _cmd = new CommandBuffer(); _cmd.name = "WriteAlphaCmd"; GetComponent().AddCommandBuffer(CameraEvent.AfterForwardOpaque, _cmd); GetComponent().cullingMask = 0; } if (_cmd != null) { FreeMaterials(); //首先清理掉命令 _cmd.Clear(); _cmd.ClearRenderTarget(true, true, new Color(0,0,0,0)); if (_renderList != null && _renderList.Count > 0) { for (int i = 0; i < _renderList.Count; i++) { var r = _renderList[i]; if (r != null && r.sharedMaterial != null) { _cmd.DrawRenderer(r, r.sharedMaterial); } } for (int i = 0; i < _renderList.Count; i++) { var r = _renderList[i]; if (r != null && r.sharedMaterial != null) { _cmd.DrawRenderer(r, GetMaterial(r.sharedMaterial)); } } } } } private Material GetMaterial(Material m) { var nm = CreateMateiral(); if (nm != null) { if (m.HasProperty(CmdBufferUtils.MainTexID)) { nm.SetTexture(CmdBufferUtils.MainTexID, m.mainTexture); nm.SetTextureOffset(CmdBufferUtils.MainTexID, m.mainTextureOffset); nm.SetTextureScale(CmdBufferUtils.MainTexID, m.mainTextureScale); } } return nm; } private void FreeMaterials() { for (int i = 0; i < _usedMats.Count; i++) { _usedMats[i].mainTexture = null; } _freeMats.AddRange(_usedMats); _usedMats.Clear(); } private Material CreateMateiral() { if (_freeMats.Count > 0) { var m = _freeMats[_freeMats.Count - 1]; _freeMats.RemoveAt(_freeMats.Count - 1); _usedMats.Add(m); return m; } if (_shader == null) { _shader = RuntimeUtilities.FindShader("Hidden/Ares/PostEffect/OnlyWriteAlpha"); } if (_shader != null) { var newMat = new Material(_shader); newMat.hideFlags = HideFlags.DontSave; _usedMats.Add(newMat); return newMat; } else { Debug.LogError("没有找到所需的Shader:Hidden/Ares/PostEffect/OnlyWriteAlpha"); } return null; } private void CheckRenders(List list) { for (int i = 0; i < list.Count; i++) { var r = list[i]; if (r != null && r is SkinnedMeshRenderer) { (r as SkinnedMeshRenderer).updateWhenOffscreen = true; } } } } }