loudixvmuniu/Assets/Render/OutLine2/Scripts/OutLineCameraRender.cs

208 lines
7.6 KiB
C#
Raw Normal View History

2025-04-02 14:37:35 +08:00
using CG.Framework;
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using Object = UnityEngine.Object;
//[ExecuteAlways]
public class OutLineCameraRender : MonoSingleton<OutLineCameraRender>
{
[Range(1.5f, 5.0f)] public float OutLineScale = 2;
[Range(0, 3.0f)] public float OutLineStrength = 1;
// Camera cam ;
// Start is called before the first frame update
private OutLineRenderPass outLineRenderPass;
void Start()
{
outLineRenderPass = new OutLineRenderPass();
RenderPipelineManager.beginCameraRendering += BeginCameraRendering;
}
private void BeginCameraRendering(ScriptableRenderContext arg1, Camera arg2)
{
if (arg2.cameraType == CameraType.SceneView || arg2.transform.CompareTag("MainCamera"))
{
outLineRenderPass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
outLineRenderPass.outLinePam = OutLineSingle.Instance().GetOutLineRenders();
outLineRenderPass.OutLineScale = OutLineScale;
outLineRenderPass.OutLineStrength = OutLineStrength;
arg2.GetUniversalAdditionalCameraData().scriptableRenderer.EnqueuePass(outLineRenderPass);
}
}
protected override void OnDestroy()
{
RenderPipelineManager.endCameraRendering -= BeginCameraRendering;
if (outLineRenderPass != null)
outLineRenderPass.Distory();
base.OnDestroy();
}
//private void OnDestroy()
//{
// RenderPipelineManager.endCameraRendering -= BeginCameraRendering;
// if(outLineRenderPass != null)
// outLineRenderPass.Distory();
//}
class OutLineRenderPass : ScriptableRenderPass
{
private RTHandle OutLineTemp;
private RTHandle OutLineTemp1;
private RTHandle OutLineTemp11;
private RTHandle OutLineTemp2;
private RTHandle OutLineTemp3;
private RTHandle OutLineTemp4;
private RTHandle OutLineTemp9;
private RTHandle OutLineTemp10;
private RTHandle depth;
private Material OutMat;
private Material OutMatAll;
public float OutLineScale;
public float OutLineStrength;
public List<OutLineDrawPam> outLinePam = new List<OutLineDrawPam>();
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
if (OutMat == null)
{
OutMat = CoreUtils.CreateEngineMaterial("Unlit URP Shader/OutLine");
OutMatAll = CoreUtils.CreateEngineMaterial("Unlit URP Shader/OutLine2");
}
RenderTextureDescriptor rtd = renderingData.cameraData.cameraTargetDescriptor;
rtd.msaaSamples = 1;
rtd.colorFormat = RenderTextureFormat.DefaultHDR;
rtd.depthBufferBits = 0;
RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp1, rtd, name: "OutLineTemp1");
RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp11, rtd, name: "OutLineTemp11");
RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp, rtd, name: "OutLineTemp");
rtd.depthBufferBits = 32;
rtd.colorFormat = RenderTextureFormat.Depth;
RenderingUtils.ReAllocateIfNeeded(ref depth, rtd, name: "depth");
rtd.colorFormat = RenderTextureFormat.DefaultHDR;
rtd.depthBufferBits = 0;
rtd.width /= 2;
rtd.height /= 2;
RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp2, rtd, name: "OutLineTemp2");
RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp10, rtd, name: "OutLineTemp10");
rtd.width /= 2;
rtd.height /= 2;
RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp3, rtd, name: "OutLineTemp3");
RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp9, rtd, name: "OutLineTemp9");
rtd.width /= 2;
rtd.height /= 2;
RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp4, rtd, name: "OutLineTemp4");
ConfigureTarget(OutLineTemp, depth);
ConfigureClear(ClearFlag.All, Vector4.zero);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get("OutLine");
cmd.SetGlobalVector("_HeightLightColor", Vector4.one);
if (outLinePam.Count == 0) return;
for (int i = 0; i < outLinePam.Count; i++)
{
if (outLinePam[i].renders == null || outLinePam[i].renders.Length == 0 || outLinePam[i].draw.color == Color.black) continue;
cmd.SetGlobalColor("_OutLineColor", outLinePam[i].draw.color);
for (int j = 0; j < outLinePam[i].renders.Length; j++)
{
if (outLinePam[i].renders[j] == null) continue;
cmd.DrawRenderer(outLinePam[i].renders[j], OutMat, 0);
}
}
//高亮范围
cmd.SetGlobalFloat("Scale", OutLineScale);
cmd.SetGlobalFloat("Strength", OutLineStrength);
//降采样
Blitter.BlitCameraTexture(cmd, OutLineTemp, OutLineTemp2, OutMatAll, 1);
Blitter.BlitCameraTexture(cmd, OutLineTemp2, OutLineTemp3, OutMatAll, 1);
Blitter.BlitCameraTexture(cmd, OutLineTemp3, OutLineTemp4, OutMatAll, 1);
//升采样
cmd.SetGlobalTexture("_Temp", OutLineTemp3);
Blitter.BlitCameraTexture(cmd, OutLineTemp4, OutLineTemp9, OutMatAll, 2);
cmd.SetGlobalTexture("_Temp", OutLineTemp2);
Blitter.BlitCameraTexture(cmd, OutLineTemp9, OutLineTemp10, OutMatAll, 2);
cmd.SetGlobalTexture("_Temp", OutLineTemp);
Blitter.BlitCameraTexture(cmd, OutLineTemp10, OutLineTemp1, OutMatAll, 2);
//全采样进行一次模糊
cmd.SetGlobalFloat("Scale", 3);
Blitter.BlitCameraTexture(cmd, OutLineTemp1, OutLineTemp11, OutMatAll, 1);
Blitter.BlitCameraTexture(cmd, OutLineTemp11, OutLineTemp, OutMatAll, 1);
//3、通过模板测试裁剪描边内部像素
cmd.SetRenderTarget(OutLineTemp, depth);
Blitter.BlitTexture(cmd, OutLineTemp1, new Vector4(1, 1, 0, 0), OutMatAll, 3);
//4、混合颜色顺便再模糊一次
Blitter.BlitCameraTexture(cmd, OutLineTemp, renderingData.cameraData.renderer.cameraColorTargetHandle, OutMatAll, 4);
context.ExecuteCommandBuffer(cmd);
cmd.Release();
}
public void Distory()
{
#if UNITY_EDITOR
if (EditorApplication.isPlaying)
{
Object.Destroy(OutMat);
Object.Destroy(OutMatAll);
}
else
{
Object.DestroyImmediate(OutMat);
Object.DestroyImmediate(OutMatAll);
}
#else
Object.Destroy(OutMat);
Object.Destroy(OutMatAll);
#endif
if (OutLineTemp != null) OutLineTemp.Release();
if (OutLineTemp11 != null) OutLineTemp11.Release();
if (OutLineTemp1 != null) OutLineTemp1.Release();
if (OutLineTemp2 != null) OutLineTemp2.Release();
if (OutLineTemp3 != null) OutLineTemp3.Release();
if (OutLineTemp4 != null) OutLineTemp4.Release();
if (OutLineTemp9 != null) OutLineTemp9.Release();
if (OutLineTemp10 != null) OutLineTemp10.Release();
if (depth != null) depth.Release();
}
}
}