Last active
July 6, 2022 16:56
-
-
Save wonkee-kim/1792cd4fced96f98ae4a09ec500a3177 to your computer and use it in GitHub Desktop.
Unity URP BlitPass with comments
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
// https://github.com/Unity-Technologies/UniversalRenderingExamples/blob/master/Assets/Scripts/Runtime/RenderPasses/BlitPass.cs | |
// https://samdriver.xyz/articles/scriptableRender.htm | |
using UnityEngine.Rendering; | |
using UnityEngine.Rendering.Universal; | |
namespace UnityEngine.Experimental.Rendering.Universal { | |
/// <summary> | |
/// Copy the given color buffer to the given destination color buffer. | |
/// | |
/// You can use this pass to copy a color buffer to the destination, | |
/// so you can use it later in rendering. For example, you can copy | |
/// the opaque texture to use it for distortion effects. | |
/// https://github.com/Unity-Technologies/UniversalRenderingExamples/blob/master/Assets/Scripts/Runtime/RenderPasses/BlitPass.cs | |
/// </summary> | |
/// | |
//The "pass" is what does the actual rendering work while the "feature" is how it interfaces with the rest of the scriptable pipeline. | |
public class BlitPass :ScriptableRenderPass { | |
// used to label this pass in Unity's Frame Debug utility | |
string m_ProfilerTag; | |
public Material blitMaterial = null; | |
public int blitShaderPassIndex = 0; | |
// https://docs.unity3d.com/ScriptReference/Rendering.RenderTargetIdentifier.html | |
// https://docs.unity3d.com/ScriptReference/Rendering.RenderTargetIdentifier-ctor.html | |
private RenderTargetIdentifier source { get; set; } | |
private RenderTargetHandle destination { get; set; } | |
RenderTargetHandle m_TemporaryColorTexture; | |
//public FilterMode filterMode { get; set; } | |
public FilterMode filterMode = FilterMode.Trilinear; | |
/// <summary> | |
/// Create the CopyColorPass | |
/// </summary> | |
public BlitPass(RenderPassEvent renderPassEvent, Material blitMaterial, int blitShaderPassIndex, string tag) { | |
this.renderPassEvent = renderPassEvent; | |
this.blitMaterial = blitMaterial; | |
this.blitShaderPassIndex = blitShaderPassIndex; | |
m_ProfilerTag = tag; | |
m_TemporaryColorTexture.Init("_TemporaryColorTexture"); | |
} | |
// This isn't part of the ScriptableRenderPass class and is our own addition. | |
// For this custom pass we need the camera's color target, so that gets passed in. | |
/// <summary> | |
/// Configure the pass with the source and destination to execute on. | |
/// </summary> | |
/// <param name="source">Source Render Target</param> | |
/// <param name="destination">Destination Render Target</param> | |
public void Setup(RenderTargetIdentifier source, RenderTargetHandle destination) { | |
this.source = source; | |
this.destination = destination; | |
} | |
// called each frame before Execute, use it to set up things the pass will need | |
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { | |
// Can't read and write to same color target, create a temp render target to blit. | |
if(destination == RenderTargetHandle.CameraTarget) { | |
// Create a temporary render texture that maches the camera | |
//cmd.GetTemporaryRT(m_TemporaryColorTexture.id, cameraTextureDescriptor, filterMode); | |
cmd.GetTemporaryRT(m_TemporaryColorTexture.id, cameraTextureDescriptor); | |
} | |
} | |
// Execute is called for every eligible camera every frame. It's not called at the moment that | |
// rendering is actually taking place, so don't directly execute rendering commands here. | |
// Instead use the methods on ScriptableRenderContext to set up instructions. | |
// RenderingData provides a bunch of (not very well documented) information about the scene | |
// and what's being rendered. | |
/// <inheritdoc/> | |
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { | |
// fetch a command buffer to use | |
CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); | |
cmd.Clear(); | |
RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor; | |
opaqueDesc.depthBufferBits = 0; | |
// Can't read and write to same color target, create a temp render target to blit. | |
if(destination == RenderTargetHandle.CameraTarget) { | |
// Create a temporary render texture that maches the camera | |
//cmd.GetTemporaryRT(m_TemporaryColorTexture.id, opaqueDesc, filterMode); | |
// the actual content of our custom render pass | |
// we apply our material while blitting to a temporary texture | |
Blit(cmd, source, m_TemporaryColorTexture.Identifier(), blitMaterial, blitShaderPassIndex); | |
// ..then blit it back again | |
Blit(cmd, m_TemporaryColorTexture.Identifier(), source); | |
//cmd.Blit(source, m_TemporaryColorTexture.Identifier(), blitMaterial, blitShaderPassIndex); | |
} else { | |
Blit(cmd, source, destination.Identifier(), blitMaterial, blitShaderPassIndex); | |
} | |
// don't forget to tell ScriptableRenderContext to actually execute the commands | |
context.ExecuteCommandBuffer(cmd); | |
// tidy up after ourselves | |
CommandBufferPool.Release(cmd); | |
} | |
// called after Execute, use it to clean up anything allocated in Configure and Execute | |
/// <inheritdoc/> | |
public override void FrameCleanup(CommandBuffer cmd) { | |
if(destination == RenderTargetHandle.CameraTarget) | |
cmd.ReleaseTemporaryRT(m_TemporaryColorTexture.id); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment