Получить данные из предыдущих кадров в URP
Чтобы получить предыдущие кадры, которые камера рендировала в Universal Render Pipeline (URP), используйте UniversalCameraData.historyManager API. Эти текстуры иногда называют текстурами истории или буферами истории.
Кадры являются выходом конвейера рендеринга GPU, поэтому они не включают никакую обработку, которая происходит после рендеринга GPU, такую как эффекты пост-обработки.
Чтобы получить предыдущие кадры вне сценария, см. Получить данные из предыдущих кадров в сценарии.
Выполните следующие действия:
-
В методе
RecordRenderGraphполучаем объектUniversalCameraDataиз объектаContextContainer. Например:public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameContext) { UniversalCameraData cameraData = frameContext.Get<UniversalCameraData>(); } -
Чтобы запросить доступ к текстурам цвета или текстурам глубины в истории отображения, используйте
RequestAccessAPI. Например:// Request access to the color textures cameraData.historyManager.RequestAccess<RawColorHistory>();Используйте
RawDepthHistoryвместо этого, чтобы запросить доступ к текстурам глубины. -
Получить одну из предыдущих текстур. Например:
// 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); -
Преобразовать текстуру в ручку, которую может использовать графическая система рендеринга. Например:
passData.historyTexture = renderGraph.ImportTexture(historyTexture);
Затем вы можете прочитать текстуру в проходе рендеринга.
Для получения дополнительной информации об использовании historyManager API, см. UniversalCameraData.historyManager.
Пример
Ниже приведена функция Scriptable Renderer, которая создает материал и использует предыдущий кадр в качестве текстуры материала.
Чтобы использовать пример, выполните следующие действия:
- Создайте шейдер URP, который семплирует текстуру под названием
_BaseMap. Пример см. в Рисование текстуры. - Создать материал из шейдера.
- Создайте новый скрипт C# под названием
RenderLastFrameInMaterial.cs, вставьте в него следующий код и сохраните файл. - В активном рендере URP добавьте Скриптовую Функцию Рендера.
- В окне Inspector активного рендера URP, в разделе Рендировать последний кадр в материале Особенности Скриптового Рендерера, добавленной на шаге 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;
class PassData
{
public Material material;
public 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, выполните следующие действия:
- Используйте Scriptable Render Pipeline (SRP) Core
RequestAccessAPI для запроса текстуры. - Используйте
UniversalAdditionalCameraData.historyAPI для получения данных.
Чтобы убедиться, что Unity завершает рендеринг кадра первым, используйте UniversalAdditionalCameraData.history API в методе LateUpdate.
Дополнительные сведения см. в следующих разделах пакета Core Scriptable Render Pipeline (SRP):
ICameraHistoryReadAccessIPerFrameHistoryTracker