我正在使用 Qt3d(不是 QML)使用 PySide6 编写 3d 游戏关卡编辑器。我偶然发现了一个问题 - 我不知道如何使用 Qt3d 创建统一缓冲区对象。基本上我想将灯光列表传递给着色器程序。
以下是我的 UBO 的定义:
struct SunInfo {
vec3 direction;
vec3 color;
float intensity;
}
struct LightInfo {
vec3 position;
vec3 rotation;
vec3 color;
float cone_inner;
float cone_outer;
float radius;
}
uniform SunInfo sun;
uniform LightInfo lights[MAX_NUM_LIGHTS];
我尝试在互联网上搜索示例...只有关于如何创建单值制服(QParameter)的解释。我在上面的单块 SunLight 上尝试过 - 我创建了一个 QBuffer 并将其分配给一个名称为“sun”的 QParameter,但这不起作用。没有错误——只是没有结果。如果我将太阳参数作为单个值传递,则着色器可以工作,但对于其他灯光数组来说这是不可能的。
我弄清楚了我的问题是什么 - 在我的 Python 代码中,我创建了一个实例名称为“sun”的 QParameter。它应该是 UBO 区块名称 - “SunInfo”。
我遇到的另一个问题是缓冲区本身的打包。我必须阅读所有布局限定符,但发现我的 SunInfo 块(vec3、vec3、float)必须打包为 32 字节,格式为“3f 4x 3f f”。基本上第一个 vec3 后面跟着 4 个字节的填充,而后面的 vec3 与一个浮点一起打包成 16 个字节。
我不知道是否有办法查询 Qt3d 中块成员的偏移量,就像您可以使用 OpenGL API 本身一样。因此,我将着色器内的块定义切换为:
layout (std140, binding=auto) uniform SunInfo {
vec3 direction;
vec3 color;
float intensity;
}sunInfo;
标准化布局。以防不同 GPU 卡上的布局有所不同。