Version: 6000.3
语言: 中文
在 URP 的渲染图系统中创建纹理
在 URP 的渲染通道中使用纹理

将纹理导入 URP 中的渲染图系统

渲染通道的渲染图系统中创建纹理时,渲染图系统将处理纹理的创建和处置。此过程意味着纹理可能不存在于下一帧中,而其他相机在场景中创建特定视点图像的组件。输出要么绘制到屏幕上,要么作为纹理捕获。更多信息
请参阅术语表
可能无法使用它。

要确保纹理在帧和摄像机中可用,请使用ImportTexture应用程序接口。

如果使用在渲染图系统外部创建的纹理,则可以导入纹理。例如,您可以创建一个渲染纹理(render texture一种特殊类型的纹理,在运行时创建和更新。要使用它们,请先创建一个新的渲染纹理,并指定要渲染到其中的摄像机之一。然后,你可以在材质中使用渲染纹理,就像使用常规纹理一样。更多信息
请参阅术语表
指向项目中的纹理,例如纹理资产,并将其用作渲染通道的输入。

渲染图系统不管理导入纹理的生存期。因此,以下内容适用:

  • 你必须释放导入的渲染纹理,以便在完成后释放它使用的内存。
  • URP无法剔除使用导入纹理的渲染通道。因此,渲染速度可能会变慢。

有关RTHandleAPI,请参阅使用 RTHandle 系统

导入纹理

要导入纹理,请在RecordRenderGraph你的方法ScriptableRenderPass类,请按照下列步骤作:

  1. 使用 RTHandle API 创建渲染纹理句柄。

    例如:

    private RTHandle renderTextureHandle;
    
  2. 使用所需的纹理属性创建 RenderTextureDescriptor 对象。

    例如:

    RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.Default, 0);
    
  3. 使用 ReAllocateIfNeeded 方法创建渲染纹理并将其附加到渲染纹理句柄。仅当渲染纹理句柄为 null 或渲染纹理与渲染纹理描述符具有不同的属性时,此方法才会创建渲染纹理。

    例如:

    RenderingUtils.ReAllocateIfNeeded(ref renderTextureHandle, textureProperties, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "My render texture" );
    
  4. 导入纹理,以将RTHandleTextureHandle渲染图表系统可以使用的对象。

    例如:

    TextureHandle texture = renderGraph.ImportTexture(renderTextureHandle);
    

然后,您可以使用TextureHandle对象,以读取或写入渲染纹理

从项目导入纹理

要从项目导入纹理,例如附加到材质的导入纹理,请执行以下步骤:

  1. 使用RTHandles.AllocAPI 从外部纹理创建渲染纹理句柄。

    例如:

    RTHandle renderTexture = RTHandles.Alloc(texture);
    
  2. 导入纹理,以将RTHandleTextureHandle渲染图系统可以使用的对象。

    例如:

    TextureHandle textureHandle = renderGraph.ImportTexture(renderTexture);
    

然后,您可以使用TextureHandle对象,以读取或写入渲染纹理

释放渲染纹理

您必须释放渲染纹理在渲染通道结束时使用的内存。

例如,您可以创建以下内容Dispose方法:

public void Dispose()
{
    renderTexture.Release();
}

以下可脚本渲染器功能包含一个示例渲染通道,用于将纹理资产复制到临时纹理。若要使用此示例,请执行以下步骤:

  1. 将此可编写脚本渲染器功能添加到URP资产。请参阅使用可编写脚本的渲染器功能注入通道。
  2. 检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
    请参阅术语表
    窗口中,将纹理添加到 要使用的纹理(Texture To Use) 属性。
  3. 使用 帧调试器(Frame Debugger) 检查渲染通道添加的纹理。
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 render 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);

            // Dispose of the texture
            RTHandles.Release(data.textureToRead);
        }
    }
}

其他资源

在 URP 的渲染图系统中创建纹理
在 URP 的渲染通道中使用纹理