WebGL2 中统一缓冲区的问题
Problems with Uniform Buffers in WebGL2
我正在尝试将一些 OpenGL 代码移植到 WebGL2,但我在使用统一缓冲区时遇到了一些问题。我使用缓冲区附加到的着色器渲染的所有内容都不再显示。我在控制台中没有收到任何错误或警告。这是我的代码:
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;
};
下次请善待我们,让我们不必手动制作回购协议!谢谢♂️
当我 运行 你的代码在 Chrome 我得到
:GL_INVALID_OPERATION : glDrawArrays: uniform buffers : buffer or buffer range at index 0 not large enough
问题是存在填充和对齐问题
请参阅 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>
我正在尝试将一些 OpenGL 代码移植到 WebGL2,但我在使用统一缓冲区时遇到了一些问题。我使用缓冲区附加到的着色器渲染的所有内容都不再显示。我在控制台中没有收到任何错误或警告。这是我的代码:
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;
};
下次请善待我们,让我们不必手动制作回购协议!谢谢♂️
当我 运行 你的代码在 Chrome 我得到
:GL_INVALID_OPERATION : glDrawArrays: uniform buffers : buffer or buffer range at index 0 not large enough
问题是存在填充和对齐问题
请参阅 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>