I am following the [WebGL2Fundametals tutorial][1]. Using some sample (cube) data I was able to successfully call `gl.drawElements();` using index, normal and geometry data. This are my fragment and vertex shaders:

Fragment shader:

    #version 300 es    
    precision mediump float;
    
    in vec3 v_normal;
    in vec3 v_surfaceToLight;
    in vec3 v_surfaceToView;
    
    uniform vec4 u_color;
    uniform float u_shininess;
    uniform vec3 u_lightDirection;
    
    uniform float u_innerLimit; // In dot space
    uniform float u_outerLimit; // In dot space
    
    
    out vec4 outColor;
    
    void main() {
      vec3 normal = normalize(v_normal);
    
      vec3 surfaceToLightDirection = normalize(v_surfaceToLight);
      vec3 surfaceToViewDirection = normalize(v_surfaceToView);
      vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);
    
      float dotFromDirection = dot(surfaceToLightDirection, -u_lightDirection);
      float inLight = smoothstep(u_outerLimit, u_innerLimit, dotFromDirection);
      // Using normals for color calculation based on the incidence of light
      float light = inLight * dot(normal, surfaceToLightDirection);
      float specular = inLight * pow(dot(normal, halfVector), u_shininess);
    
      outColor = u_color;
    
      outColor.rgb *= light;
    
      // Add in the specular
      outColor.rgb += specular;
    }


Vertex shader:

    #version 300 es
    in vec4 a_position;
    in vec3 a_normal;
    
    uniform mat4 u_world;
    uniform mat4 u_worldViewProjection;
    uniform mat4 u_worldInverseTranspose;
    
    uniform vec3 u_lightWorldPosition;
    uniform vec3 u_viewWorldPosition;
    
    // varying to pass the normal to the fragment shader
    out vec3 v_normal;
    
    out vec3 v_surfaceToLight;
    out vec3 v_surfaceToView;
    
    void main() {
    
      gl_Position = u_worldViewProjection * a_position;
    
      // Orient the normals and pass to the fragment shader
      v_normal = mat3(u_worldInverseTranspose) * a_normal;
    
      vec3 surfaceWorldPosition = (u_world * a_position).xyz;
      v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;
      v_surfaceToView = u_viewWorldPosition - surfaceWorldPosition;
    }

With the following call the cube is successfully rendered:


    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer);
    GLHelper.setUniformValues(this._uniforms, uniformValues);
    gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);


Here is the working cube data:

Vertices:

            // Front face
            -100, -100, 100,
            100, -100, 100,
            100, 100, 100,
            -100, 100, 100,

            // Back face
            -100, -100, -100,
            -100, 100, -100,
            100, 100, -100,
            100, -100, -100,

            // Top face
            -100, 100, -100,
            -100, 100, 100,
            100, 100, 100,
            100, 100, -100,

            // Bottom face
            -100, -100, -100,
            100, -100, -100,
            100, -100, 100,
            -100, -100, 100,

            // Right face
            100, -100, -100,
            100, 100, -100,
            100, 100, 100,
            100, -100, 100,

            // Left face
            -100, -100, -100,
            -100, -100, 100,
            -100, 100, 100,
            -100, 100, -100,

Normals:

            // Front
            0.0, 0.0, 1.0,
            0.0, 0.0, 1.0,
            0.0, 0.0, 1.0,
            0.0, 0.0, 1.0,

            // Back face
            0.0, 0.0, -1.0,
            0.0, 0.0, -1.0,
            0.0, 0.0, -1.0,
            0.0, 0.0, -1.0,

            // Top face
            0.0, 1.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 1.0, 0.0,

            // Bottom face
            0.0, -1.0, 0.0,
            0.0, -1.0, 0.0,
            0.0, -1.0, 0.0,
            0.0, -1.0, 0.0,

            // Right face
            1.0, 0.0, 0.0,
            1.0, 0.0, 0.0,
            1.0, 0.0, 0.0,
            1.0, 0.0, 0.0,

            // Left face
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,

Indices:

            0, 1, 2, 0, 2, 3,    // Front face
            4, 5, 6, 4, 6, 7,    // Back face
            8, 9, 10, 8, 10, 11,  // Top face
            12, 13, 14, 12, 14, 15, // Bottom face
            16, 17, 18, 16, 18, 19, // Right face
            20, 21, 22, 20, 22, 23,  // Left face

If I get it right the normals in this model should look something like the cube's normals in [the very first animation in the "Introducing normals" part](https://webgl2fundamentals.org/webgl/lessons/webgl-3d-lighting-directional.html). Now I was trying to create and import a cube using Blender.

Unfortunately I wasn't able to recreate a cube with the same kind of normals. Blender generates only one (pink) normal per vertex and they also obviously have a totally different angle:

[![enter image description here][2]][2]

[Some sources](https://blender.stackexchange.com/a/14697) suggest that smoothing the faces would fix this issue. It did not for me. Here is the Wavefront file:

    o Cube
    v 1.000000 -1.000000 -1.000000
    v 1.000000 -1.000000 1.000000
    v -1.000000 -1.000000 1.000000
    v -1.000000 -1.000000 -1.000000
    v 1.000000 1.000000 -0.999999
    v 0.999999 1.000000 1.000001
    v -1.000000 1.000000 1.000000
    v -1.000000 1.000000 -1.000000
    vn 0.0000 -1.0000 0.0000
    vn 0.0000 1.0000 0.0000
    vn 1.0000 -0.0000 0.0000
    vn 0.0000 -0.0000 1.0000
    vn -1.0000 -0.0000 -0.0000
    vn 0.0000 0.0000 -1.0000
    s off
    f 1//1 3//1 4//1
    f 8//2 6//2 5//2
    f 5//3 2//3 1//3
    f 6//4 3//4 2//4
    f 3//5 8//5 4//5
    f 1//6 8//6 5//6
    f 1//1 2//1 3//1
    f 8//2 7//2 6//2
    f 5//3 6//3 2//3
    f 6//4 7//4 3//4
    f 3//5 7//5 8//5
    f 1//6 4//6 8//6


When I try to import and to render this data using `gl.drawElements(gl.TRIANGLES, 72, gl.UNSIGNED_SHORT, 0);` I get the following output:

> ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of
> range vertices in attribute 1

If I use above (.obj) vertex and normal data six time each I do not get any more errors but instead of a cube only a single triangle seems to be rendered.

[![enter image description here][3]][3]

I am pretty sure that `attribute 1` is `in vec3 a_normal;` in my vertex shader. So I am mainly confused about one thing here:

 - How do I modify my code in order to interpret and render the data
   correctly?

**EDIT:**

After changing indices to be zero based I do get more than a single triangle, the object still looks wrong.

[![enter image description here][4]][4]

The result drawn with `gl.LINES`:

[![enter image description here][5]][5]


  [1]: https://webgl2fundamentals.org/webgl/lessons/webgl-3d-lighting-directional.html
  [2]: https://i.sstatic.net/JhiETm.png
  [3]: https://i.sstatic.net/JFspWm.png
  [4]: https://i.sstatic.net/VpR3l.gif
  [5]: https://i.sstatic.net/88klr.gif