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

Добавить текстуры в историю камеры

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

Создание типа журнала камеры

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

  1. Создайте класс, наследующий CameraHistoryItem. Например:

    public class ExampleHistoryType : CameraHistoryItem {
        ...
    }
    
  2. В этом классе добавьте идентификатор для системы истории камеры. Например:

        private int uniqueId;
    

    Идентификатор представляет собой полную историю текстуры, включая текущий и предыдущие кадры.

    Вы также можете добавить любые другие необходимые данные, например, дескриптор текстуры, который нужно хранить между кадрами.

  3. Переопределить OnCreate метод. В методе, вызвать OnCreate метод родительского класса и сформируйте уникальный идентификатор. Например:

    public override void OnCreate(BufferedRTHandleSystem owner, uint typeId)
    {
        // Call the OnCreate method of the parent class
        base.OnCreate(owner, typeId);
    
        // Generate the unique id
        uniqueId = MakeId(0);
    }
    
  4. Создайте открытые свойства для текущей и предыдущей текстур, чтобы проходы рендеринга могли к ним обращаться. Например:

    public RTHandle currentTexture => GetCurrentFrameRT(uniqueId);
    public RTHandle previousTexture => GetPreviousFrameRT(uniqueId);
    
  5. Выделить память для текстуры. Например:

    // Allocate 2 textures using a texture descriptor, assign them to the uniqueId, and give them a name.
    AllocHistoryFrameRT(uniqueId, 2, ref textureDescriptor, "ExampleHistoryTexture");
    
  6. Реализуйте метод Reset для освобождения текстур истории, когда система истории камеры сбрасывает тип. Например:

    public override void Reset()
    {
        ReleaseHistoryFrameRT(uniqueId);
    }
    

Также может потребоваться перераспределять память для каждого кадра, если проход рендеринга записывает текстуру с другим размером или форматом.

Запись в текстуру

Для записи в созданную текстуру выполните следующие действия:

  1. Чтобы запросить доступ к текстуре в ScriptableRenderPass класс, используйте RequestAccess API с типом истории камеры. Например:

    cameraData.historyManager.RequestAccess<ExampleHistoryType>();
    
  2. Получить текстуру для текущего кадра для записи и преобразовать ее в handle, который может использовать графическая система рендеринга. Например:

    // Get the textures 
    ExampleHistoryType history = cameraData.historyManager.GetHistoryForWrite<ExampleHistoryType>();
    
    // Get the texture for the current frame
    RTHandle historyTexture = history?.currentTexture;
    
    // Convert the texture into a handle the render graph system can use
    historyTexture = renderGraph.ImportTexture(historyTexture);
    

Затем вы можете записать текстуру в свой проход рендеринга. Более подробную информацию см. в Использование текстур.

Читать из текстуры

Чтобы прочитать текстуру, используйте RequestAccess API с созданным типом истории камеры.

Вы должны записать текстуру, прежде чем читать из нее.

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

Примеры

Ниже приведен пример типа истории камеры.

using UnityEngine;
using UnityEngine.Rendering;

public class ExampleHistoryType : CameraHistoryItem
{
    private int m_Id;

    // Add a descriptor for the size and format of the texture.
    private RenderTextureDescriptor m_Descriptor;

    // Add a hash key to track changes to the descriptor.
    private Hash128 m_DescKey;

    public override void OnCreate(BufferedRTHandleSystem owner, uint typeId)
    {
        base.OnCreate(owner, typeId);
        m_Id = MakeId(0);
    }

    // Release the history GPU resources (textures) when the camera history system resets the type.
    public override void Reset()
    {
        ReleaseHistoryFrameRT(m_Id);
    }

    public RTHandle currentTexture => GetCurrentFrameRT(m_Id);
    public RTHandle previousTexture => GetPreviousFrameRT(m_Id);

    // The render pass calls the Update method every frame, to initialize, update, or dispose of the textures.
    public void Update(RenderTextureDescriptor textureDescriptor)
    {
        // Dispose of the textures if the memory needs to be reallocated.
        if (m_DescKey != Hash128.Compute(ref textureDescriptor))
            ReleaseHistoryFrameRT(m_Id);

        // Allocate the memory for the textures if it's not already allocated.
        if (currentTexture == null)
        {
            AllocHistoryFrameRT(m_Id, 2, ref textureDescriptor, "HistoryTexture");

            // Store the descriptor and hash key for future changes.
            m_Descriptor = textureDescriptor;
            m_DescKey = Hash128.Compute(ref textureDescriptor);
        }
    }
}

Ниже приведен пример прохода рендеринга, который записывает текстуру. Вы можете использовать материал URP в качестве materialи Scriptable Renderer Feature для введения прохода рендеринга в конвейер рендеринга.

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule;

class WriteToHistoryTexture : ScriptableRenderPass
{
    // Property for the custom material that writes to the history texture.
    public Material m_Material;

    class PassData
    {
        public Material material;
    }

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

        // Request access to the history texture.
        cameraData.historyManager.RequestAccess<ExampleHistoryType>();
        var history = cameraData.historyManager.GetHistoryForWrite<ExampleHistoryType>();

        if (history != null)
        {
            // Make the history a color-only texture to match the camera target.
            var historyDesc = cameraData.cameraTargetDescriptor;
            historyDesc.depthBufferBits = 0;
            historyDesc.msaaSamples = 1;
            
            // Call the Update method of the camera history type.
            history.Update(historyDesc);

            using (var builder = renderGraph.AddRasterRenderPass<PassData>("Write to history texture", out var passData))
            {
                UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
                RTHandle historyTexture = history?.currentTexture;

                // Set the render graph to render to the history texture.
                builder.SetRenderAttachment(renderGraph.ImportTexture(historyTexture), 0, AccessFlags.Write);

                passData.material = m_Material;

                builder.SetRenderFunc(static (PassData data, RasterGraphContext context) =>
                {
                    // Draw a triangle to the history texture
                    context.cmd.DrawProcedural(Matrix4x4.identity, data.material, 0, MeshTopology.Triangles, 3, 1);
                });
            }
        }
    }
}

Дополнительные ресурсы