arrays - 索引到第二个数组元素总是返回零
问题描述
我有一个看起来像这样的 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;
并且每个顶点着色器实例都像这样访问一位uint selection[128]
:
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 显示前 2uint
是ubo.selection[128]
F0000380 和 0000000F (这意味着第二uint
不是零),所以我猜测着色器在索引到数组时有问题,所以任何想法为什么n
是零,除非我索引到数组的第一个元素?
AMD Polaris10 显卡。
提供此 UBO 的 C++ 结构是:
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] 的类。
解决方案
在std140
布局中,所有数组都有一个元素到元素的数组步幅,四舍五入到最接近sizeof(vec4)
的 16 字节。所以除非u32
实际上是一个 16 字节的结构,u32 selection[128];
与你的定义不匹配。
您的 GLSL 需要做的是采用uvec4
比实际大小小 4 倍的数组,并像这样索引数组:
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);
...
}
推荐阅读
- spring-boot - 如何在 Java 中将字节数组上传到 S3 存储桶?
- c++ - 当`this`变成nullptr时,如何在类成员线程中处理quick_exit?
- cefsharp - cefsharp 中是否有 ExcuteDevToolsMethod 的示例?
- c# - 当查询返回值时,OleDbCommand.ExecuteScalar 返回 null
- markdown - 由于代码解析,mdx 中的代码块抛出错误
- javascript - 如何在chrome新标签中实现搜索栏
- php - 在我的 woocommerce 订单列表中显示/隐藏特定类别
- python - 在 Python 日志记录中限制日志文件大小
- arrays - 使用 scanf() 时的指针数组
- java - 如何在文本中的其他一些点显示 MultiAutoCompleteTextView 下拉菜单