WebGL GL ERROR: GL_INVALID_OPERATION: glDrawElements: попытка получить доступ к вершинам диапазона значений в атрибуте 1

Я пытаюсь исправить заранее существующую ошибку в некотором коде, основанном на THREE.js rev 49 с некоторыми пользовательскими шейдерами.

Я - полный WebGL newb, поэтому мне не удалось сделать много голов или хвостов других ответов, поскольку они, казалось, обладали гораздо большим количеством знаний, чем я. Я был бы очень благодарен даже за любые подсказки относительно того, что искать!:) Конечный результат кода состоит в том, чтобы нарисовать прозрачный коробчатый каркас и нарисовать лица полупрозрачными текстурами.

Конкретная ошибка:

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

Я выделил проблему для конкретного _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 ); в THREE.WebGLRenderer.renderBuffer.

Вот фрагмент кода вызова:

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")

Спасибо за вашу помощь!

Ответ 1

В WebGL вы настраиваете буферы, полные данных, обычно вершинные положения, нормали, цвета, координаты текстуры. Затем вы попросите WebGL нарисовать что-то с этими буферами. Вы можете задать с помощью gl.drawArrays или с помощью gl.drawElements. gl.drawElements использует другой буфер, полный индексов, чтобы решить, какие вершины использовать.

Полученная ошибка означает, что вы попросили WebGL рисовать или получать доступ к большему количеству элементов, чем настройки буферов. Другими словами, если вы предоставляете только 3 значения вершин, но вы просите его нарисовать 4 вершины, когда вы вызываете gl.drawArrays, вы получите эту ошибку. Аналогично, если вы предоставляете только 3 вершины, а затем устанавливаете индексы, которые обращаются к любой вершине больше 2, вы получите эту ошибку. У вас есть 3 вершины с номерами # 0, # 1 и # 2, поэтому, если какой-либо из ваших индексов больше 2, вы просите WebGL получить доступ к чему-то из диапазона 3 вершин, которые вы предоставили.

Итак, проверьте свои данные. Вы индексы вне пределов досягаемости? Является ли один из ваших буферов короче других? и т.д..

Ответ 2

Я добавляю это для тщательности - я использовал импортированную модель OBJ и получал эту ошибку при создании шейдера через THREE.ShaderLib [ "normalmap" ]

Исправление было просто вызовом computeTangents() объекта геометрии сетки:

model.geometry.computeTangents();

заархивировал ответ здесь