OpenGL使用统一缓冲区作为数组

Posted

技术标签:

【中文标题】OpenGL使用统一缓冲区作为数组【英文标题】:OpenGL use uniform buffer as an array 【发布时间】:2021-06-27 16:37:37 【问题描述】:

我发现我可以像这样使用统一缓冲区来存储多个变量

#version 330 core
layout (location = 0) in vec3 aPos;

layout (std140) uniform Matrices

    mat4 projection;
    mat4 view;
;

uniform mat4 model;

void main()

    gl_Position = projection * view * model * vec4(aPos, 1.0);
  

并像对待任何其他缓冲区一样对待这些数据


unsigned int uboMatrices
glGenBuffers(1, &uboMatrices);
  
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
  
glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));

但是,我似乎找不到任何可以让我将此类缓冲区视为数组的示例。本质上我想实现这样的全局随机访问缓冲区

#version 330 core
layout (location = 0) in vec3 aPos;

layout (what here?) uniform float[] globalBuffer;

uniform mat4 model;

void main()

    ...
  

长期计划是稍后使用 OpenCL 生成这个数组

【问题讨论】:

【参考方案1】:

uniform float[] globalBuffer; 不是统一缓冲区。它只是一组制服。你必须用glUniform1fv设置制服。

Uniform block 将是:

layout (std140) uniform Foo 
 
    float[] globalBuffer; 

不幸的是,在这种情况下,每个数组元素都将与vec4 的大小对齐。见OpenGL 4.6 API Core Profile Specification; 7.6.2.2 Standard Uniform Block Layout:

    如果成员是标量或向量数组,则根据规则 (1)、(2) 和 (3) 设置基本对齐方式和数组步幅以匹配单个数组元素的基本对齐方式,并且四舍五入到vec4的基本对齐方式

我建议使用Shader Storage Buffer Object

layout (std430) buffer Foo

    float[] globalBuffer; 
;

OpenGL 4.6 API Core Profile Specification; 7.6.2.2 Standard Uniform Block Layout:

着色器存储块(参见第 7.8 节)还支持 std140 布局限定符,以及统一块不支持的 std430 限定符。当使用std430 存储布局时,着色器存储块在缓冲存储中的布局与使用std140 布局的统一和着色器存储块相同,除了数组的基本对齐方式和步幅规则 4 中的标量和向量以及规则 9 中的结构不会向上取整为 vec4 的基本对齐方式的倍数

【讨论】:

以上是关于OpenGL使用统一缓冲区作为数组的主要内容,如果未能解决你的问题,请参考以下文章

我的OpenGL学习进阶之旅统一变量和属性

我的OpenGL学习进阶之旅统一变量和属性

OpenGL GLSL 统一缓冲区对象

在交错的 openGL 顶点缓冲区对象之间复制

OpenGL更新顶点数组/缓冲区

我的OpenGL学习进阶之旅介绍顶点缓冲区对象VBO和元素数组缓冲区对象EBO,并对比使用VBO和不使用VBO绘制三角形的效果