繁体   English   中英

理解 Unity 中的 Buffer 和 SetBuffer 方法

[英]Understanding Buffer and SetBuffer method in Unity

我不明白为什么 ComputeShader 的 _Positions 属性作为 material.SetBuffer 的参数给出。

我认为SetSomething(property, value)方法为属性赋予了价值。

但是在这种情况下, _Positions属性是 ComputeShader 的变量,那么将其赋予material的含义是什么?

经验表明,代码实际上存储了material的位置。 它是如何以及为什么这样做的?

我想我遗漏了一些关于 Buffers 的基本知识。

它与 ShaderGraph 的 Position 节点输入来自哪里有关吗?

C# 代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GPUGraph : MonoBehaviour
{
    [SerializeField]
    ComputeShader computeShader;
    static int positionID = Shader.PropertyToID("_Positions");
 // _Positions poperty in computeShader
 // RWStructuredBuffer<float3> _Positions;
 // Some position data saved in _Positions property

    [SerializeField]
    Material material;

    [SerializeField]
    Mesh mesh;

    ComputeBuffer positionBuffer;
    const int MaxResolution = 10;

    void OnEnable() {
        positionBuffer = new ComputeBuffer(MaxResolution * MaxResolution, 3 * 4);

    }
    
    void OnDisable() {
        positionBuffer.Release();
        positionBuffer = null;
    }
    void Update() {
        UpdateFunctionOnGPU();
    }

    void UpdateFunctionOnGPU() {        
        computeShader.SetBuffer(0, positionID, positionBuffer);

        int groups = Mathf.CeilToInt(MaxResolution / 8f);

        computeShader.Dispatch(0, groups, groups, 1);

        material.SetBuffer(positionID, positionBuffer);

        var bounds = new Bounds(Vector3.zero, Vector3.one * (2f + 2f / resolution));
        Graphics.DrawMeshInstancedProcedural(mesh, 0, material, bounds, resolution * resolution);
    }
}

应用于材质的 ShaderGraph

为了让您自己清楚,您应该了解着色器和材质是什么。

着色器- 是一种程序,在 GPU 上执行。 它不同于用 C#、Java 或其他东西编写的 CPU 常规程序。 大多数着色器是用类 C 语言(Unity 中的HLSL )编写的。 还有一些无代码工具,例如 Unity 中用于创建着色器的Shader Graph 着色器用于在屏幕上绘制一些东西。

Material - 是一个抽象的概念,它代表了一个……我认为它可以称为着色器实例。 换句话说,它是一个结构,包含有关应该执行哪个着色器以及使用哪些参数的数据,以及可能有关着色器执行的其他一些数据。

并谈到缓冲区。 正如我所说,着色器不同于常规的 CPU 程序。 而且,要执行它,您应该执行三个一般步骤。

  1. 在 GPU 上加载此程序
  2. 加载应由该程序处理的数据(该程序的参数)。
  3. 说 GPU 来执行这个程序。

如果您有低级别网络开发或不同类型的硬件组件交互的经验,您就会知道,缓冲区是从组件到组件或从计算机到计算机传递任何数据的主要方式。 因此,要将任何数据传递给 GPU,您应该将其放在具体缓冲区中。 它可以是可执行代码、参数或某些控制指令的缓冲区。 有时有一个缓冲区用于多个目标,您应该知道缓冲区中的哪些字节位置是您需要的。

Unity 封装了您的所有这些员工。 实际上,您只能使用材料。 在您的代码中,您有positionID = Shader.PropertyToID("_Positions") 对于 Unity,它是缓冲区的指示符,应将其加载到 GPU 以使其理解,该数据应作为"_Positions"变量处理。 然后执行material.SetBuffer(positionID, positionBuffer); 并且,通常,链接您为该指标创建的缓冲区。 在你这样做之后(不是立即,但可能在 Unity 执行管道的渲染步骤中),这个positionBuffer将被加载到 GPU 并将作为_Position变量处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM