加入很多新内容,这波一块交了
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.RenderGraphModule;
|
||||
using UnityEngine.Rendering.RenderGraphModule.Util;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
public class GlobalAfterimageRendererFeature : ScriptableRendererFeature
|
||||
{
|
||||
[Tooltip("When the custom afterimage pass should execute.")]
|
||||
public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
|
||||
|
||||
private Material material;
|
||||
private GlobalAfterimagePass pass;
|
||||
|
||||
public override void Create()
|
||||
{
|
||||
if (pass == null)
|
||||
pass = new GlobalAfterimagePass();
|
||||
|
||||
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;
|
||||
|
||||
GlobalAfterimageVolume settings = VolumeManager.instance.stack.GetComponent<GlobalAfterimageVolume>();
|
||||
bool hasVolume = settings != null && settings.active;
|
||||
float runtimeOpacity = GlobalAfterimageRuntimeController.RuntimeOpacity;
|
||||
float baseOpacity = hasVolume ? settings.opacity.value : 0f;
|
||||
float finalOpacity = Mathf.Clamp01(Mathf.Max(baseOpacity, runtimeOpacity));
|
||||
if (finalOpacity <= 0.0001f)
|
||||
return;
|
||||
|
||||
if (camera.cameraType == CameraType.SceneView && hasVolume && !settings.affectSceneView.value)
|
||||
return;
|
||||
|
||||
float runtimeScale = Mathf.Max(1f, GlobalAfterimageRuntimeController.RuntimeScale);
|
||||
float baseScale = hasVolume ? settings.scale.value : 1.05f;
|
||||
float finalScale = Mathf.Max(baseScale, runtimeScale);
|
||||
bool captureRequested = GlobalAfterimageRuntimeController.ConsumeCaptureRequest();
|
||||
|
||||
pass.Setup(material, finalOpacity, finalScale, captureRequested, renderingData.cameraData.cameraTargetDescriptor);
|
||||
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/GlobalAfterimage");
|
||||
if (shader == null)
|
||||
return false;
|
||||
|
||||
material = CoreUtils.CreateEngineMaterial(shader);
|
||||
return material != null;
|
||||
}
|
||||
|
||||
private sealed class GlobalAfterimagePass : ScriptableRenderPass
|
||||
{
|
||||
private static readonly int OpacityId = Shader.PropertyToID("_AfterimageOpacity");
|
||||
private static readonly int ScaleId = Shader.PropertyToID("_AfterimageScale");
|
||||
private static readonly int SnapshotTexId = Shader.PropertyToID("_SnapshotTex");
|
||||
|
||||
private Material passMaterial;
|
||||
private float opacity;
|
||||
private float scale;
|
||||
private bool captureRequested;
|
||||
private RenderTextureDescriptor descriptor;
|
||||
private RTHandle compatibilityCopy;
|
||||
private RTHandle snapshotTexture;
|
||||
|
||||
public void Setup(Material material, float passOpacity, float passScale, bool passCaptureRequested, RenderTextureDescriptor targetDescriptor)
|
||||
{
|
||||
passMaterial = material;
|
||||
opacity = passOpacity;
|
||||
scale = Mathf.Max(1f, passScale);
|
||||
captureRequested = passCaptureRequested;
|
||||
descriptor = targetDescriptor;
|
||||
descriptor.msaaSamples = 1;
|
||||
descriptor.depthBufferBits = 0;
|
||||
requiresIntermediateTexture = true;
|
||||
RenderingUtils.ReAllocateHandleIfNeeded(ref snapshotTexture, descriptor, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_GlobalAfterimageSnapshot");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
compatibilityCopy?.Release();
|
||||
compatibilityCopy = null;
|
||||
snapshotTexture?.Release();
|
||||
snapshotTexture = null;
|
||||
}
|
||||
|
||||
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
|
||||
{
|
||||
if (passMaterial == null || snapshotTexture == null)
|
||||
return;
|
||||
|
||||
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
|
||||
if (resourceData.isActiveTargetBackBuffer)
|
||||
return;
|
||||
|
||||
ApplyMaterialProperties();
|
||||
|
||||
TextureHandle source = resourceData.activeColorTexture;
|
||||
TextureHandle importedSnapshot = renderGraph.ImportTexture(snapshotTexture);
|
||||
if (captureRequested)
|
||||
{
|
||||
renderGraph.AddBlitPass(source, importedSnapshot, Vector2.one, Vector2.zero, passName: "Global Afterimage Capture");
|
||||
}
|
||||
|
||||
TextureDesc tempDesc = renderGraph.GetTextureDesc(source);
|
||||
tempDesc.name = "CameraColor-GlobalAfterimageTemp";
|
||||
tempDesc.clearBuffer = false;
|
||||
TextureHandle tempTexture = renderGraph.CreateTexture(tempDesc);
|
||||
|
||||
RenderGraphUtils.BlitMaterialParameters effectParameters = new(source, tempTexture, passMaterial, 0);
|
||||
renderGraph.AddBlitPass(effectParameters, passName: "Global Afterimage Effect");
|
||||
renderGraph.AddBlitPass(tempTexture, resourceData.activeColorTexture, Vector2.one, Vector2.zero, passName: "Global Afterimage Restore");
|
||||
}
|
||||
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (passMaterial == null || snapshotTexture == null)
|
||||
return;
|
||||
|
||||
ApplyMaterialProperties();
|
||||
RenderingUtils.ReAllocateHandleIfNeeded(ref compatibilityCopy, descriptor, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_GlobalAfterimageCompatibilityCopy");
|
||||
|
||||
CommandBuffer cmd = CommandBufferPool.Get("Global Afterimage Pass");
|
||||
if (captureRequested)
|
||||
{
|
||||
Blitter.BlitCameraTexture(cmd, renderingData.cameraData.renderer.cameraColorTargetHandle, snapshotTexture);
|
||||
}
|
||||
|
||||
Blitter.BlitCameraTexture(cmd, renderingData.cameraData.renderer.cameraColorTargetHandle, compatibilityCopy);
|
||||
Blitter.BlitCameraTexture(cmd, compatibilityCopy, renderingData.cameraData.renderer.cameraColorTargetHandle, passMaterial, 0);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
private void ApplyMaterialProperties()
|
||||
{
|
||||
passMaterial.SetFloat(OpacityId, opacity);
|
||||
passMaterial.SetFloat(ScaleId, scale);
|
||||
if (snapshotTexture != null)
|
||||
passMaterial.SetTexture(SnapshotTexId, snapshotTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user