索引到第二个数组元素总是返回零 [英] Indexing into 2nd array element always returns zero
问题描述
我有一个看起来像这样的UBO:
I have an UBO that looks like this:
#version 450
#extension GL_ARB_separate_shader_objects : enable
const uint InstanceCount = 64;
layout(std140, align = 16, binding = 0) uniform UBO
{
vec4 array_indices[InstanceCount];
mat4 proj;
mat4 model;
mat4 models[InstanceCount];
uint selection[128];
} ubo;
每个顶点着色器实例都从 uint selection [128]
中访问一位,如下所示:
and each vertex shader instance accesses one bit from uint selection[128]
like this:
layout(location = 1) out uint is_selected;
void main() {
uint id = gl_InstanceIndex;
uint num_index = id / 32;
uint bit_index = id % uint(32);
uint n = ubo.selection[num_index];
is_selected = n & (1u << bit_index);
...
}
问题在于,每当 id
大于31时(即 num_index
为1或更大时), n
始终为零.但是RenderDoc显示 ubo.selection [128]
的前两个 uint
是F0000380和0000000F(这意味着第二个 uint
不为零)),所以我猜想着色器在索引到数组时会遇到问题,因此,除非我索引到数组的第一个元素,否则为什么 n
为零的任何想法?
The problem is that whenever id
is greater than 31 (that is when num_index
is 1 or greater) n
is always zero. But RenderDoc shows that the first 2 uint
s of ubo.selection[128]
are F0000380 and 0000000F (which means the 2nd uint
is not zero), so I'm guessing the shader has problems indexing into the array, so any ideas why n
is zero unless I'm indexing into the first elem of the array?
AMD Polaris10视频卡.
AMD Polaris10 video card.
提供此UBO的C ++结构是:
The C++ structure which feeds this UBO is:
static const u32 InstanceCount = 64;
struct UBO
{
vkm::vec4 array_indices[InstanceCount];
vkm::mat4 proj;
vkm::mat4 model;
vkm::mat4 models[InstanceCount];
u32 selection[128];
};
vkm :: mat4
是一个具有单个成员float arr [16]的类.
vkm::mat4
is a class with a single member float arr[16].
推荐答案
在 std140
布局中,所有数组都有一个元素到元素的数组步长,四舍五入到最接近的 sizeof(vec4)
,即16个字节.因此,除非 u32
实际上是一个16字节结构,否则 u32 selection [128];
与您的定义不匹配.
In std140
layout, all arrays have an element-to-element array stride rounded up to the nearest sizeof(vec4)
, which is 16 bytes. So unless u32
is actually a 16-byte structure, u32 selection[128];
doesn't match with your definition.
您的GLSL需要做的是获取一个 uvec4
数组,其大小是其实际大小的4倍,并像这样对数组进行索引:
What your GLSL needs to do is to take a uvec4
array 4 times smaller than its actual size, and index the array like this:
const int num_selection_elements = 128;
const int num_selection_words = num_selection_elements / 4
layout(std140, align = 16, binding = 0) uniform UBO
{
...
uvec4 selection[num_selection_words];
} ubo;
void main() {
uint id = gl_InstanceIndex;
uint bit_index = id % 32;
uint word_index = (id / 32) % 4;
uint vec_index = id / (num_selection_words * 32 * 4);
uint n = ubo.selection[vec_index][word_index];
is_selected = n & (1u << bit_index);
...
}
这篇关于索引到第二个数组元素总是返回零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!