renderfeature可以方便的定义后处理
注意要插入postprocess之后,否者会被其他的renderTartget冲掉
https://bzyzhang.github.io/2021/01/31/2021-01-31-%EF%BC%88%E5%8D%81%E4%BA%8C%EF%BC%89URP%E4%B8%AD%E8%87%AA%E5%AE%9A%E4%B9%89%E5%90%8E%E5%A4%84%E7%90%86%E5%AE%9E%E4%BE%8B/
可以参考URP自带SSAO的实现
https://qiita.com/t-matsunaga/items/09343ae7c683269374c4 这个也可以参考
https://www.jianshu.com/p/ef5dfa7c7e0b // 后处理框架
可参考这个吧 https://github.com/Unity-Technologies/UniversalRenderingExamples/blob/master/Assets/Scripts/Runtime/RenderPasses/DrawFullscreenPass.cs
https://alexanderameye.github.io/notes/scriptable-render-passes/ // boxblur
第一步
shader
新建一个image effect
第二步
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class CustomRenderPassFeature : ScriptableRendererFeature
{
private class CustomRenderPass : ScriptableRenderPass
{
private CustomRPSettings _CustomRPSettings;
private RenderTargetHandle _TemporaryColorTexture;
private RenderTargetIdentifier _Source;
private RenderTargetHandle _Destination;
public CustomRenderPass(CustomRPSettings settings)
{
_CustomRPSettings = settings;
}
public void Setup(RenderTargetIdentifier source, RenderTargetHandle destination)
{
_Source = source;
_Destination = destination;
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
_TemporaryColorTexture.Init("_TemporaryColorTexture");
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get("My Pass");
cmd.GetTemporaryRT(_TemporaryColorTexture.id,
renderingData.cameraData.cameraTargetDescriptor, FilterMode.Bilinear);
cmd.Blit(source, _TemporaryColorTexture.Identifier(), m_Materials.uber);
cmd.Blit(_TemporaryColorTexture.Identifier(), source);
// 释放临时RT
cmd.ReleaseTemporaryRT(_TemporaryColorTexture.id);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
public override void FrameCleanup(CommandBuffer cmd)
{
if (_Destination == RenderTargetHandle.CameraTarget)
{
cmd.ReleaseTemporaryRT(_TemporaryColorTexture.id);
}
}
}
[System.Serializable]
public class CustomRPSettings
{
public Material Material;
public RenderPassEvent PassEvent = RenderPassEvent.AfterRenderingPostProcessing;
}
public CustomRPSettings customRPSettings = new CustomRPSettings();
private CustomRenderPass _ScriptablePass;
public override void Create()
{
_ScriptablePass = new CustomRenderPass(customRPSettings);
_ScriptablePass.renderPassEvent = customRPSettings.PassEvent;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
// if (renderingData.cameraData.isSceneViewCamera) return;
_ScriptablePass.Setup(renderer.cameraColorTarget, RenderTargetHandle.CameraTarget);
renderer.EnqueuePass(_ScriptablePass);
}
}
如果是最后做的话
需要加
Blit(cmd, xxx, RenderTargetHandle.CameraTarget.id);
或者
if (this.renderPassEvent == RenderPassEvent.AfterRenderingPostProcessing)
{
Blit(cmd, destination,BuiltinRenderTextureType.CameraTarget);
}
else
{
Blit(cmd, destination, source);
}
_SourceTex
注意Bloom Blit
Bloom blit的时候会重写一个函数, 如下
目的是为了把上一个pass的结果应用到下一个pass
private new void Blit(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, int passIndex = 0)
{
cmd.SetGlobalTexture(SourceTexId, source);
cmd.Blit(source, destination, material, passIndex);
}
如果优化的话
可以和_CameraColorTexture绑定起来
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@13.1/manual/renderer-features/how-to-fullscreen-blit-in-xr-spi.html
如果还是有bug
试试这种方法 结合 unity的 XR blit
https://github.com/zane133/CommandBufferDemo/blob/main/Assets/Scripts/RenderFeatures/SetRenderTarget/Passes/DrawAndBlitTestPass.cs
add pass的时候记得加 ConfigureInput
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if (renderingData.cameraData.cameraType == CameraType.Game)
{
//Calling ConfigureInput with the ScriptableRenderPassInput.Color argument ensures that the opaque texture is available to the Render Pass
m_RenderPass.ConfigureInput(ScriptableRenderPassInput.Color);
m_RenderPass.SetTarget(renderer.cameraColorTarget, m_Intensity);
renderer.EnqueuePass(m_RenderPass);
}
}
Bilt
https://docs.unity3d.com/2020.3/Documentation/ScriptReference/Rendering.CommandBuffer.Blit.html
Blit函数可以把一个RT拷贝到另一个RT里
其中如果mat == null shader的输入属性应该为 _MainTex
记得要加
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
完整后处理shader
Shader "Hidden/TestRF"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off
// ZWrite Off ZTest Always
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = TransformObjectToHClip(v.vertex.xyz);
o.uv = v.uv;
return o;
}
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
half4 frag (v2f i) : SV_Target
{
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
// just invert the colors
col.rgb = 1 - col.rgb;
return col;
}
ENDHLSL
}
}
}