Vertex buffer is not big enough for the draw call only on mac computers

Hi!

I am having some problems with three js. I wanted to make a line shader that fades and asked for help here and it works really good for windows and linux pcs. How to make a Line2 fading out shader

Turns out this does not work on macs and I am trying to figure out why. The error I am getting is:

[.WebGL-0x10c0c08a900] GL_INVALID_OPERATION: Vertex buffer is not big enough for the draw call

What I am doing:

const geometry = new LineGeometry();
const line = new Line2(geometry, material);
geometry.setPositions(positions); // positions is a number[]
scene.add(line)

Later on in the code I do:

geometry.setPositions(positions); // also a number[]

And this gives me that error, but only on Apple Mac computers (and maybe phones have not tested them). Why does it do this and why does it work on windows/linux but not on mac? Is it because of the architecture or maybe different implementation of WebGL? Any easy way to solve this or do I have to make a new Line() each time? (I also use setColor(color) where I do the setPositions and removing that changes nothing).

1 Like

Have also just ran into this. Shall update the thread if I find a solution.

meet the same problem on some macOs, and don’t know why

this problem caused by BufferAttribute array length; one of Attributes length not right in my case

2 Likes

I also met this problem. Has the problem been solved?

It would be great if someone having this problem could share enough details (code, demo) to fully reproduce the problem. As the error suggests, the number of vertices and/or indices in your geometry is closely related, please share those numbers at the minimum. :slight_smile:

1 Like

I have run into the same problem!
I’m trying to generate 50 triangles.
As soon as I change 16 to 17 in the first loop. I get an error:
WebGL-0x13805d01500] GL_INVALID_OPERATION: Vertex buffer is not big enough for the draw call

But I need to go up to 50. What could be a problem?

import './style.css'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

/**
 * Base
 */
// Canvas
const canvas = document.querySelector('canvas.webgl')

// Scene
const scene = new THREE.Scene()

// Object
const geometry = new THREE.BufferGeometry();

let indices = [];
let vertices = new Float32Array(150);
console.log(vertices);
for (let i = 0; i < 16; i++) {
    for (let j = 0; j < 3; j++) {
        // console.log(3 * (3 * i + j));
        // console.log(3 * (3 * i + j) + 1);
        // console.log(3 * (3 * i + j) + 2);
        vertices[3 * (3 * i + j)] = Math.random();
        vertices[3 * (3 * i + j) + 1] = Math.random();
        vertices[3 * (3 * i + j) + 2] = Math.random();
        indices.push(3 * i + j);
    }
}
console.log(vertices);
geometry.setIndex(indices);
console.log(indices);

// specify vertex positions
geometry.setAttribute('position',
    new THREE.BufferAttribute(vertices, 3));

const material = new THREE.MeshBasicMaterial({
    color: 0xff0000,
    wireframe: true
})
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)

// Sizes
const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () => {
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

// Camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.z = 3
scene.add(camera)

// Controls
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true

// Renderer
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

// Animate
const clock = new THREE.Clock()

const tick = () => {
    const elapsedTime = clock.getElapsedTime()

    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

It’s crazy but I just have solved the problem in 30 seconds using ChatGPT.

And here is the answer:

The error message suggests that the size of the vertex buffer is not sufficient for rendering all the triangles you want to generate. In the provided code, the size of the vertex buffer is set to 150, which corresponds to 16 triangles. If you want to render 50 triangles, you need to adjust the size of the vertex buffer accordingly.

To do this, you can change the size of the vertices array from new Float32Array(150) to new Float32Array(50 * 3 * 3). This will allocate enough memory for 50 triangles, each with 3 vertices that each have 3 coordinates (x, y, z). Additionally, you should also adjust the loop limits in your code from for (let i = 0; i < 16; i++) to for (let i = 0; i < 50; i++) to generate 50 triangles.

With these changes, the code should be able to generate and render 50 triangles without the GL_INVALID_OPERATION error.

1 Like

this happens often when vertices are dynamically changed, while some of the attribute lengths are not consistent.