版本:Unity 6 (6000.0)
语言:English
在 URP 中获取当前帧的数据
向相机历史记录添加纹理

在 URP 中获取上一帧的数据

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

帧是 GPU 渲染管线的输出,因此它们不包含 GPU 渲染后发生的任何处理,例如后期处理在图像显示在屏幕上之前应用滤镜和效果来改善产品视觉效果的过程。例如,您可以使用后期处理效果来模拟物理相机和胶片属性,例如 Bloom 和景深。 更多信息 后期处理, 后期处理, 后处理
参见 术语表
效果。

要从可脚本化的渲染传递之外获取上一帧,请参阅在脚本中获取上一帧的数据

请按照以下步骤操作

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

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

    // 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);
    

然后,您可以在渲染传递中读取纹理。

有关使用 historyManager API 的更多信息,请参阅UniversalCameraData.historyManager

示例

以下是创建材质并使用上一帧作为材质纹理的可脚本化渲染功能。

要使用此示例,请按照以下步骤操作

  1. 创建一个采样名为 _BaseMap 的纹理的 URP着色器在 GPU 上运行的程序。 更多信息
    参见 术语表
    。有关示例,请参阅绘制纹理
  2. 从着色器创建材质。
  3. 创建一个名为 RenderLastFrameInMaterial.cs 的新 C# 脚本,将以下代码粘贴到其中,然后保存文件。
  4. 在活动 URP 渲染器中,添加可脚本化渲染功能
  5. 在活动 URP 渲染器的检查器一个 Unity 窗口,显示有关当前选定游戏对象、资源或项目设置的信息,允许您检查和编辑值。 更多信息
    参见 术语表
    窗口中,在您在步骤 4 中添加的可脚本化渲染功能的渲染材质中的上一帧部分中,将您在步骤 2 中创建的材质分配给对象材质字段。
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) Core 的RequestAccess API 请求纹理。
  2. 使用UniversalAdditionalCameraData.history API 获取数据。

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

有关更多信息,请参阅可脚本化渲染管线 (SRP) Core 包中的以下内容

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