【问题标题】:Problems with Uniform Buffers in WebGL2WebGL2 中的统一缓冲区问题
【发布时间】:2020-11-01 09:48:09
【问题描述】:

我正在尝试将一些 OpenGL 代码移植到 WebGL2,但我遇到了 Uniform Buffers 的一些问题。我使用缓冲区附加到的着色器渲染的所有内容都不再显示。我在控制台中没有收到任何错误或警告。这是我的代码:

var data = new Float32Array(1);
data[0] = 1.0;

var uniformBuffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
gl.bufferData(gl.UNIFORM_BUFFER, 4, gl.STATIC_DRAW);
gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, uniformBuffer, 0, 4);

gl.uniformBlockBinding(mapShader.getProgram(), gl.getUniformBlockIndex(mapShader.getProgram(), "test"), 0);


gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
gl.bindBuffer(gl.UNIFORM_BUFFER, null);

一旦我将它添加到我的着色器中,我之前描述的问题就会出现:

layout (std140) uniform test {
    float testFloat;
};

【问题讨论】:

    标签: javascript webgl webgl2


    【解决方案1】:

    下次请善待我们,让我们不必手动进行回购!谢谢?‍♂️

    当我在 Chrome 中运行您的代码时,我得到了

    :GL_INVALID_OPERATION : glDrawArrays: 统一缓冲区 : 索引 0 处的缓冲区或缓冲区范围不够大

    问题是存在填充和对齐问题

    请参阅the spec 第 2.12.6.4 节

    将缓冲区和范围大小更改为 16 即可。另请注意,BindBufferRange 的有效偏移量有对齐要求,您可以使用gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT) 查找

    const gl = document.querySelector('canvas').getContext('webgl2');
    
    const vs = `#version 300 es
    void main() {
      gl_PointSize = 100.0;
      gl_Position = vec4(0, 0, 0, 1);
    }
    `;
    
    const fs = `#version 300 es
    precision highp float;
    
    layout (std140) uniform test {
        float testFloat;
    };
    
    out vec4 outColor;
    
    void main() {
      outColor = vec4(testFloat, 0, 0, 1);
    }
    `;
    
    const prg = twgl.createProgram(gl, [vs, fs]);
    gl.useProgram(prg);
    const mapShader = {
      getProgram: _ => prg,
    };
    
    var data = new Float32Array(1);
    data[0] = 1.0;
    
    var uniformBuffer = gl.createBuffer();
    gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
    gl.bufferData(gl.UNIFORM_BUFFER, 16, gl.STATIC_DRAW);
    gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, uniformBuffer, 0, 16);
    
    gl.uniformBlockBinding(mapShader.getProgram(), gl.getUniformBlockIndex(mapShader.getProgram(), "test"), 0);
    
    
    gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
    gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
    gl.bindBuffer(gl.UNIFORM_BUFFER, null);
    
    gl.drawArrays(gl.POINTS, 0, 1);
    <script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
    
    <canvas></canvas>

    【讨论】:

    • 感谢成功,我测试了一下,每增加一个浮点数,大小就增加了 4 对吗?
    • 浮点数被填充到 vec4 中,因此 1 个浮点数为 16 字节,2 个浮点数为 16 字节,4 个为 16 字节,5 个为 32 字节。等等...答案中链接的规范中详细说明了规则。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    相关资源
    最近更新 更多