-
-
Save kkhomyakov3d/059b88d62086f4d3cd48c16055b071af 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 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 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); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment