Uniform Block 与 Shader Storage Buffer

特性 Uniform Block (uniform) Shader Storage Buffer (buffer)
设计用途 少量、高频更新的"参数" 大量、任意大小的"数据"
大小限制 很小 很大(可达显存上限)
读写权限 只读 可读可写
布局规则 std140 std430(默认) 或 std140
硬件存储位置 常量寄存器 / 专用 UBO Cache 全局显存(走通用内存总线)
访问速度 极快(专用硬件路径) 较慢(通用内存访问,有缓存但延迟高)
原子操作 不支持 支持
绑定数量 较少 较多
典型数据 MVP矩阵、光照参数、材质属性 顶点/粒子数据、计算结果、大型查找表
  • Uniform = “配置参数” 可以理解成函数的入参。数据量小、每帧可能变、所有着色器线程读同一份值。GPU 有专门的常量缓存来加速它,所以快,但也因此容量受限且只读。
  • Buffer (SSBO) = “数据仓库” 可以理解成函数的堆内存指针。可以存任意大小的数据,着色器既能读也能写(包括原子操作),适合做 GPGPU 计算、粒子模拟、间接绘制命令等。代价是走通用显存总线,延迟比 UBO 高。

std430 与 std140 对齐差异

规则 std140 std430
数组元素对齐 一律按 vec4 (16B) 按元素自身类型对齐(float=4, vec2=8, vec3=16…)
结构体基对齐 一律按 vec4 (16B) 取成员中最大对齐值(不再强制16)
其他所有规则 ⚠️ 与 std140 完全相同

std430 数组和结构体不再强制 vec4 对齐,改为"自然对齐",也只改了这两个。


SSBO(Shader Storage Buffer Object)

GLSL 声明

GLSL
// 使用 std430 布局,绑定到 Binding Point 0
layout(std430, binding = 0) buffer ExampleBlock {
    float a;
    vec2 b;
    vec3 c;
    float d;
    mat4 e;
} myData; // SSBO 通常建议给一个实例名,方便在 shader 中调用 myData.a
点击展开查看更多

创建 SSBO 并上传数据

CPP
GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(ExampleBlock), &obj, GL_DYNAMIC_DRAW);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
点击展开查看更多

绑定 SSBO

根据 Binding Point 绑定

CPP
// 绑定到 binding = 0
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
点击展开查看更多

版权声明

作者: Cheyne Xie

链接: https://chaim.eu.org/posts/c4522cf2/

许可证: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

开始搜索

输入关键词搜索文章内容

↑↓
ESC
⌘K 快捷键