Arrays 索引到第二个数组元素总是返回零

Arrays 索引到第二个数组元素总是返回零,arrays,indexing,glsl,vulkan,Arrays,Indexing,Glsl,Vulkan,我有一个UBO,看起来像这样: #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 mode

我有一个UBO,看起来像这样:

#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;
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);
...
}
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);
...
}
每个顶点着色器实例从
uint selection[128]
访问一位,如下所示:

#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;
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);
...
}
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);
...
}

vkm::mat4
是一个具有单个成员浮点arr[16]的类。

std140
布局中,所有数组都有一个元素到元素数组跨距,向上舍入到最接近的
sizeof(vec4)
,即16字节。因此,除非
u32
实际上是一个16字节的结构,
u32选择[128]与您的定义不匹配

您的GLSL需要做的是将
uvec4
数组设置为比其实际大小小4倍的数组,并按如下方式对数组进行索引:

#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;
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);
...
}
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);
...
}
const int num\u selection\u elements=128;
const int num_selection_words=num_selection_elements/4
布局(std140,对齐=16,绑定=0)统一UBO
{
...
uvec4选择[num_selection_words];
}ubo;
void main(){
uint id=gl_实例索引;
uint位索引=id%32;
uint单词索引=(id/32)%4;
uint向量索引=id/(选择字数*32*4);
uint n=ubo.selection[vec_index][word_index];

经过更多测试后,这是对
uvec4
数组的最终正确索引:

uint index = gl_InstanceIndex;
const uint vec_index = index / 128; // 128 = 32 * 4 = vec size
index %= 128;
uint num_index = index / 32;
const uint bit_index = index % 32;
const uint n = ubo.selection[vec_index][num_index];
is_selected = n & (1u << bit_index);
uint index=gl\u InstanceIndex;
const uint vec_index=index/128;//128=32*4=vec size
指数%=128;
uint num_index=index/32;
常量位索引=索引%32;
const uint n=ubo.selection[vec_index][num_index];

是否选择了_=n&(1U)你如何将数据上传到着色器?那就是,你认为C或C++结构是什么?相当于GLSL定义?我附加了C++结构,一个填充问题是我唯一能想到的问题,但是我不知道如何修复/检测它。如果你有问题的答案,用答案加上答案写它。n、 不要将其编辑到您的问题中。谢谢,尽管我已经测试了它,而且选择现在根本不起作用,尽管RenderDoc现在说UBO占用的空间更少。我刚刚醒来,所以如果我有新想法,我会稍后与大家分享。这是一个小应用程序(仅适用于Linux),我应该把它发布到某个地方,以便人们可以尝试编译它吗?RenderDoc说选择数组不是空的,所以可能是数组中的索引..或其他一些错误原因。谢谢!你的答案是正确的,除了vec数组索引,我通过反复尝试最终找到并编辑了我的原始帖子。