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

Запустить вычислительный шейдер в проходе рендеринга в URP

Чтобы создать проход отображения, в котором запускается вычислительный шейдер, выполните следующие действия:

  1. Настройте проход рендеринга для использования вычислительного шейдера.
  2. Добавить выходной буфер.
  3. Передаёт и выполняет вычислительный шейдер.
  4. Получить выходные данные из буфера выхода.

Чтобы проверить, поддерживает ли платформа вычислительные шейдеры, используйте SystemInfo.supportsComputeShaders API

Настройка прохода отображения для использования вычислительного шейдера

Когда вы создаете ScriptableRenderPass, выполните следующие действия:

  1. Используйте AddComputePass вместо AddRasterRenderPass.
  2. Используйте ComputeGraphContext вместо RasterGraphContext.

Например:

class ComputePass : ScriptableRenderPass
{
    ...

    public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer contextData)
    {
        ...
        // Use AddComputePass instead of AddRasterRenderPass.
        using (var builder = renderGraph.AddComputePass("MyComputePass", out PassData data))
        {
            ...

            // Use ComputeGraphContext instead of RasterGraphContext.
            builder.SetRenderFunc(static (PassData data, ComputeGraphContext context) => ExecutePass(data, context));

            ...
        }
    }
}

Добавление буфера вывода

Чтобы создать буфер, в который будет выводиться вычисление шейдера, выполните следующие действия:

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

    // Declare an output buffer
    public GraphicsBuffer outputBuffer;
    
    // Add a handle to the output buffer in your pass data
    class PassData
    {
        public BufferHandle output;
    }
    
    // Create the buffer in the render pass constructor
    public ComputePass(ComputeShader computeShader)
    {
        // Create the output buffer as a structured buffer
        // Create the buffer with a length of 5 integers, so the compute shader can output 5 values.
        outputBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, 5, sizeof(int));
    }
    
  2. Используйте граф рендеринга ImportBuffer API для преобразования буфера в адрес, который может использовать система графа рендеринга, а затем установите поле BufferHandle в данных прохода. Например:

    BufferHandle outputHandleRG = renderGraph.ImportBuffer(outputBuffer);
    passData.output = outputHandleRG;
    
  3. Используйте метод UseBuffer для установки буфера как буфера с возможностью записи в системе графов отображения.

    builder.UseBuffer(passData.output, AccessFlags.Write);
    

Передача и выполнение вычислительного шейдера

Выполните следующие действия:

  1. Передайте вычислительный шейдер в проход рендеринга. Например, в ScriptableRendererFeature класс, предоставьте ComputeShader свойство, а затем передайте вычислительный шейдер в класс прохода рендеринга.

  2. Добавьте поле ComputeShader к вашим данным прохода и установите его для вычислительного шейдера. Например:

    // Add a `ComputeShader` field to your pass data
    class PassData
    {
        ...
        public ComputeShader computeShader;
    }
    
    // Set the `ComputeShader` field to the compute shader
    passData.computeShader = yourComputeShader;
    
  3. В вашем методе SetRenderFunc используйте SetComputeBufferParam API для присоединения буфера к вычислительному шейдеру. Например:

    // The first parameter is the compute shader
    // The second parameter is the function that uses the buffer
    // The third parameter is the StructuredBuffer output variable to attach the buffer to
    // The fourth parameter is the handle to the output buffer
    context.cmd.SetComputeBufferParam(passData.computeShader, passData.computeShader.FindKernel("Main"), "outputData", passData.output);
    
  4. Используйте DispatchCompute API для выполнения вычислительного шейдера.

    context.cmd.DispatchCompute(passData.computeShader, passData.computeShader.FindKernel("CSMain"), 1, 1, 1);
    

Получить выходные данные из буфера выхода

Для получения данных из буфера вывода используйте GraphicsBuffer.GetData API.

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

Например:

// Create an array to store the output data
outputData = new int[5];

// Copy the output data from the output buffer to the array
outputBuffer.GetData(outputData);

Пример

Полный пример см. в примере Вычисление в графической системе отображения Образцы пакета URP.

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

  • Вычисление шейдеров
  • Запись шейдеров