c++ - 为什么在向着色器存储缓冲区发送结构时会收到垃圾数据?
问题描述
我正在使用 c++ 开发基于 opengl 的光线追踪器应用程序。我想将数据从 cpu 端发送到片段着色器。数据是包围体层次结构 (BVH) 树。不幸的是,在着色器方面,当我尝试使用 gl_fragcolor 将坐标写为颜色时,我得到了垃圾数据。我不知道为什么。任何帮助表示赞赏。
我在 CPU 端有这个结构:
struct FlatBvhNode {
glm::vec4 min;
glm::vec4 max;
int order;
bool isLeaf;
bool createdEmpty;
vector<glm::vec4> indices;
FlatBvhNode() { }
FlatBvhNode(glm::vec3 min, glm::vec3 max, int ind, bool isLeaf, bool createdEmpty, vector<glm::vec3> indices) {
this->min=glm::vec4(min.x, min.y, min.z, 1.0f);
this->max=glm::vec4(max.x, max.y, max.z, 1.0f);
this->order=ind;
this->isLeaf=isLeaf;
this->createdEmpty=createdEmpty;
indices.reserve(2);
for (int i = 0; i < indices.size(); i++) {
this->indices.push_back(glm::vec4(indices.at(i).x, indices.at(i).y, indices.at(i).z, 1));
}
}
};
我想在片段着色器中接收上述结构:
struct FlatBvhNode{ //base aligment aligned offset
vec3 min; // 16 byte 0
vec3 max; // 16 byte 16
int order; // 4 byte 20
bool isLeaf; // 4 byte 24
bool createdEmpty; // 4 byte 28
vec3 indices[2]; // 32 byte 32
};
我不确定对齐的偏移量是否正确。我读过 vec3s 被视为 16 个字节,布尔值和整数被视为 4 个字节。其次,对齐的偏移量必须等于或倍于基本对齐。
我用这些代码发送上述结构:
vector<BvhNode::FlatBvhNode>* nodeArrays=bvhNode.putNodeIntoArray();
unsigned int nodesArraytoSendtoShader;
glGenBuffers(1, &nodesArraytoSendtoShader);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, nodesArraytoSendtoShader);
glBufferData(GL_SHADER_STORAGE_BUFFER, nodeArrays->size() * sizeof(BvhNode::FlatBvhNode), nodeArrays, GL_STATIC_DRAW);
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 2, nodesArraytoSendtoShader, 0, nodeArrays->size() * sizeof(BvhNode::FlatBvhNode));
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
解决方案
当您指定Shader Storage Buffer Object时,您必须使用std430
限定符。
请参阅OpenGL 4.6 API 核心配置文件规范;7.6.2.2 标准统一块布局。
如果要在着色器中使用以下数据结构:
struct FlatBvhNode
{
// base aligment aligned offset
vec4 min; // 16 byte 0
vec4 max; // 16 byte 16
int order; // 4 byte 32
int isLeaf; // 4 byte 36
int createdEmpty; // 4 byte 40
vec4 indices[2]; // 32 byte 48
};
layout(std430) buffer TNodes
{
FlatBvhNode nodes[];
}
那么你必须考虑,那indices
是一个 type 的数组vec4
。因此indices
对齐到 16 个字节。
这对应于c ++中的以下数据结构
struct FlatBvhNode {
glm::vec4 min;
glm::vec4 max;
int order;
int isLeaf;
int createdEmpty;
int dummy; // alignment
std::array<glm::vec4, 2> indices;
}
注意,虽然std::vector
封装了动态大小的数组,但std::array
封装了固定大小的数组。std::array<glm::vec4, 2>
对应于glm::vec4[2]
,但std::vector<glm::vec4>
更像是glm::vec4*
一些额外的尺寸信息。
推荐阅读
- javascript - 将事件从子组件引发到 Vue.js 中的容器组件?
- sql - 在 Postgres 中按月检索在职员工
- amazon-web-services - AWS CloudWatch 触发 CodePipeline 执行在一个账户中有效,但在另一个账户中无效
- back4app - 是否可以在我的 Back4App 应用程序中强制“仅 https”?
- c# - .Net Core 2.1 Identity - 参考错误
- python - 将 JSON 字符串映射到 PySpark 中的结构
- php - jcrop - 轮次选择结果
- javascript - 我是编码新手。我需要一个快速的解释
- nhibernate - Nhibernate高效级联删除
- firebase - 缺少 firebase_core/FirebaseCorePlugin.h