Unity 6.3
0 онлайн 53 гостей 3 в системе
Вход

Создание временной текстуры для одного кадра в URP

Чтобы создать временную текстуру в системе графов рендеринга, используйте метод CreateTexture экземпляра графа рендеринга.

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

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

Создание временной текстуры

В течение RecordRenderGraph метод вашего ScriptableRenderPass класс, выполните следующие шаги:

  1. Создайте объект TextureDesc с необходимыми свойствами текстуры.

  2. Используйте методы CreateTexture экземпляра графа рендеринга для создания текстуры и возврата ручки текстуры.

Например, следующая команда создает текстуру того же размера, что и экран.

UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
TextureDesc textureDesc = resourceData.activeColorTexture.GetDescriptor(renderGraph);
TextureHandle textureHandle = renderGraph.CreateTexture(textureDesc);

Примечание: Не использовать. UniversalRenderer.CreateRenderGraphTexture, потому что он может вводить тонкие ошибки.

Система рендеринга графов управляет жизненным циклом текстур, созданных с помощью CreateTexture, так что вам не нужно вручную удалять память, которую они используют, когда вы закончили с ними.

Проверить, как URP обрабатывает действия загрузки текстуры

Вы можете использовать окно Окно Render Graph Viewer для проверки того, как URP обрабатывает действия загрузки текстур. Это полезно для отладки результатов и подтверждения того, что Unity очищает, сохраняет или отбрасывает текстуру.

Примечание: параметр clear и значение AccessFlags влияют на то, как URP задаёт действие загрузки текстуры. Это может повлиять на результаты рендеринга:

  • Если clear является true и вы используете AccessFlags.WriteAll, то действием загрузки является DontCare, а не Clear. Это потому, что Unity предполагает, что вы перезаписываете всю текстуру, поэтому он пропускает очистку текстуры для оптимизации производительности.
  • Если clear является false и вы используете AccessFlags.Write, то действием загрузки является Clear. Это потому, что Unity автоматически очищает текстуру, чтобы избежать отображения артефактов, если вы записываете только часть текстуры. Чтобы пропустить Unity очищение текстуры, используйте AccessFlags.WriteAll, чтобы явно сообщить Unity, что вы записываете всю текстуру.

Пример

Следующая функция Scriptable Renderer содержит пример прохода рендеринга, который создает текстуру и очищает ее до желтого цвета. Дополнительные сведения о добавлении прохода рендеринга в конвейер рендеринга см. в Вставка прохода с помощью функции Scriptable Renderer.

Используйте Frame Debugger для проверки текстуры, добавленной в ходе рендеринга.

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

public class CreateYellowTextureFeature : ScriptableRendererFeature
{
    CreateYellowTexture customPass;

    public override void Create()
    {
        customPass = new CreateYellowTexture();
        customPass.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(customPass);
    }

    class CreateYellowTexture : ScriptableRenderPass
    {
        class PassData
        {
            public TextureHandle cameraColorTexture;
        }

        public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
        {
            using (var builder = renderGraph.AddRasterRenderPass<PassData>("Create yellow texture", out var passData))
            {
                // Get the frame data
                UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();

                // Create texture properties that match the screen size
                TextureDesc textureDesc = resourceData.activeColorTexture.GetDescriptor(renderGraph);
                textureDesc.msaaSamples = MSAASamples.None;

                // Create a temporary texture
                TextureHandle texture = renderGraph.CreateTexture(textureDesc);

                // Set the texture as the render target
                builder.SetRenderAttachment(texture, 0, AccessFlags.Write);
    
                // Make sure the render graph system keeps the render pass, even if it's not used in the final frame.
                // Don't use this in production code, because it prevents the render graph system from removing the render pass if it's not needed.
                builder.AllowPassCulling(false);

                builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => ExecutePass(data, context));
            }
        }

        static void ExecutePass(PassData data, RasterGraphContext context)
        {          
            // Clear the render target to yellow
            context.cmd.ClearRenderTarget(true, true, Color.yellow);            
        }
    }

}

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