Version: 6000.3
语言: 中文
从 URP 中的当前帧中获取数据
将纹理添加到相机历史记录中

在 URP 中获取前一帧的数据

要获取相机在场景中创建特定视点图像的组件。输出要么绘制到屏幕上,要么作为纹理捕获。更多信息
请参阅术语表
在通用渲染管线(Render Pipeline) 获取场景内容并将其显示在屏幕上的一系列作。Unity 允许您从预构建的渲染管道中进行选择,或编写自己的渲染管道。更多信息
请参阅术语表
(URP),请使用UniversalCameraData.historyManager应用程序接口。这些纹理有时称为历史纹理或历史缓冲区。

帧是 GPU 渲染管道的输出,因此它们不包括 GPU 渲染后发生的任何处理,例如后处理在图像出现在屏幕上之前通过应用滤镜和效果来改善产品视觉效果的过程。你可以使用后期处理效果来模拟物理摄像机和胶片属性,例如泛光和景深。更多信息 后处理, 后处理, 后处理
术语表中查看
影响。

要从可编写脚本的渲染通道外部获取先前的帧,请参阅从脚本中的先前帧获取数据

按着这些次序:

  1. RecordRenderGraph方法,获取UniversalCameraData对象ContextContainer对象。例如:

    public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameContext)
    {
        UniversalCameraData cameraData = frameContext.Get<UniversalCameraData>();
    }    
    
  2. 要请求访问渲染历史记录中的颜色纹理或深度纹理,请使用RequestAccess应用程序接口。例如:

    // Request access to the color textures
    cameraData.historyManager.RequestAccess<RawColorHistory>();
    

    RawDepthHistory而是请求访问深度纹理。

  3. 获取之前的纹理之一。例如:

    // Get the previous textures 
    RawColorHistory history = cameraData.historyManager.GetHistoryForRead<RawColorHistory>();
    
    // Get the first texture, which the camera rendered in the previous frame
    RTHandle historyTexture = history?.GetPreviousTexture(0);
    
  4. 将纹理转换为渲染图系统可以使用的句柄。例如:

    passData.historyTexture = renderGraph.ImportTexture(historyTexture);
    

然后,您可以在渲染通道中读取纹理。

有关使用historyManagerAPI,请参阅UniversalCameraData.historyManager.

下面是一个可编写脚本渲染器功能,它创建材质并使用前一帧作为材质的纹理。

要使用该示例,请执行以下步骤:

  1. 创建 URP着色器在 GPU 上运行的程序。更多信息
    请参阅术语表
    该纹理采样名为_BaseMap.有关示例,请参阅绘制纹理
  2. 从着色器创建材质。
  3. 创建一个名为RenderLastFrameInMaterial.cs,将以下代码粘贴到其中,然后保存文件。
  4. 在活动的URP渲染器中,添加 可编写脚本渲染器功能(Scriptable Renderer Feature)。
  5. 检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
    请参阅术语表
    在步骤4中添加的可脚本渲染器功能的 渲染材料中的最后一帧(Render Last Frame In Material) 分段中,将你在步骤2中创建的材质分配给 对象材质(Object Material) 字段。
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule;
public class RenderLastFrameInMaterial : ScriptableRendererFeature
{
    public Material objectMaterial;
    CustomRenderPass renderLastFrame;

    public override void Create()
    {
        renderLastFrame = new CustomRenderPass();
        renderLastFrame.renderPassEvent = RenderPassEvent.BeforeRenderingOpaques;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderLastFrame.passMaterial = objectMaterial;
        renderer.EnqueuePass(renderLastFrame);
    }

    class CustomRenderPass : ScriptableRenderPass
    {
        public Material passMaterial;

        public class PassData
        {
            internal Material material;
            internal TextureHandle historyTexture;
        }

        public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer contextData)
        {
            UniversalCameraData cameraData = contextData.Get<UniversalCameraData>();

            // Return if the history manager isn't available
            // For example, there are no history textures during the first frame
            if (cameraData.historyManager == null) { return; }
  
            // Request access to the color and depth textures
            cameraData.historyManager.RequestAccess<RawColorHistory>();

            using (var builder = renderGraph.AddRasterRenderPass<PassData>("Get last frame", out var passData))
            {
                UniversalResourceData resourceData = contextData.Get<UniversalResourceData>();

                // Set the render graph to render to the active color texture
                builder.SetRenderAttachment(resourceData.activeColorTexture, 0, AccessFlags.Write);

                // Add the material to the pass data
                passData.material = passMaterial;
                
                // Get the color texture the camera rendered to in the previous frame
                RawColorHistory history = cameraData.historyManager.GetHistoryForRead<RawColorHistory>();
                RTHandle historyTexture = history?.GetPreviousTexture(0);
                passData.historyTexture = renderGraph.ImportTexture(historyTexture);

                builder.SetRenderFunc(static (PassData data, RasterGraphContext context) =>
                {
                    // Set the material to use the texture
                    data.material.SetTexture("_BaseMap", data.historyTexture);
                });
            }
        }
    }
}

从脚本中的前一帧获取数据

要从脚本中的前一帧获取数据,例如MonoBehaviour,请执行以下作:

  1. 使用可编写脚本的渲染管线(SRP)核心RequestAccessAPI 来请求纹理。
  2. 使用UniversalAdditionalCameraData.historyAPI 来获取数据。

要确保 Unity 首先完成帧渲染,请使用UniversalAdditionalCameraData.historyAPI 中的LateUpdate方法。

有关更多信息,请参阅可编写脚本的渲染管线(SRP)核心包中的以下内容:

从 URP 中的当前帧中获取数据
将纹理添加到相机历史记录中