Импорт текстуры в проход рендеринга в URP
Чтобы сделать текстуру доступной для всех кадров и камер, создайте ее вне системы графов рендеринга, а затем укажите на нее граф рендеринга с помощью ImportTexture API.
Система рендеринга графов не управляет сроком эксплуатации импортированных текстур, поэтому она не может оптимизировать использование текстуры, и могут возникнуть утечки памяти. По возможности, Создайте временную текстуру для одного кадра вместо этого, так что система рендеринга графов управляет его сроком эксплуатации.
Чтобы получить текстуры, созданные URP вместо вашего собственного кода, например, цвет камеры и текстуры глубины, см. Фреймовые данные в графической системе отображения.
Создание текстуры рендеринга
Чтобы создать текстуру один раз, но использовать ее в нескольких кадрах, создайте ее до вызова AddRasterRenderPass. Например:
-
Объявить текстуру с помощью RTHandle API.
Например:
public RTHandle renderTextureHandle; Создайте объект
TextureDescс необходимыми свойствами текстуры.-
Выделить текстуру рендеринга с помощью ReAllocateHandleIfNeeded API. Этот метод проверяет, существует ли текстура рендеринга уже, поэтому создает текстуру рендеринга только один раз.
Например:
RenderingUtils.ReAllocateHandleIfNeeded(ref renderTextureHandle, textureDesc, name: "My render texture");
Направление графа рендеринга на текстуру
Чтобы использовать текстуру после вызова AddRasterRenderPass, используйте ImportTexture API для получения адреса текстуры рендеринга, которую может использовать граф рендеринга. Например:
TextureHandle texture = renderGraph.ImportTexture(renderTextureHandle);
Затем вы можете использовать объект TextureHandle для чтения или записи текстуры рендеринга, и текстура не будет удалена в конце прохождения рендеринга.
Удалить текстуру рендеринга
В конце рендеринга необходимо высвободить память, которую использует текстура рендеринга в конце прохода рендеринга.
Например, можно создать следующий Dispose метод в вашем ScriptableRendererFeature class.
public void Dispose()
{
renderTexture.Release();
}
Пример
Следующая Scriptable Renderer Feature создает текстуру вне системы графов рендеринга, а затем использует ее в проходе рендеринга для рисования случайного треугольника в каждом кадре. Чтобы увидеть текстуру, откройте Frame Debugger и выберите элемент Тестовый проход рендеринга.
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.RenderGraphModule.Util;
using UnityEngine.Rendering.Universal;
using UnityEngine.Experimental.Rendering;
public class RandomTriangles : ScriptableRendererFeature
{
class DrawRandomTriangles : ScriptableRenderPass
{
RTHandle destinationTexture;
class PassData
{
public TextureHandle destination;
public Material material;
}
public DrawRandomTriangles(RTHandle externalTexture)
{
destinationTexture = externalTexture;
}
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameContext)
{
using (var builder = renderGraph.AddRasterRenderPass<PassData>("Test render pass", out var passData))
{
// 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);
// Create a material for drawing a mesh.
passData.material = new Material(Shader.Find("Unlit/Texture"));
// Point the render graph to the external texture.
passData.destination = renderGraph.ImportTexture(destinationTexture);
builder.SetRenderAttachment(passData.destination, 0, AccessFlags.Write);
builder.SetRenderFunc(static (PassData data, RasterGraphContext context) =>
{
// Create a triangle mesh.
Mesh mesh = new Mesh();
Vector3[] vertices = new Vector3[3]
{
new Vector3(0, 0, 0),
new Vector3(1f, 0, 0),
new Vector3(0, 1f, 0),
};
int[] triangles = new int[3]
{
0, 2, 1,
};
mesh.vertices = vertices;
mesh.triangles = triangles;
// Draw the triangle mesh at a random position.
Vector3 randomPos = new Vector3(Random.Range(-10, 10), Random.Range(-10, 10), 0);
Matrix4x4 trs = Matrix4x4.TRS(randomPos, Quaternion.Euler(0, 0, 0), Vector3.one);
context.cmd.DrawMesh(mesh, trs, data.material, 0);
});
}
}
}
DrawRandomTriangles renderPass;
public RTHandle myRenderTexture;
public override void Create()
{
// Allocate a render texture outside the shader graph
TextureDesc textureDesc = new TextureDesc(Vector2.one)
{
colorFormat = GraphicsFormat.R8G8B8A8_UNorm,
width = 256,
height = 256,
clearBuffer = true,
clearColor = Color.red,
name = "My temporary texture"
};
RenderingUtils.ReAllocateHandleIfNeeded(ref myRenderTexture, textureDesc, name: "My render texture");
// Create the render pass and pass in the render texture
renderPass = new DrawRandomTriangles(myRenderTexture);
renderPass.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(renderPass);
}
public new void Dispose()
{
myRenderTexture.Release();
}
}
Дополнительные ресурсы
- Использование системы RTHandle
- Тексты
- Текстура рендеринга
- Настраиваемые текстуры рендеринга