WebGL GL错误:GL_INVALID_OPERATION:glDrawElements:尝试访问属性1中的范围外顶点

时间:2014-01-18 05:25:02

标签: three.js webgl

我试图在一些基于THREE.js rev 49的代码中使用一些自定义着色器修复预先存在的错误。

我是一个完整的WebGL新手,所以我没有能够做出其他答案的多少或多少,因为他们似乎承担了比我更多的知识。我会非常感谢任何关于要寻找什么的提示! :)代码的最终结果是绘制一个半透明的框线框并用半透明纹理绘制面。

特殊错误是:

[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1

我将问题追溯到THREE.WebGLRenderer.renderBuffer中的特定_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

以下是调用代码的片段:

scene.overrideMaterial = depthMaterial; // shaders below
var ctx = renderer.getContext(); // renderer is a THREE.WebGLRenderer
ctx.disable(ctx.BLEND);
// renderTarget is a THREE.WebGLRenderTarget, _camera, scene is obvious
renderer.render(scene, _camera, renderTarget, true); // error occurs here

以下是相关着色器:

    uniforms: {},

    vertexShader: [
        "varying vec3 vNormal;",

        "void main() {",

            "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
            "vNormal = normalMatrix * normal;",

            "gl_Position = projectionMatrix * mvPosition;",

        "}"
    ].join("\n"),

    fragmentShader: [
        "vec4 pack_depth( const in highp float depth ) {",

            "const highp vec4 bit_shift = vec4( 256.0, 256.0*256.0, 256.0*256.0*256.0, 256.0*256.0*256.0*256.0 );",
            "vec4 res = depth * bit_shift;",
            "res.x = min(res.x + 1.0, 255.0);",
            "res = fract(floor(res) / 256.0);",
            "return res;",

        "}",

        "void main() {",
            "gl_FragData[0] = pack_depth( gl_FragCoord.z );",
        "}"
    ].join("\n")

感谢您的帮助!

2 个答案:

答案 0 :(得分:22)

在WebGL中,您可以设置充满数据的缓冲区,通常是顶点位置,法线,颜色,纹理坐标。然后,您要求WebGL使用这些缓冲区绘制内容。您可以使用gl.drawArraysgl.drawElements询问。 gl.drawElements使用另一个充满索引的缓冲区来决定使用哪些顶点。

您获得的错误意味着您要求WebGL绘制或访问比您设置的缓冲区更多的元素。换句话说,如果您只提供3个顶点的数据但是当您调用gl.drawArrays时要求它绘制4个顶点,那么您将得到该错误。类似地,如果您只提供3个顶点值的数据,然后设置访问任何大于2的顶点的索引,那么您将得到该错误。您有3个顶点编号为#0,#1和#2,因此,如果您的任何索引大于2,那么您要求WebGL访问超出您提供的3个顶点范围的内容。

所以,检查一下你的数据。你的指数是否超出范围?你的缓冲区比其他缓冲区短吗?等。

答案 1 :(得分:3)

我是为了彻底性而添加它 - 我使用的是导入的OBJ模型,并且在通过THREE.ShaderLib创建着色器时出现此错误[“normalmap”]

修复只是在网格的几何对象上调用computeTangents():

model.geometry.computeTangents();

归档了答案here