Files
Main/Assets/Launcher/ExternalLibs/CmdBuffer/OpaqueBloom/OnlyWriteAlphaScript.cs
2025-01-25 04:38:09 +08:00

151 lines
4.6 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace Thousandto.Launcher.ExternalLibs
{
/// <summary>
/// 这个脚本用于专门写alpha通道信息,属于OpaqueBloom的配套脚本
/// </summary>
public class OnlyWriteAlphaScript : MonoBehaviour
{
public List<Renderer> _renderList;
private CommandBuffer _cmd;
private Shader _shader;
private List<Material> _freeMats = new List<Material>();
private List<Material> _usedMats = new List<Material>();
// 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<Renderer> 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<Camera>().AddCommandBuffer(CameraEvent.AfterForwardOpaque, _cmd);
GetComponent<Camera>().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<Renderer> list)
{
for (int i = 0; i < list.Count; i++)
{
var r = list[i];
if (r != null && r is SkinnedMeshRenderer)
{
(r as SkinnedMeshRenderer).updateWhenOffscreen = true;
}
}
}
}
}