98 lines
3.9 KiB
C#
98 lines
3.9 KiB
C#
using System;
|
|
using System.Drawing.Drawing2D;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.RenderGraphModule;
|
|
using UnityEngine.Rendering.Universal;
|
|
|
|
namespace UVC.Rendering
|
|
{
|
|
public class EdgeDetection : ScriptableRendererFeature
|
|
{
|
|
private class EdgeDetectionPass : ScriptableRenderPass
|
|
{
|
|
private Material material;
|
|
|
|
private static readonly int OutlineThicknessProperty = Shader.PropertyToID("_OutlineThickness");
|
|
private static readonly int OutlineColorProperty = Shader.PropertyToID("_OutlineColor");
|
|
public EdgeDetectionPass()
|
|
{
|
|
profilingSampler = new ProfilingSampler(nameof(EdgeDetectionPass));
|
|
}
|
|
|
|
public void Setup(ref EdgeDetectionSettings settings, ref Material edgeDetectionMaterial)
|
|
{
|
|
material = edgeDetectionMaterial;
|
|
renderPassEvent = settings.renderPassEvent;
|
|
material.SetFloat(OutlineThicknessProperty, settings.outlineThickness);
|
|
material.SetColor(OutlineColorProperty, settings.outlineColor);
|
|
}
|
|
private class PassData
|
|
{
|
|
}
|
|
|
|
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
|
|
{
|
|
var resourceData = frameData.Get<UniversalResourceData>();
|
|
using var builder = renderGraph.AddRasterRenderPass<PassData>("Edge Detection", out var passData);
|
|
builder.SetRenderAttachment(resourceData.activeColorTexture, 0);
|
|
builder.UseAllGlobalTextures(true);
|
|
builder.AllowPassCulling(false);
|
|
builder.SetRenderFunc((PassData pd, RasterGraphContext context) =>
|
|
{
|
|
Blitter.BlitTexture(context.cmd, Vector2.one, material, 0);
|
|
});
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class EdgeDetectionSettings
|
|
{
|
|
public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingTransparents;
|
|
[Range(0, 15)] public float outlineThickness = 3;
|
|
public Color outlineColor = Color.black;
|
|
public LayerMask layerMask = ~0;
|
|
}
|
|
|
|
[SerializeField] EdgeDetectionSettings settings;
|
|
public Material edgeDetectionMaterial;
|
|
EdgeDetectionPass edgeDetectionPass;
|
|
|
|
public override void Create()
|
|
{
|
|
edgeDetectionPass ??= new EdgeDetectionPass();
|
|
}
|
|
|
|
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
|
|
{
|
|
if (renderingData.cameraData.cameraType == CameraType.Preview
|
|
|| renderingData.cameraData.cameraType == CameraType.Reflection
|
|
|| UniversalRenderer.IsOffscreenDepthTexture(ref renderingData.cameraData))
|
|
{
|
|
return;
|
|
}
|
|
if (edgeDetectionMaterial == null)
|
|
{
|
|
edgeDetectionMaterial= CoreUtils.CreateEngineMaterial(Shader.Find("Custom/EdgeDetectionOutline"));
|
|
if(edgeDetectionMaterial == null)
|
|
{
|
|
Debug.LogWarning("Not all required materials could be created. Edge Detection will not render.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
edgeDetectionPass.ConfigureInput(ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal | ScriptableRenderPassInput.Color);
|
|
edgeDetectionPass.requiresIntermediateTexture = true;
|
|
edgeDetectionPass.Setup(ref settings, ref edgeDetectionMaterial);
|
|
|
|
renderer.EnqueuePass(edgeDetectionPass);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
edgeDetectionPass = null;
|
|
if (edgeDetectionMaterial != null)
|
|
GameObject.DestroyImmediate(edgeDetectionMaterial);
|
|
}
|
|
}
|
|
} |