GLSL:统一缓冲区对象示例
GLSL : uniform buffer object example
我有一个大小可变的GLubyte数组。我想把它传给碎片着色器。我见过这根线和这根线。所以我决定使用"统一缓冲区对象"。但作为GLSL的新手,我不知道:
1-如果我要将此添加到片段着色器,我如何传递大小?我应该创建一个结构吗?
layout(std140) uniform MyArray
{
GLubyte myDataArray[size]; //I know GLSL doesn't understand GLubyte
};
2-在C++代码中如何以及在哪里关联这个缓冲区对象?
3-如何处理铸造GLubyte浮动?
1-如果我要将此添加到片段着色器,我如何传递大小?我应该创建一个结构吗?
使用统一缓冲区(UB),您无法做到这一点
size
必须是静态的,并且在链接GLSL程序时是已知的。这意味着它必须硬编码到实际的着色器中。
解决这一问题的现代方法是使用GL4中名为着色器存储缓冲区(SSB)的功能
SSB可以具有可变长度(最后一个字段可以声明为无大小数组,如myDataArray[]
),并且它们还可以存储比UB多得多的数据。
在旧版本的GL中,您可以使用缓冲区纹理将大量动态大小的数据传递到着色器中,但与SSB相比,这是一种廉价的破解方法,而且您也无法使用类似struct
的界面访问数据。
3-如何处理铸造GLubyte浮动?
你真的根本不会这么做,这要复杂得多
GLSL数据结构中可以使用的最小数据类型是32位。如果需要,您可以使用packUnorm4x8 (...)
等特殊函数将较小的数据块打包和解包到uint
中。这样做是有意的,以避免定义具有较小大小的新数据类型。
即使不使用任何特殊的GLSL函数,也可以执行此操作。
packUnorm4x8 (...)
大致相当于执行以下操作:
for (int i = 0; i < 4; i++)
packed += round (clamp (vec [i], 0, 1) * 255.0) * pow (2, i * 8);
它采用范围为[0,1]的浮点值的4分量矢量,并进行定点运算,将每个浮点值打包为一个无符号归一化(unorm)8位整数,占据uint
的1/4。
GLSL的较新版本引入了可以做到这一点的内部函数,但实际上,只要着色器存在,GPU就一直在做这种事情。无论何时从着色器读取/写入GL_RGBA8
纹理,基本上都是在打包或拆包由32位整数表示的4个8位无序。
- 在 cpp 中的平面缓冲区中序列化对象
- 在共享缓冲区内存中创建 ::std::string 对象
- Opengl 3/4 : 我可以将相同的缓冲区对象绑定到不同的目标吗?
- 绘制一个对象,比较模具缓冲区的两个不同值
- 如何分配适合容纳 T 类型对象的缓冲区(可能过度对齐、可能有运算符 new 等)
- 如何将带有缓冲区的对象从插件发送到节点线程安全
- 使用 OpengGLES2(角度)从帧缓冲区对象读取
- 使用(非对象)API 时改变表数组C++而不重新创建整个平面缓冲区
- 如何将统一缓冲区对象数组加载到着色器中?
- 将矩阵建模为单个统一缓冲区对象
- 如何将图像缓冲区传递到OpenCV垫子对象
- 为什么存储对象地址在缓冲区中会导致内存泄漏并删除它们
- 在C 中,是否有可能在不兼容类型的std ::向量对象之间传输不同类型的缓冲区
- 多采样框架渲染对象和深度缓冲区
- 我是否需要删除传递给谷歌协议缓冲区(protobuf)的对象
- 如何使用 new 和 delete 与 OpenGL 的缓冲区对象一起使用?
- OpenGL:缓冲区对象/着色器超出范围
- OpenGL-缓冲区更新下一个渲染对象
- FlatBuffers C++从缓冲区转换为对象,仅适用于root_type(而Java具有所有)
- 为什么我的顶点缓冲区对象出现访问冲突错误?