webGL2统一缓冲区对象和布局的使用(std140)
Posted
技术标签:
【中文标题】webGL2统一缓冲区对象和布局的使用(std140)【英文标题】:Usage of webGL2 Uniform Buffer Object and layout(std140) 【发布时间】:2015-11-22 16:43:20 【问题描述】:我正在做一个 webgl 布料模拟项目,尝试使用变换反馈。模拟将在顶点着色器中完成。我需要访问顶点的相邻顶点来计算力。我正在考虑使用统一缓冲区对象来存储所有顶点的位置。
我定义了一个统一的块,如下所示:
layout(std140) uniform u_testBlock
vec4 v0;
vec4 v1;
...
;
但是,我遇到了“布局:语法错误”。这是在 webGL2 中使用 UBO 的正确方法吗? webGL2规范说统一块只支持std140布局,为什么会出现这样的语法错误?
非常感谢!
【问题讨论】:
我不知道你是否意识到这一点,但是 atm 对 webGL 2 的支持非常低。先检查webglreport.com/?v=2,看看你的浏览器是否支持webGL 2。 您是否声明了适当的 GLSL ES#version
?
【参考方案1】:
您是否在着色器前添加了#version 300 es
?这必须是使用 gls es 3.0 功能的第一行(前面没有空行)
您的精度也必须匹配。
您的示例在 Firefox 中适用于我。 Chrome Canary 版本 54.0.2824.0 似乎已损坏(它曾经可以工作)。我相信它很快就会修复。
var vs = `#version 300 es
// NOTE: We need to mark these as mediump to match
// the fragment shader (or of course we could mark
// the fragment shader's uniform block to highp)
//
layout(std140) uniform u_testBlock
mediump vec4 v0;
mediump vec4 v1;
;
void main()
gl_Position = v0;
`;
var fs = `#version 300 es
precision mediump float;
layout(std140) uniform u_testBlock
vec4 v0;
vec4 v1;
;
out vec4 theColor;
void main()
theColor = v1;
`;
var gl = document.createElement("canvas").getContext("webgl2");
if (!gl)
log ("ERROR: need WebGL 2 support");
var prg = createProgram(gl, [vs, fs]);
log("there should be no errors above");
function log()
var pre = document.createElement("pre");
pre.appendChild(document.createTextNode(Array.prototype.join.call(arguments, " ")));
document.body.appendChild(pre);
function createShader(gl, type, src)
var s = gl.createShader(type);
gl.shaderSource(s, src);
gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS))
log("ERROR:", gl.getShaderInfoLog(s));
return s;
function createProgram(gl, shaders)
var prg = gl.createProgram();
gl.attachShader(prg, createShader(gl, gl.VERTEX_SHADER, shaders[0]));
gl.attachShader(prg, createShader(gl, gl.FRAGMENT_SHADER, shaders[1]));
gl.linkProgram(prg);
if (!gl.getProgramParameter(prg, gl.LINK_STATUS))
log("ERROR:", gl.getProgramInfoLog(prg));
return prg;
【讨论】:
不确定这对阅读本文的人是否有用,但 Canary 57.0.2926.0 仍然提供ERROR: Interface blocks with the same name but different fields/layout: u_testBlock
和上面的示例代码。如果我在顶点着色器中指定precision mediump float;
(即匹配片段着色器),错误就会消失。
谢谢。是的,这个限制是在我写完上述内容之后的某个时候添加的。固定以上是关于webGL2统一缓冲区对象和布局的使用(std140)的主要内容,如果未能解决你的问题,请参考以下文章
WebGL2系列之实例数组(Instanced Arrays)