Last active
April 16, 2022 21:48
-
-
Save EricHu33/d3dfb936b5001fac79a407c7aca0885e to your computer and use it in GitHub Desktop.
An example of how to write custom grab pass renderer feature in Unity URP
This file contains hidden or 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
namespace UnityEngine.Rendering.Universal | |
{ | |
public enum BufferType | |
{ | |
CameraColor, | |
Custom | |
} | |
public class DrawFullScreenFeature : ScriptableRendererFeature | |
{ | |
[System.Serializable] | |
public class Settings | |
{ | |
public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingTransparents; | |
public BufferType sourceType = BufferType.CameraColor; | |
public BufferType destinationType = BufferType.CameraColor; | |
public string sourceTextureId = "_SourceTexture"; | |
public string destinationTextureId = "_DestinationTexture"; | |
public string tempTextureId = "_Temp"; | |
public string grabTexName = "_GrabTexTexture"; | |
} | |
public Settings settings = new Settings(); | |
DrawFullScreenPass blitPass; | |
public override void Create() | |
{ | |
blitPass = new DrawFullScreenPass(name, settings.tempTextureId, settings.grabTexName); | |
} | |
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) | |
{ | |
blitPass.renderPassEvent = settings.renderPassEvent; | |
blitPass.settings = settings; | |
renderer.EnqueuePass(blitPass); | |
} | |
} | |
} |
This file contains hidden or 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
namespace UnityEngine.Rendering.Universal | |
{ | |
/// <summary> | |
/// Draws full screen mesh using given material and pass and reading from source target. | |
/// </summary> | |
internal class DrawFullScreenPass : ScriptableRenderPass | |
{ | |
public FilterMode filterMode { get; set; } | |
public DrawFullScreenFeature.Settings settings; | |
RenderTargetIdentifier source; | |
RenderTargetIdentifier destination; | |
int temporaryRTId; | |
int grabTexId; | |
int sourceId; | |
int destinationId; | |
bool isSourceAndDestinationSameTarget; | |
string m_ProfilerTag; | |
public DrawFullScreenPass(string tag, string tempTextureId, string grabTexName) | |
{ | |
m_ProfilerTag = tag; | |
temporaryRTId = Shader.PropertyToID(tempTextureId); | |
grabTexId = Shader.PropertyToID(grabTexName); | |
} | |
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) | |
{ | |
RenderTextureDescriptor blitTargetDescriptor = renderingData.cameraData.cameraTargetDescriptor; | |
blitTargetDescriptor.depthBufferBits = 0; | |
isSourceAndDestinationSameTarget = settings.sourceType == settings.destinationType && | |
(settings.sourceType == BufferType.CameraColor || settings.sourceTextureId == settings.destinationTextureId); | |
var renderer = renderingData.cameraData.renderer; | |
if (settings.sourceType == BufferType.CameraColor) | |
{ | |
sourceId = -1; | |
source = renderer.cameraColorTarget; | |
} | |
else | |
{ | |
sourceId = Shader.PropertyToID(settings.sourceTextureId); | |
cmd.GetTemporaryRT(sourceId, blitTargetDescriptor, filterMode); | |
source = new RenderTargetIdentifier(sourceId); | |
} | |
if (isSourceAndDestinationSameTarget) | |
{ | |
destinationId = temporaryRTId; | |
cmd.GetTemporaryRT(destinationId, blitTargetDescriptor, filterMode); | |
destination = new RenderTargetIdentifier(destinationId); | |
} | |
else if (settings.destinationType == BufferType.CameraColor) | |
{ | |
destinationId = -1; | |
destination = renderer.cameraColorTarget; | |
} | |
else | |
{ | |
destinationId = Shader.PropertyToID(settings.destinationTextureId); | |
cmd.GetTemporaryRT(destinationId, blitTargetDescriptor, filterMode); | |
destination = new RenderTargetIdentifier(destinationId); | |
} | |
} | |
/// <inheritdoc/> | |
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) | |
{ | |
CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); | |
// Can't read and write to same color target, create a temp render target to blit. | |
if (isSourceAndDestinationSameTarget) | |
{ | |
Blit(cmd, source, destination); | |
Blit(cmd, destination, source); | |
} | |
else | |
{ | |
Blit(cmd, source, destination); | |
} | |
cmd.SetGlobalTexture(grabTexId, destination); | |
context.ExecuteCommandBuffer(cmd); | |
CommandBufferPool.Release(cmd); | |
} | |
/// <inheritdoc/> | |
public override void FrameCleanup(CommandBuffer cmd) | |
{ | |
if (destinationId != -1) | |
cmd.ReleaseTemporaryRT(destinationId); | |
if (source == destination && sourceId != -1) | |
cmd.ReleaseTemporaryRT(sourceId); | |
} | |
} | |
} |
Author
EricHu33
commented
Nov 17, 2021
- choose which render pass event to grab the full screen image.
- name the grabbed texture (Grab Tex Name).
- To use the texture in shader just called
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment