194 lines
7.0 KiB
C#
194 lines
7.0 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.RenderGraphModule;
|
|
using UnityEngine.Rendering.RenderGraphModule.Util;
|
|
using UnityEngine.Rendering.Universal;
|
|
|
|
public class GlobalDistortionRendererFeature : ScriptableRendererFeature
|
|
{
|
|
[Tooltip("When the custom distortion pass should execute.")]
|
|
public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
|
|
|
|
private Material material;
|
|
private GlobalDistortionPass pass;
|
|
|
|
public override void Create()
|
|
{
|
|
if (pass == null)
|
|
pass = new GlobalDistortionPass();
|
|
|
|
pass.renderPassEvent = renderPassEvent;
|
|
EnsureMaterial();
|
|
}
|
|
|
|
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
|
|
{
|
|
if (!EnsureMaterial())
|
|
return;
|
|
|
|
Camera camera = renderingData.cameraData.camera;
|
|
if (camera == null)
|
|
return;
|
|
|
|
if (renderingData.cameraData.cameraType == CameraType.Preview || renderingData.cameraData.cameraType == CameraType.Reflection)
|
|
return;
|
|
|
|
if (!renderingData.cameraData.postProcessEnabled)
|
|
return;
|
|
|
|
GlobalDistortionVolume settings = VolumeManager.instance.stack.GetComponent<GlobalDistortionVolume>();
|
|
bool hasVolume = settings != null && settings.active;
|
|
float runtimeIntensity = GlobalDistortionRuntimeController.RuntimeIntensity;
|
|
float baseIntensity = hasVolume ? settings.intensity.value : 0f;
|
|
float finalIntensity = Mathf.Clamp01(baseIntensity + runtimeIntensity);
|
|
if (finalIntensity <= 0.0001f)
|
|
return;
|
|
|
|
if (camera.cameraType == CameraType.SceneView && hasVolume && !settings.affectSceneView.value)
|
|
return;
|
|
|
|
pass.Setup(
|
|
material,
|
|
finalIntensity,
|
|
hasVolume ? settings.noiseStrength.value : 0.16f,
|
|
hasVolume ? settings.radialStrength.value : 0.35f,
|
|
hasVolume ? settings.noiseScale.value : 12f,
|
|
hasVolume ? settings.center.value : new Vector2(0.5f, 0.5f),
|
|
hasVolume ? settings.edgeFade.value : 1.25f
|
|
);
|
|
|
|
renderer.EnqueuePass(pass);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (pass != null)
|
|
{
|
|
pass.Dispose();
|
|
pass = null;
|
|
}
|
|
|
|
if (material != null)
|
|
{
|
|
CoreUtils.Destroy(material);
|
|
material = null;
|
|
}
|
|
}
|
|
|
|
private bool EnsureMaterial()
|
|
{
|
|
if (material != null)
|
|
return true;
|
|
|
|
Shader shader = Shader.Find("Hidden/Bansonic/GlobalDistortion");
|
|
if (shader == null)
|
|
return false;
|
|
|
|
material = CoreUtils.CreateEngineMaterial(shader);
|
|
return material != null;
|
|
}
|
|
|
|
private sealed class GlobalDistortionPass : ScriptableRenderPass
|
|
{
|
|
private static readonly int IntensityId = Shader.PropertyToID("_DistortionIntensity");
|
|
private static readonly int NoiseStrengthId = Shader.PropertyToID("_NoiseStrength");
|
|
private static readonly int RadialStrengthId = Shader.PropertyToID("_RadialStrength");
|
|
private static readonly int NoiseScaleId = Shader.PropertyToID("_NoiseScale");
|
|
private static readonly int CenterId = Shader.PropertyToID("_DistortionCenter");
|
|
private static readonly int EdgeFadeId = Shader.PropertyToID("_EdgeFade");
|
|
|
|
private Material passMaterial;
|
|
private float intensity;
|
|
private float noiseStrength;
|
|
private float radialStrength;
|
|
private float noiseScale;
|
|
private Vector2 center;
|
|
private float edgeFade;
|
|
private RTHandle compatibilityCopy;
|
|
|
|
public void Setup(Material material, float passIntensity, float passNoiseStrength, float passRadialStrength, float passNoiseScale, Vector2 passCenter, float passEdgeFade)
|
|
{
|
|
passMaterial = material;
|
|
intensity = passIntensity;
|
|
noiseStrength = passNoiseStrength;
|
|
radialStrength = passRadialStrength;
|
|
noiseScale = passNoiseScale;
|
|
center = passCenter;
|
|
edgeFade = passEdgeFade;
|
|
requiresIntermediateTexture = true;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
compatibilityCopy?.Release();
|
|
compatibilityCopy = null;
|
|
}
|
|
|
|
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
|
|
{
|
|
if (passMaterial == null)
|
|
return;
|
|
|
|
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
|
|
if (resourceData.isActiveTargetBackBuffer)
|
|
return;
|
|
|
|
ApplyMaterialProperties();
|
|
|
|
TextureHandle source = resourceData.activeColorTexture;
|
|
TextureDesc tempDesc = renderGraph.GetTextureDesc(source);
|
|
tempDesc.name = "CameraColor-GlobalDistortionTemp";
|
|
tempDesc.clearBuffer = false;
|
|
|
|
TextureHandle tempTexture = renderGraph.CreateTexture(tempDesc);
|
|
RenderGraphUtils.BlitMaterialParameters effectParameters = new(source, tempTexture, passMaterial, 0);
|
|
renderGraph.AddBlitPass(effectParameters, passName: "Global Distortion Effect");
|
|
|
|
renderGraph.AddBlitPass(
|
|
tempTexture,
|
|
resourceData.activeColorTexture,
|
|
Vector2.one,
|
|
Vector2.zero,
|
|
passName: "Global Distortion Restore"
|
|
);
|
|
}
|
|
|
|
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
|
{
|
|
if (passMaterial == null)
|
|
return;
|
|
|
|
ApplyMaterialProperties();
|
|
|
|
RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
|
descriptor.msaaSamples = 1;
|
|
descriptor.depthBufferBits = 0;
|
|
RenderingUtils.ReAllocateHandleIfNeeded(ref compatibilityCopy, descriptor, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_GlobalDistortionCompatibilityCopy");
|
|
|
|
CommandBuffer cmd = CommandBufferPool.Get("Global Distortion Pass");
|
|
try
|
|
{
|
|
Blitter.BlitCameraTexture(cmd, renderingData.cameraData.renderer.cameraColorTargetHandle, compatibilityCopy);
|
|
Blitter.BlitCameraTexture(cmd, compatibilityCopy, renderingData.cameraData.renderer.cameraColorTargetHandle, passMaterial, 0);
|
|
context.ExecuteCommandBuffer(cmd);
|
|
}
|
|
finally
|
|
{
|
|
cmd.Clear();
|
|
CommandBufferPool.Release(cmd);
|
|
}
|
|
}
|
|
|
|
private void ApplyMaterialProperties()
|
|
{
|
|
passMaterial.SetFloat(IntensityId, intensity);
|
|
passMaterial.SetFloat(NoiseStrengthId, noiseStrength);
|
|
passMaterial.SetFloat(RadialStrengthId, radialStrength);
|
|
passMaterial.SetFloat(NoiseScaleId, noiseScale);
|
|
passMaterial.SetVector(CenterId, center);
|
|
passMaterial.SetFloat(EdgeFadeId, edgeFade);
|
|
}
|
|
}
|
|
}
|
|
|