我试图在一些基于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")
感谢您的帮助!
答案 0 :(得分:22)
在WebGL中,您可以设置充满数据的缓冲区,通常是顶点位置,法线,颜色,纹理坐标。然后,您要求WebGL使用这些缓冲区绘制内容。您可以使用gl.drawArrays
或gl.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