Skip to content

Instantly share code, notes, and snippets.

@fuqunaga
Last active November 20, 2023 07:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fuqunaga/a0b12ea3175aa7144e4431024329d77d to your computer and use it in GitHub Desktop.
Save fuqunaga/a0b12ea3175aa7144e4431024329d77d to your computer and use it in GitHub Desktop.
GrabColorRendererFeature
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
/// <summary>
/// Built-in Render PipelineのGrabPassに近いRendererFeature
/// RenderObjectsRendererFeatureでGrab対象のオブジェクトを描画し、
/// そのあとにGrabColorRendererFeatureを設定することで任意のタイミングでキャプチャ、
/// 以降のシェーダーでgrabbedTextureNameで指定した名前でキャプチャしたテクスチャを参照できる
///
/// 例:Opaqueの一部のオブジェクトをキャプチャする場合、UniversalRenderDataをInspector上で以下のように設定する
///  1. キャプチャする対象オブジェクトに専用のレイヤー(以下GrabTargetLayer)を設定
///  2. UniversalRendererDataのopaqueLayerマスクからGrabTargetLayerを除外
///  3. RenderObjectsRendererFeatureをRenderFeatureに追加
///   - EventをBeforeRenderingOpaquesにセット
///   - Filters>LayerMaskでGrabTargetLayerをセット
///  4. 3.の次になるようにGrabColorRenderFeatureを設定
/// - RenderPassEventをBeforeRenderingOpaquesにセット
/// </summary>
public class GrabColorRendererFeature : ScriptableRendererFeature
{
public RenderPassEvent renderPassEvent = RenderPassEvent.BeforeRenderingOpaques;
public string grabbedTextureName = "g_GrabbedTexture";
private GrabColorPass _pass;
public override void Create()
{
_pass = new(grabbedTextureName, renderPassEvent);
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(_pass);
}
private class GrabColorPass : ScriptableRenderPass
{
private readonly RTHandle _textureHandle;
private readonly int _texturePropertyId;
public GrabColorPass(string textureName, RenderPassEvent renderPassEvent)
{
this.renderPassEvent = renderPassEvent;
_texturePropertyId = Shader.PropertyToID(textureName);
_textureHandle = RTHandles.Alloc(_texturePropertyId, textureName);
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
cmd.GetTemporaryRT(_texturePropertyId, cameraTextureDescriptor);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
var cmd = CommandBufferPool.Get(nameof(GrabColorPass));
#if UNITY_2022_2_OR_NEWER
var source = renderingData.cameraData.renderer.cameraColorTargetHandle;
if (source.rt != null)
{
Blit(cmd, source, _textureHandle);
}
#else
Blit(cmd, renderingData.cameraData.renderer.cameraColorTarget, _textureHandle);
#endif
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
public override void OnCameraCleanup(CommandBuffer cmd)
{
cmd.ReleaseTemporaryRT(_texturePropertyId);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment