使用统一缓冲区对象进行批处理渲染
Batched rendering with Uniform Buffer Object
我正在更改我的基本渲染器,使其成为批处理渲染器以提高性能。我已经成功地更改了顶点数据以在单个批次中绘制所有网格,但是当我想处理多个材质时,就会出现问题。
显然,我不能使用普通uniforms
,因为我要批处理大量网格,因此我想使用统一缓冲区对象来存储所有材质数据。
问题是,如何更新此缓冲区?
如果我像这样设置我的 UBO:
layout(std140) uniform MATERIAL
{
vec4 Color[20];
float Specular[20];
float Roughness[20];
float Metallic[20];
float ReflectionIntensity[20];
};
我不认为那么,当我提交单个材料的数据时,我可以使用基于材料指数计算的起始偏移量并提交这样的数据:
struct Material {
float color[4];
float specular;
float roughness;
float metallic;
float reflectionIntensity;
};
int bufferStride = 32; // 16 (vec4) + 4 (float) + 4 (float) + 4 (float) + 4 (float)
int offset = bufferStride * updatingMaterialIndex;
Material m;
m.color...
glBufferSubData(GL_UNIFORM_BUFFER, offset, &m, sizeof(Material));
因为我认为 OpenGL 的内存中将有 20 vec4
后跟 80 float
。
那我该怎么做呢?我必须单独计算每个元素的偏移量吗?
另外,我应该如何索引网格使用的材质?我应该将材质索引作为顶点属性传递吗?
您最初的建议是使用包含数组的结构。那么为什么不做相反的事情:一个包含结构的数组呢?
struct Material
{
vec4 Color;
float Specular;
float Roughness;
float Metallic;
float ReflectionIntensity;
}
layout(std140) uniform Materials
{
Material mtls[20];
};
然后,您将在 CPU 上构建类似的阵列。
现在要执行此操作,必须确保遵循std140
的对齐规则。特别重要的是结构和阵列的对齐。由于Material
有一个vec4
,因此其基本对齐方式为 16。数组元素之间的步幅必须是数组元素基本对齐方式的倍数。
因此,mtls[20]
的大小为 32 * 20 字节。即使您从Material
中删除了一个浮点数,它仍然是该大小。
如果您真的想保留数组结构方法,您只需要在 CPU 上使用相应的数据结构。
相关文章:
- 如何在 SEAL 3.1 中使用 CRT 批处理技术Microsoft?
- 批处理归一化层构造
- 多 GPU 批处理 1D FFT:似乎只有一个 GPU 可以工作
- 我们在批处理模式下使用 G++ 时遇到错误
- 如何在 c++ 窗口中将参数和返回的退出值传递到批处理文件/从批处理文件获取返回的退出值
- 从之前添加的批处理文件中删除单词
- 使用qprocess将参数传递给批处理
- 从批处理中提取矩阵,表示为张量
- 无法从C++ Windows 服务执行批处理文件
- 我将如何在C++中文件处理对象(存储/导入)
- 如何将批处理文件的输出读取到C 中的字符串中
- cmake:生成批处理文件调用cl.exe
- 是否可以使用开发控制台使用批处理脚本编译 c++
- 用于批处理分配的库
- 在调用进程的上下文中通过 win32 执行批处理,从而保留环境变量
- 如何运行批处理文件和读取输出
- 嵌入批处理脚本文件并在C 控制台项目中运行
- GetCommandLine():无法从批处理文件(GCC-Compiler)传递多行参数
- AWS 批处理"unable to connect to endpoint"
- 使用统一缓冲区对象进行批处理渲染