レンダーパス内で レンダーグラフシステムを使用してテクスチャを作成する と、レンダーグラフシステムがテクスチャの作成と破棄を処理します。この処理により、次のフレームにそのテクスチャが存在しない場合や他のカメラがテクスチャを使用できない場合があります。
複数のフレームおよびカメラをまたいでテクスチャを使用できるようにするには、ImportTexture API を使用してレンダーグラフシステムにインポートします。
レンダーグラフシステムの外部で作成されたテクスチャを使用する場合、テクスチャをインポートできます。例えば、テクスチャアセット など、プロジェクト内のテクスチャを指すレンダーテクスチャを作成し、レンダーパスへの入力として使用できます。
レンダーグラフシステムは、インポートしたテクスチャの生存期間を管理しません。そのため、以下の内容が適用されます。
RTHandle API の詳細については、RTHandle システムの使用 を参照してください。
テクスチャをインポートするには、ScriptableRenderPass クラスの RecordRenderGraph メソッドで、以下のステップに従います。
RTHandle API を使用してレンダーテクスチャハンドルを作成します。
例:
private RTHandle renderTextureHandle;
必要なテクスチャプロパティを持つ RenderTextureDescriptor オブジェクトを作成します。
例:
RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.Default, 0);
ReAllocateIfNeeded メソッドを使用し、レンダーテクスチャを作成してレンダーテクスチャハンドルにアタッチします。このメソッドは、レンダーテクスチャハンドルが null である場合、またはレンダーテクスチャがレンダーテクスチャ記述子と異なるプロパティを持つ場合にのみレンダーテクスチャを作成します。
例:
RenderingUtils.ReAllocateIfNeeded(ref renderTextureHandle, textureProperties, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "My render texture" );
テクスチャをインポートして、RTHandle オブジェクトをレンダーグラフシステムが使用できる TextureHandle オブジェクトに変換します。
例:
TextureHandle texture = renderGraph.ImportTexture(renderTextureHandle);
その後、TextureHandle オブジェクトを使用して、レンダーテクスチャの読み取り/書き込み を行うことができます。
プロジェクトからテクスチャ (マテリアルに設定されているインポートされたテクスチャなど) をインポートするには、以下のステップに従います。
RTHandles.Alloc API を使用して、外部テクスチャからレンダーテクスチャハンドルを作成します。
例:
RTHandle renderTexture = RTHandles.Alloc(texture);
テクスチャをインポートして、RTHandle オブジェクトをレンダーグラフシステムが使用できる TextureHandle オブジェクトに変換します。
例:
TextureHandle textureHandle = renderGraph.ImportTexture(renderTexture);
その後、TextureHandle オブジェクトを使用して、レンダーテクスチャの読み取り/書き込み を行うことができます。
Dispose メソッドを使用して、レンダーパス終了時にレンダーテクスチャが使用するメモリを解放する必要があります。
public void Dispose()
{
renderTexture.Release();
}
以下の Scriptable Renderer Feature には、テクスチャアセットを一時的なテクスチャにコピーするレンダーパスの例が含まれています。この例を使用するには、以下のステップに従います。
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering;
public class BlitFromExternalTexture : ScriptableRendererFeature
{
// The texture to use as input
public Texture2D textureToUse;
BlitFromTexture customPass;
public override void Create()
{
// Create an instance of the render pass, and pass in the input texture
customPass = new BlitFromTexture(textureToUse);
customPass.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(customPass);
}
class BlitFromTexture : ScriptableRenderPass
{
class PassData
{
internal TextureHandle textureToRead;
}
private Texture2D texturePassedIn;
public BlitFromTexture(Texture2D textureIn)
{
// In the render pass's constructor, set the input texture
texturePassedIn = textureIn;
}
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameContext)
{
using (var builder = renderGraph.AddRasterRenderPass<PassData>("Copy texture", out var passData))
{
// Create a temporary texture and set it as the render target
RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.Default, 0);
TextureHandle texture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, textureProperties, "My texture", false);
builder.SetRenderAttachment(texture, 0, AccessFlags.Write);
// Create a render texture from the input texture
RTHandle rtHandle = RTHandles.Alloc(texturePassedIn);
// Create a texture handle that the shader graph system can use
TextureHandle textureToRead = renderGraph.ImportTexture(rtHandle);
// Add the texture to the pass data
passData.textureToRead = textureToRead;
// Set the texture as readable
builder.UseTexture(passData.textureToRead, AccessFlags.Read);
builder.AllowPassCulling(false);
builder.SetRenderFunc((PassData data, RasterGraphContext context) => ExecutePass(data, context));
}
}
static void ExecutePass(PassData data, RasterGraphContext context)
{
// Copy the imported texture to the render target
Blitter.BlitTexture(context.cmd, data.textureToRead, new Vector4(0.8f,0.6f,0,0), 0, false);
}
}
}