Unity 6.3
0 онлайн 96 гостей 3 в системе
Вход
Конвейеры отображения Шаг 94 из 129

Получить данные из предыдущих кадров в URP

Чтобы получить предыдущие кадры, которые камера рендировала в Universal Render Pipeline (URP), используйте UniversalCameraData.historyManager API. Эти текстуры иногда называют текстурами истории или буферами истории.

Кадры являются выходом конвейера рендеринга GPU, поэтому они не включают никакую обработку, которая происходит после рендеринга GPU, такую как эффекты пост-обработки.

Чтобы получить предыдущие кадры вне сценария, см. Получить данные из предыдущих кадров в сценарии.

Выполните следующие действия:

  1. В методе RecordRenderGraph получаем объект UniversalCameraData из объекта ContextContainer. Например:

    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.

Пример

Ниже приведена функция Scriptable Renderer, которая создает материал и использует предыдущий кадр в качестве текстуры материала.

Чтобы использовать пример, выполните следующие действия:

  1. Создайте шейдер URP, который семплирует текстуру под названием _BaseMap. Пример см. в Рисование текстуры.
  2. Создать материал из шейдера.
  3. Создайте новый скрипт C# под названием RenderLastFrameInMaterial.cs, вставьте в него следующий код и сохраните файл.
  4. В активном рендере URP добавьте Скриптовую Функцию Рендера.
  5. В окне 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, выполните следующие действия:

  1. Используйте Scriptable Render Pipeline (SRP) Core RequestAccess API для запроса текстуры.
  2. Используйте UniversalAdditionalCameraData.history API для получения данных.

Чтобы убедиться, что Unity завершает рендеринг кадра первым, используйте UniversalAdditionalCameraData.history API в методе LateUpdate.

Дополнительные сведения см. в следующих разделах пакета Core Scriptable Render Pipeline (SRP):

  • ICameraHistoryReadAccess
  • IPerFrameHistoryTracker