Создание временной текстуры для одного кадра в URP
Чтобы создать временную текстуру в системе графов рендеринга, используйте метод CreateTexture экземпляра графа рендеринга.
Когда вы создаете текстуру внутри прохода рендеринга, система графов рендеринга управляет созданием и удалением текстуры. Этот процесс означает, что текстура может не существовать в следующем кадре, и другие камеры могут не использовать ее. Чтобы убедиться, что текстура доступна между кадрами и камерами, см. Используйте текстуру в нескольких проходах рендеринга вместо этого.
Когда система рендеринга графиков оптимизирует конвейер рендеринга, она может не создавать текстуру, если окончательный кадр не использует текстуру, чтобы уменьшить использование памяти и пропускной способности проходов рендеринга.
Создание временной текстуры
В течение RecordRenderGraph метод вашего ScriptableRenderPass класс, выполните следующие шаги:
Создайте объект
TextureDescс необходимыми свойствами текстуры.Используйте методы
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);
}
}
}