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

Получить текущий кадровый буфер из GPU памяти в URP

Для более эффективного чтения кадра, который Unity рендировал в предыдущем проходе, используйте SetInputAttachment API, чтобы установить выход одного прохода рендеринга в качестве входа следующего прохода рендеринга.

Использование SetInputAttachment означает, что рендерный проход может получить доступ к кадровому буферу из чиповой памяти GPU, а не из видеопамяти. Это ускоряет рендеринг, потому что GPU не нужно копировать текстуру в видеопамять и из нее. Этот процесс иногда называется framebuffer fetch.

На мобильных устройствах скорость рендеринга повышается на мобильных устройствах, которые используют отложенное рендеринг на основе плиток (TBDR). GPU сохраняет кадр в памяти плиток на чипе между проходами рендеринга, используя меньшую пропускную способность памяти и время обработки.

Если вы используете SetInputAttachment API, URP объединяет прохождения рендеринга, которые записывают в framebuffer и читают из него. Вы можете проверить это в окне Render Graph Viewer.

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

Потребности в ресурсах

SetInputAttachment API поддерживается, если вы используете одну из следующих графиков APIs:

  • Vulkan
  • Metal

Если вы используете SetInputAttachment с неподдерживаемым API, Unity копирует текстуру в видеопамять и из нее, поэтому скорость рендеринга не меняется.

Используйте SetInputAttachment API

Чтобы использовать SetInputAttachment API в проходе рендеринга, используйте следующее:

  • SetInputAttachment API для установки выхода предыдущего рендеринга в качестве входа нового рендеринга.
  • Макрос LOAD_FRAMEBUFFER_X_INPUT в коде шейдера фрагмента для чтения пикселей из предыдущего прохода рендеринга, вместо макроса выборки, такого как SAMPLE_TEXTURE2D.

Следующие шаги предполагают, что у вас уже есть один проход рендеринга, который записывает в TextureHandle, называемый sourceTextureHandle.

  1. Создайте пользовательский шейдер, а затем создайте материал из шейдера. Более подробную информацию о создании пользовательского шейдера см. в Запись пользовательских шейдеров.

  2. В HLSLPROGRAM вашего пользовательского шейдера убедитесь, что вы импортировали файл Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl:

    HLSLPROGRAM
    ...
    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    ...
    ENDHLSL
    
  3. Внутри HLSLPROGRAM используйте один из следующих способов для объявления текстуры из предыдущего прохода рендеринга. Например:

    • FRAMEBUFFER_INPUT_X_HALF
    • FRAMEBUFFER_INPUT_X_FLOAT
    • FRAMEBUFFER_INPUT_X_INT
    • FRAMEBUFFER_INPUT_X_UINT

    Например:

    FRAMEBUFFER_INPUT_X_HALF(0);
    
  4. В функции фрагмента используйте LOAD_FRAMEBUFFER_X_INPUT для выборки текстуры из памяти GPU на чипе. Например:

    half4 frag() : SV_Target
    {
        half4 colorFromPreviousRenderPass = LOAD_FRAMEBUFFER_X_INPUT(0, input.positionCS.xy);
        return colorFromPreviousRenderPass;
    }
    
  5. В новом проходе рендеринга графика рендеринга добавьте созданный материал к вашему PassData. Например:

    class PassData
    {
        public Material exampleMaterial;
    }
    
  6. Используйте builder.SetInputAttachment, чтобы установить выход предыдущего прохода рендеринга в качестве входа нового прохода рендеринга. Например:

    builder.SetInputAttachment(sourceTextureHandle, 0, AccessFlags.Read);
    
  7. В вашем методе SetRenderFunc используйте такую команду, как BlitTexture, для рендеринга с использованием материала. Например:

    static void ExecutePass(PassData data, RasterGraphContext context)
    {
        Blitter.BlitTexture(context.cmd, new Vector4(1, 1, 0, 0), exampleMaterial, 1);
    }
    

Пример

Полный пример см. в примере, названном FrameBufferFetch в рендеринговой графической системе URP образцы пакета.

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