当您在渲染通道中在渲染图系统中创建纹理时,渲染图系统会处理纹理的创建和释放。此过程意味着纹理可能在下一帧不存在,并且其他摄像机一个组件,用于创建场景中特定视点的图像。输出要么绘制到屏幕上,要么作为纹理捕获。 更多信息
参见 术语表可能无法使用它。
要确保纹理跨帧和摄像机可用,请使用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);
}
}
}