webGL2统一缓冲区对象和布局的使用(std140)

时间:2015-11-22 16:43:20

标签: opengl-es glsl webgl webgl2

我正在开发一个webgl布料模拟项目,尝试使用转换反馈。模拟将在顶点着色器中完成。我需要访问顶点的邻居顶点来计算力。我正在考虑使用统一缓冲区对象来存储所有顶点的位置。

我定义了一个统一的块,如下所示:

layout(std140) uniform u_testBlock
{
    vec4 v0;
    vec4 v1;
    ...
};

但是,我有'布局:语法错误'。这是在webGL2中使用UBO的正确方法吗? webGL2规范说统一块只支持std140布局,为什么会出现这样的语法错误?

非常感谢!

1 个答案:

答案 0 :(得分:1)

您的着色器前缀为#version 300 es吗?这必须是使用glsl es 3.0功能的第一行(之前没有空行)

此外,您的精确度必须匹配。

您的示例适用于Firefox。从版本54.0.2824.0开始,Chrome Canary似乎已被破坏(以前用于工作)。我相信很快就会修好。

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;
}