1

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

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

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

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

非常感谢!

4

1 回答 1

2

您是否在着色器前面加上#version 300 es? 那必须是使用 glsl 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;
}

于 2016-08-09T08:48:04.453 回答