Last active
June 26, 2023 22:41
-
-
Save rngtm/c313ca0ac3987a60aa108ec55e9cce70 to your computer and use it in GitHub Desktop.
URP 10.7.0でのフルスクリーンエフェクトでのRenderBufferのロード・ストア最適化の検証
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Hidden/CustomImageEffect" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
} | |
SubShader | |
{ | |
// No culling or depth | |
Cull Off ZWrite Off ZTest Always | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
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 = UnityObjectToClipPos(v.vertex); | |
o.uv = v.uv; | |
return o; | |
} | |
sampler2D _MainTex; | |
half4 frag (v2f i) : SV_Target | |
{ | |
float2 uv = i.uv; | |
uv.x += sin(uv.y * 64.0) * 0.01; | |
return tex2D(_MainTex, uv); | |
} | |
ENDCG | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.Experimental.Rendering; | |
using UnityEngine.Experimental.Rendering.Universal; | |
using UnityEngine.Rendering; | |
using UnityEngine.Rendering.Universal; | |
public class CustomImageEffectFeature : ScriptableRendererFeature | |
{ | |
class CustomRenderPass : ScriptableRenderPass | |
{ | |
private bool m_IsOptimizeLoadStore; | |
private Material m_Material; | |
private int m_RepeatCount; | |
public void Setup(RenderPassEvent passEvent, Material material, int repeatCount = 1, bool optimizeLoadStore = false) | |
{ | |
renderPassEvent = passEvent; | |
m_Material = material; | |
m_IsOptimizeLoadStore = optimizeLoadStore; | |
m_RepeatCount = repeatCount; | |
} | |
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) | |
{ | |
base.Configure(cmd, cameraTextureDescriptor); | |
// ポストエフェクト用の一時テクスチャを作成 (RenderTextureはGPUメモリ上に乗っている) | |
var desc = cameraTextureDescriptor; | |
cameraTextureDescriptor.depthBufferBits = 0; | |
cameraTextureDescriptor.stencilFormat = GraphicsFormat.None; | |
cmd.GetTemporaryRT(ShaderPropertyId.TempTex1, desc); | |
cmd.GetTemporaryRT(ShaderPropertyId.TempTex2, desc); | |
} | |
// 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) | |
{ | |
var cmd = CommandBufferPool.Get($"CustomImageEffect (Repeat: {m_RepeatCount}"); | |
RenderTargetIdentifier cameraColorTarget = renderingData.cameraData.renderer.cameraColorTarget; | |
int buffer1 = ShaderPropertyId.TempTex1; | |
int buffer2 = ShaderPropertyId.TempTex2; | |
cmd.Blit(cameraColorTarget, buffer1); | |
RenderBufferLoadAction colorLoadAction; | |
RenderBufferStoreAction colorStoreAction; | |
if (PostEffectSettings.IsOptimizeLoadStoreColor) | |
{ | |
// カラーバッファのロードを行わない | |
colorLoadAction = RenderBufferLoadAction.DontCare; | |
colorStoreAction = RenderBufferStoreAction.Store; | |
} | |
else | |
{ | |
// カラーバッファのロード・ストアが行われる | |
colorLoadAction = RenderBufferLoadAction.Load; | |
colorStoreAction = RenderBufferStoreAction.Store; | |
} | |
RenderBufferLoadAction depthLoadAction; | |
RenderBufferStoreAction depthStoreAction; | |
if (PostEffectSettings.IsOptimizeLoadStoreDepth) | |
{ | |
// デプスのロード・ストアを行わない | |
depthLoadAction = RenderBufferLoadAction.DontCare; | |
depthStoreAction = RenderBufferStoreAction.DontCare; | |
} | |
else | |
{ | |
// デプスのロード・ストアが行われる (不要) | |
depthLoadAction = RenderBufferLoadAction.Load; | |
depthStoreAction = RenderBufferStoreAction.Store; | |
} | |
for (int i = 0; i < m_RepeatCount; i++) | |
{ | |
if (m_IsOptimizeLoadStore) | |
{ | |
cmd.SetRenderTarget(buffer2, | |
colorLoadAction, | |
colorStoreAction, | |
depthLoadAction, | |
depthStoreAction); | |
} | |
else | |
{ | |
cmd.SetRenderTarget(buffer2); | |
} | |
cmd.Blit(buffer1, buffer2, m_Material); | |
if (i != m_RepeatCount - 1) | |
{ | |
// swap | |
(buffer1, buffer2) = (buffer2, buffer1); | |
} | |
} | |
if (m_IsOptimizeLoadStore) | |
{ | |
cmd.SetRenderTarget(buffer2, | |
colorLoadAction, | |
colorStoreAction, | |
depthLoadAction, | |
depthStoreAction); | |
} | |
cmd.Blit(buffer2, cameraColorTarget); | |
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) | |
{ | |
cmd.ReleaseTemporaryRT(ShaderPropertyId.TempTex1); | |
cmd.ReleaseTemporaryRT(ShaderPropertyId.TempTex2); | |
} | |
} | |
private CustomRenderPass m_ScriptablePass; | |
private Material m_Material; | |
[SerializeField] private Settings settings = new Settings(); | |
[System.Serializable] | |
private class Settings | |
{ | |
public RenderPassEvent RenderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; | |
} | |
/// <inheritdoc/> | |
public override void Create() | |
{ | |
m_ScriptablePass = new CustomRenderPass(); | |
m_ScriptablePass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; | |
if (m_Material == null) | |
{ | |
m_Material = CoreUtils.CreateEngineMaterial("Hidden/CustomImageEffect"); | |
} | |
} | |
// 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) | |
{ | |
if (PostEffectSettings.RepeatCount > 0) | |
{ | |
m_ScriptablePass.Setup(settings.RenderPassEvent, m_Material, PostEffectSettings.RepeatCount, PostEffectSettings.IsOptimizeLoadStore); | |
renderer.EnqueuePass(m_ScriptablePass); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class PostEffectSettings | |
{ | |
public static int RepeatCount = 30; // Blitの実行回数 | |
public static bool IsOptimizeLoadStore = true; // RenderBufferのロード・ストアの最適化 | |
public static bool IsOptimizeLoadStoreColor = true; // RenderBuffer(カラーバッファ)のロード・ストアの最適化 | |
public static bool IsOptimizeLoadStoreDepth = true; // RenderBuffer(デプスバッファ)のロード・ストアの最適化 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment