索引到第二个数组元素总是返回零 [英] Indexing into 2nd array element always returns zero

查看:71
本文介绍了索引到第二个数组元素总是返回零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像这样的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 uints 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆