Получить текущий кадровый буфер из 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 в проходе рендеринга, используйте следующее:
SetInputAttachmentAPI для установки выхода предыдущего рендеринга в качестве входа нового рендеринга.- Макрос
LOAD_FRAMEBUFFER_X_INPUTв коде шейдера фрагмента для чтения пикселей из предыдущего прохода рендеринга, вместо макроса выборки, такого какSAMPLE_TEXTURE2D.
Следующие шаги предполагают, что у вас уже есть один проход рендеринга, который записывает в TextureHandle, называемый sourceTextureHandle.
Создайте пользовательский шейдер, а затем создайте материал из шейдера. Более подробную информацию о создании пользовательского шейдера см. в Запись пользовательских шейдеров.
-
В HLSLPROGRAM вашего пользовательского шейдера убедитесь, что вы импортировали файл
Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl:HLSLPROGRAM ... #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" ... ENDHLSL -
Внутри HLSLPROGRAM используйте один из следующих способов для объявления текстуры из предыдущего прохода рендеринга. Например:
FRAMEBUFFER_INPUT_X_HALFFRAMEBUFFER_INPUT_X_FLOATFRAMEBUFFER_INPUT_X_INTFRAMEBUFFER_INPUT_X_UINT
Например:
FRAMEBUFFER_INPUT_X_HALF(0); -
В функции фрагмента используйте
LOAD_FRAMEBUFFER_X_INPUTдля выборки текстуры из памяти GPU на чипе. Например:half4 frag() : SV_Target { half4 colorFromPreviousRenderPass = LOAD_FRAMEBUFFER_X_INPUT(0, input.positionCS.xy); return colorFromPreviousRenderPass; } -
В новом проходе рендеринга графика рендеринга добавьте созданный материал к вашему
PassData. Например:class PassData { public Material exampleMaterial; } -
Используйте
builder.SetInputAttachment, чтобы установить выход предыдущего прохода рендеринга в качестве входа нового прохода рендеринга. Например:builder.SetInputAttachment(sourceTextureHandle, 0, AccessFlags.Read); -
В вашем методе
SetRenderFuncиспользуйте такую команду, какBlitTexture, для рендеринга с использованием материала. Например:static void ExecutePass(PassData data, RasterGraphContext context) { Blitter.BlitTexture(context.cmd, new Vector4(1, 1, 0, 0), exampleMaterial, 1); }
Пример
Полный пример см. в примере, названном FrameBufferFetch в рендеринговой графической системе URP образцы пакета.