151 lines
6.2 KiB
C#

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class VolumeLight : ScriptableRendererFeature
{
[Range(0.001f,1)]public float space_sigma=1;
[Range(0.001f,1)]public float range_sigma =0.5f;
// public Vector3 BoundMin;
// public Vector3 BoundMax;
[Range(8,16)]public int Precision=10;
[Range(0,5)]public float Strength=2;
class CustomRenderPass : ScriptableRenderPass
{
public float space_sigma;
public float range_sigma ;
private Material mat;
//private RTHandle tempRT;
// private RTHandle tempRT1;
private readonly int temp = Shader.PropertyToID("temp");
private readonly int temp1 = Shader.PropertyToID("temp1");
private readonly int temp2 = Shader.PropertyToID("temp2");
public Vector3 BoundMin;
public Vector3 BoundMax;
[Range(1,3)]public int Precision;
public float Strength;
public CustomRenderPass()
{
if (mat == null)
{
mat = CoreUtils.CreateEngineMaterial("Unlit/volumeLight");
}
}
// This method is called before executing the render pass.
// It can be used to configure render targets and their clear state. Also to create temporary render target textures.
// When empty this render pass will render to the active camera render target.
// You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
// The render pipeline will ensure target setup and clearing happens in a performant manner.
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
//cmd.GetTemporaryRT(temp,renderingData.cameraData.cameraTargetDescriptor.width,renderingData.cameraData.cameraTargetDescriptor.height);
var dp = renderingData.cameraData.cameraTargetDescriptor;
dp.msaaSamples = 1;
dp.depthBufferBits = 0;
//RenderingUtils.ReAllocateIfNeeded(ref tempRT, dp); //RTHandles.Alloc(temp)
//RenderingUtils.ReAllocateIfNeeded(ref tempRT1, dp);
}
// Here you can implement the rendering logic.
// Use <c>ScriptableRenderContext</c> to issue drawing commands or execute command buffers
// https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html
// You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline.
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get("volumeLight");
RenderTextureDescriptor rtDescriptor = renderingData.cameraData.cameraTargetDescriptor;
//后处理取消抗锯齿
rtDescriptor.msaaSamples = 1;
cmd.GetTemporaryRT(temp,rtDescriptor);
//rtDescriptor.width /= 2;
//rtDescriptor.height /= 2;
cmd.GetTemporaryRT(temp2,rtDescriptor);
cmd.GetTemporaryRT(temp1,rtDescriptor);
//cmd.SetGlobalVector("_BoundMin",BoundMin);
//cmd.SetGlobalVector("_BoundMax",BoundMax);
cmd.SetGlobalFloat("_J",Precision);
cmd.SetGlobalFloat("_Strength",Strength);
//光线步进
//cmd.Blit(renderingData.cameraData.renderer.cameraColorTarget,temp2);
cmd.Blit(renderingData.cameraData.renderer.cameraColorTarget,temp1,mat,0);
//cmd.Blit(temp2,temp1,mat,0);
cmd.SetGlobalFloat("space_sigma",space_sigma);
cmd.SetGlobalFloat("range_sigma",range_sigma);
//双边过滤
cmd.Blit(temp1,temp2,mat,1);
//Blitter.BlitCameraTexture(cmd,tempRT,tempRT1,mat,1);
// 快速模糊
//Blitter.BlitCameraTexture(cmd,tempRT,tempRT1,mat,3);
cmd.Blit(temp2,temp1,mat,4);
cmd.Blit(temp1,temp2,mat,3);
//混合
cmd.SetGlobalTexture("_LightMar",temp2);
cmd.Blit(renderingData.cameraData.renderer.cameraColorTarget,temp,mat,2);
//Blitter.BlitCameraTexture(cmd,renderingData.cameraData.renderer.cameraColorTargetHandle,tempRT1,mat,2);
cmd.Blit(temp,renderingData.cameraData.renderer.cameraColorTarget);
// Blitter.BlitCameraTexture(cmd,tempRT1,renderingData.cameraData.renderer.cameraColorTargetHandle);
cmd.ReleaseTemporaryRT(temp);
cmd.ReleaseTemporaryRT(temp1);
cmd.ReleaseTemporaryRT(temp2);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
// Cleanup any allocated resources that were created during the execution of this render pass.
public override void OnCameraCleanup(CommandBuffer cmd)
{
}
public void Destory()
{
CoreUtils.Destroy(mat);
}
}
CustomRenderPass m_ScriptablePass;
public RenderPassEvent renderPassEvent=RenderPassEvent.AfterRenderingPostProcessing;
/// <inheritdoc/>
public override void Create()
{
m_ScriptablePass = new CustomRenderPass();
// Configures where the render pass should be injected.
m_ScriptablePass.renderPassEvent = renderPassEvent;
}
// Here you can inject one or multiple render passes in the renderer.
// This method is called when setting up the renderer once per-camera.
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
m_ScriptablePass.ConfigureInput(ScriptableRenderPassInput.Depth);
m_ScriptablePass.range_sigma = range_sigma;
m_ScriptablePass.space_sigma = space_sigma;
//m_ScriptablePass.BoundMax = BoundMax;
//m_ScriptablePass.BoundMin = BoundMin;
m_ScriptablePass.Precision = Precision;
m_ScriptablePass.Strength = Strength;
renderer.EnqueuePass(m_ScriptablePass);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
m_ScriptablePass.Destory();
}
}