计算着色器中的数组值无效?

发布于 2025-01-11 03:52:52 字数 705 浏览 0 评论 0原文

我使用一个缓冲区来传递我的 C++ 结构

struct Node {
    Node(int size, glm::ivec3 position);

    bool isEmpty();
    int getSubIndex(const glm::ivec3& vec);
    void divide(std::vector<Node> &nodes);
    void setColor(glm::vec4 color);
    int getSubNodeIndex(const glm::ivec3& vec);
    int getSubNodeIndex(int subIndex);

    glm::ivec4 position;
    glm::vec4 color;
    int halfSize;
    int sub;
    int leaf;
};

在着色器中它看起来像这样

struct Node {
    vec4 position;
    vec4 color;
    int data[3];
};

layout(std430, binding=4) readonly buffer Octree_data {
    Node nodes[];
};

在计算过程中,我发现在数组的所有元素中(第一个元素除外)都有不正确的数据(很可能被替换)我可能会犯什么错误?

I use a buffer to which I pass my C++ structures

struct Node {
    Node(int size, glm::ivec3 position);

    bool isEmpty();
    int getSubIndex(const glm::ivec3& vec);
    void divide(std::vector<Node> &nodes);
    void setColor(glm::vec4 color);
    int getSubNodeIndex(const glm::ivec3& vec);
    int getSubNodeIndex(int subIndex);

    glm::ivec4 position;
    glm::vec4 color;
    int halfSize;
    int sub;
    int leaf;
};

In the shader it looks like this

struct Node {
    vec4 position;
    vec4 color;
    int data[3];
};

layout(std430, binding=4) readonly buffer Octree_data {
    Node nodes[];
};

In the process of calculations, I find out that in all elements of the array (except for the first element) there are incorrect data (most likely displaced) in what could I make a mistake?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

等待圉鍢 2025-01-18 03:52:52

Node 结构所需的 std430 对齐方式是 16 字节。这是因为它包含 16 字节对齐类型(vec4ivec4)。因此,Node 数组中的每个数组元素都必须从 16 字节边界开始。因此,nodes 的数组步长必须为 48。

Node 结构的 C++ 对齐方式可能是 4 个字节。这是因为 在 C++ 布局中,您的 Node 结构不需要更高的对齐方式。 GLM 的 4 元素向量类型是 4 字节对齐的(或者更确切地说,它们是浮点对齐的,几乎总是 4 字节)。这意味着 sizeof(Node) 将为 44 字节,数组步长也是 44 字节。

如果您希望 C++ 结构体匹配 GLSL 所需的布局,则需要正确对齐它:

struct Node {
    Node(int size, glm::ivec3 position);

    bool isEmpty();
    int getSubIndex(const glm::ivec3& vec);
    void divide(std::vector<Node> &nodes);
    void setColor(glm::vec4 color);
    int getSubNodeIndex(const glm::ivec3& vec);
    int getSubNodeIndex(int subIndex);

    alignas(16) glm::ivec4 position;
    alignas(16) glm::vec4 color;
    int halfSize;
    int sub;
    int leaf;
};

The std430 required alignment for your Node structure is 16-bytes. This is because it contains a 16-byte-aligned type (vec4 and ivec4). Therefore, every array element in the Node array will have to start at a 16-byte boundary. So the array stride for nodes will have to be 48.

The C++ alignment of your Node structure is probably 4 bytes. This is because nothing in C++'s layout for your Node structure requires higher alignment. GLM's 4-element vector types are 4-byte aligned (or rather, they're float aligned, which is almost always 4 bytes). This means that the sizeof(Node) will be 44 bytes, as will the array stride.

If you want your C++ struct to match the GLSL required layout, you need to align it properly:

struct Node {
    Node(int size, glm::ivec3 position);

    bool isEmpty();
    int getSubIndex(const glm::ivec3& vec);
    void divide(std::vector<Node> &nodes);
    void setColor(glm::vec4 color);
    int getSubNodeIndex(const glm::ivec3& vec);
    int getSubNodeIndex(int subIndex);

    alignas(16) glm::ivec4 position;
    alignas(16) glm::vec4 color;
    int halfSize;
    int sub;
    int leaf;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文