208 lines
7.6 KiB
C#
208 lines
7.6 KiB
C#
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();
|
||
|
||
|
||
|
||
|
||
}
|
||
}
|
||
}
|