렌더 패스 과정에서 렌더 그래프 시스템에서 텍스처를 생성하면 렌더 그래프 시스템이 텍스처의 생성 및 폐기를 처리합니다. 이는 텍스처가 다음 프레임에는 존재하지 않아 다른 카메라가 해당 텍스처를 사용하지 못할 수 있다는 의미합니다.
서로 다른 프레임과 카메라에서 텍스처를 사용할 수 있는지를 확인하려면 ImportTexture API를 사용하여 해당 텍스처를 렌더 그래프 시스템으로 임포트하십시오.
렌더 그래프 시스템 외부에서 생성된 텍스처를 사용하는 경우 텍스처를 임포트할 수 있습니다. 예를 들어 프로젝트의 텍스처(예: 텍스처 에셋)를 가리키는 렌더 텍스처를 만들어 렌더 패스의 입력으로 사용할 수 있습니다.
렌더 그래프 시스템은 임포트된 텍스처의 수명을 관리하지 않습니다. 그 결과 다음에 유의해야 합니다.
RTHandle API에 대한 자세한 내용은 RTHandle 시스템 사용하기를 참조하십시오.
텍스처를 임포트하려면 ScriptableRenderPass 클래스의 RecordRenderGraph 메서드에서 다음 과정을 수행하십시오.
RTHandle API를 사용하여 렌더 텍스처 핸들을 생성합니다.
예시:
private RTHandle renderTextureHandle;
필요한 텍스처 프로퍼티를 사용하여 RenderTextureDescriptor 오브젝트를 만듭니다.
예시:
RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.Default, 0);
ReAllocateIfNeededed 메서드를 사용하여 렌더 텍스처를 만들고 렌더 텍스처 핸들에 연결합니다. 이 메서드는 렌더 텍스처 핸들이 null이거나 렌더 텍스처에 렌더 텍스처 기술자(descriptor)와 다른 프로퍼티가 있는 경우에만 렌더 텍스처를 생성합니다.
예시:
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();
}
다음 스크립터블 렌더러 기능에는 텍스처 에셋을 임시 텍스처로 복사하는 렌더 패스의 예시가 포함되어 있습니다. 이 예시를 사용하려면 다음 과정을 따르십시오.
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);
}
}
}