将超长数组传递给 gl.uniform3fv

Passing arrays of off-length to gl.uniform3fv

似乎在使用 WebGL uniform3fv 时你必须传递一个 长度等于 3 的数组,如果你的着色器制服是 vec3 或者一个数组有长度等于 3 的倍数,如果你的着色器制服是 vec3 的数组。

这样做:

var data = new Float32Array([ 1, 2, 3, 4 ]);
gl.uniform3fv( uniformLocation, data );

当您的制服声明为:

uniform vec3 some_uniform;

将导致 some_uniform 获得 (0,0,0) 值。

我搜索了网络、SO 和 MDN 以及论坛和其他东西(其中之一是 WebGL 规范),但找不到(或提及)此限制的要求。

我的问题是:这是否是 WebGL 规范所要求的(如果是,请您指点一下)还是您应该了解的一些未记录的行为?

如果需要,我们将更改代码以按要求支持它,如果它是未记录的怪癖,我们将更改代码以支持该怪癖,并提供 disable/remove 一旦怪癖支持的选项没了。

来自the WebGL spec section 5.14.10

If the array passed to any of the vector forms (those ending in v) has an invalid length, an INVALID_VALUE error will be generated. The length is invalid if it is too short for or is not an integer multiple of the assigned type.

您检查过 JavaScript 控制台了吗?当我尝试它时,我清楚地看到控制台中的 INVALID_VALUE 错误。

下面的代码

const gl = document.querySelector('canvas').getContext('webgl');
const vs = `
attribute vec4 position;
void main() {
  gl_Position = position;
}
`;
const fs = `
precision mediump float;
uniform vec3 color;
void main() {
  gl_FragColor = vec4(color, 1);
}
`;
const program = twgl.createProgram(gl, [vs, fs]);
const loc = gl.getUniformLocation(program, 'color');
gl.useProgram(program);
gl.uniform3fv(loc, [1, 2, 3, 4]);  // generates INVALID_VALUE
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>

打印

在 JavaScript 控制台中

换句话说,你的制服没有设置为 0,0,0。相反,您的 gl.uniform3fv 函数由于出现错误而无法执行,因此制服保留为它已经存在的任何值。制服默认为 0,所以这是 0 的来源

如果您想在调试期间捕获此类错误,请考虑使用 this helper library。一般来说,我发现只要查看 JavaScript 控制台就足以让我找出问题所在。