Webgl vertexAttribPointer:索引超出范围
Webgl vertexAttribPointer: index out of range
我正在尝试传递 uv 缓冲区以及 webgl 中的普通缓冲区。但由于某种原因,我在传递值时收到此警告 vertexAttribPointer: index out of range
。我不明白我做错了什么,因为 uv 阵列看起来不错,法线也一样。
似乎错误只发生在法线和 uv 上,而不是位置。
enableVertexAttribArray: index out of range
vertexAttribPointer: index out of range
let canvas = document.querySelector("canvas");
let gl = canvas.getContext("webgl");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const vsSource = `
attribute vec4 position;
attribute vec2 uv;
attribute vec3 normal;
uniform mat4 modelViewMatrix;
varying vec4 vColor;
void main(void) {
gl_Position = position;
}
`;
const fsSource = `
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vec4(1.0,0.0,1.0,1.0);
}
`;
// Shader setup
let vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
var log = gl.getShaderInfoLog(vertexShader);
throw "Shader compilation failed\n\n" + log + "\n\n";
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
var log = gl.getShaderInfoLog(fragmentShader);
throw "Shader compilation failed\n\n" + log + "\n\n";
}
let program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
var log = gl.getProgramInfoLog(program);
throw "Program link failed\n\n" + log;
}
gl.useProgram(program);
let modelViewMatrix = gl.getUniformLocation(program, "modelViewMatrix");
let model = mat4.create();
gl.uniformMatrix4fv(modelViewMatrix, false, model);
var vertices = new Float32Array([
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
-0.5,
-0.5
]);
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
let position = gl.getAttribLocation(program, "position");
gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(position);
var uvBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0
]),
gl.STATIC_DRAW
);
let uv = gl.getAttribLocation(program, "uv");
gl.vertexAttribPointer(uv, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(uv);
var normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1
]),
gl.STATIC_DRAW
);
let normal = gl.getAttribLocation(program, "normal");
gl.vertexAttribPointer(normal, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normal);
var indices = new Uint16Array([
0,
2,
1,
2,
3,
1,
4,
6,
5,
6,
7,
5,
8,
10,
9,
10,
11,
9,
12,
14,
13,
14,
15,
13,
16,
18,
17,
18,
19,
17,
20,
22,
21,
22,
23,
21
]);
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
<canvas></canvas>
您的着色器未使用 uv
或 normal
,因此您的驱动程序正在优化这些属性。在这种情况下,gl.getAttribLocation
returns -1 表示位置(-1 = 此名称的属性不存在)。 -1 超出范围。有效值为 0 到 gl.getParameter(gl.MAX_VERTEX_ATTRIBS) - 1
换句话说,你需要检查你的属性的位置,如果它们不存在,就不要设置它们。
这就是 write some helper functions for WebGL 为您处理这些问题的好处之一,这样当您修改着色器时,您的代码就不会中断。
我正在尝试传递 uv 缓冲区以及 webgl 中的普通缓冲区。但由于某种原因,我在传递值时收到此警告 vertexAttribPointer: index out of range
。我不明白我做错了什么,因为 uv 阵列看起来不错,法线也一样。
似乎错误只发生在法线和 uv 上,而不是位置。
enableVertexAttribArray: index out of range
vertexAttribPointer: index out of range
let canvas = document.querySelector("canvas");
let gl = canvas.getContext("webgl");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const vsSource = `
attribute vec4 position;
attribute vec2 uv;
attribute vec3 normal;
uniform mat4 modelViewMatrix;
varying vec4 vColor;
void main(void) {
gl_Position = position;
}
`;
const fsSource = `
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vec4(1.0,0.0,1.0,1.0);
}
`;
// Shader setup
let vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
var log = gl.getShaderInfoLog(vertexShader);
throw "Shader compilation failed\n\n" + log + "\n\n";
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
var log = gl.getShaderInfoLog(fragmentShader);
throw "Shader compilation failed\n\n" + log + "\n\n";
}
let program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
var log = gl.getProgramInfoLog(program);
throw "Program link failed\n\n" + log;
}
gl.useProgram(program);
let modelViewMatrix = gl.getUniformLocation(program, "modelViewMatrix");
let model = mat4.create();
gl.uniformMatrix4fv(modelViewMatrix, false, model);
var vertices = new Float32Array([
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
-0.5,
-0.5
]);
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
let position = gl.getAttribLocation(program, "position");
gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(position);
var uvBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0
]),
gl.STATIC_DRAW
);
let uv = gl.getAttribLocation(program, "uv");
gl.vertexAttribPointer(uv, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(uv);
var normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1
]),
gl.STATIC_DRAW
);
let normal = gl.getAttribLocation(program, "normal");
gl.vertexAttribPointer(normal, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normal);
var indices = new Uint16Array([
0,
2,
1,
2,
3,
1,
4,
6,
5,
6,
7,
5,
8,
10,
9,
10,
11,
9,
12,
14,
13,
14,
15,
13,
16,
18,
17,
18,
19,
17,
20,
22,
21,
22,
23,
21
]);
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
<canvas></canvas>
您的着色器未使用 uv
或 normal
,因此您的驱动程序正在优化这些属性。在这种情况下,gl.getAttribLocation
returns -1 表示位置(-1 = 此名称的属性不存在)。 -1 超出范围。有效值为 0 到 gl.getParameter(gl.MAX_VERTEX_ATTRIBS) - 1
换句话说,你需要检查你的属性的位置,如果它们不存在,就不要设置它们。
这就是 write some helper functions for WebGL 为您处理这些问题的好处之一,这样当您修改着色器时,您的代码就不会中断。