我需要将几个可变长度数组传输到着色器。所以我在glsl中建立了一个相当复杂的数据结构,其中包含多个image1D。但我现在无法成功将数据传输到着色器。
片段着色器:
struct HoleArea {
bool clipping;
int mesh_object_id;
layout (rgba32f) image1D anchor_points;
layout (rgba32f) image1D clip_planes;
};
layout (binding = 2) uniform HoleArea hole_area[10];
以及 C++ 代码:
// set the anchor_points in hole_area[0]
glBindBuffer(GL_TEXTURE_BUFFER, m_anchorPointBuffer);
glBufferData(GL_TEXTURE_BUFFER, m_anchorPointPos.size() * sizeof(FLOAT4), &m_anchorPointPos[0], GL_STATIC_DRAW);
glBindBuffer(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_TEXTURE_BUFFER, m_anchorPointTexture);
glTextureBuffer(m_anchorPointTexture, GL_RGBA32F, m_anchorPointBuffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindImageTexture(2, m_anchorPointTexture, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F);
这是我的问题:
image1D 和 imageBuffer 有什么区别?当我需要将一维glm::vec4数组传输到着色器中时,似乎image1D和imageBuffer都可以满足要求。
图像格式有r32f、rg32f、rgba32f。为什么没有 rgb32f 格式来保存 glm::vec3 数据?
对于上面的代码,我应该如何为每个hole_area(hole_area[0],hole_area)设置anchor_points和clip_planes [1]...)。换句话说,我应该如何为每个 image1D 设置 glBindImageTexture 中的第一个变量(图像单元的索引)。
如果有人能回答我的问题,我将非常感激,谢谢!
最佳答案
除非您使用 bindless texturing (如果是,那么您可能已经知道答案),您不能输入 opaque types like images UBO/SSBO 结构内部。
不透明类型只能是松散的统一变量;它们可以排列,但不能成为结构的一部分。
你可以这样做:
layout (binding = 0) uniform image1D hole_anchor_points[10];
layout (binding = 10) uniform image1D hole_clip_planes[10];
数组中的每个制服都有自己单独的位置,从layout
限定符中指定的绑定(bind)
开始。
但是,在单个着色器阶段中可以访问的图像数量是有限的。您想要尝试在一个阶段使用 20 个图像,这可能是exceeds your GPU's limits即使您正确创建了这样的数组。
如果您只想从缓冲区对象读取一些数据,则应该使用 SSBO。 SSBO 中的最后一个元素可以调整大小,从而允许您在其他地方确定其大小。您还可以指定每个数组的开始位置,从而允许您将多个数组放入 SSBO 定义的单个数组中:
layout(binding = 0, std430) readonly buffer anchor_points
{
int arrayIxs[10]; //Index offset to the start of each array.
vec4 array[]; //Unsized. Determined by the size of the bound buffer range.
} hole_anchor_points;
vec4 anchor_point_ix(int arrayIx, int ix)
{
return hole_anchor_points.array[ix + hole_anchor_points.arrayIxs[arrayIx]];
}
What's the difference between image1D and imageBuffer?
一个是一维纹理;另一个是缓冲纹理。一种允许过滤,但有更严格的限制;而另一个总是准确地获取缓冲区中的内容,并且具有更大的限制。
如果您的数据已经在缓冲区中,并且您只想从中读取而不进行过滤,则应该使用缓冲区纹理。
Why there isn't a rgb32f format to save the
glm::vec3
data?
因为硬件不喜欢未对齐的数据读取。
关于c++ - OpenGL -- 如何在 OpenGL 4.5 中处理多个 image1D,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67228464/