Use external VBO

Hello!
This is a feature request. I want to be able to optionally feed my VBO to three.js BufferAttribute. I walked through some (three.js) code and couldn’t find any way to do so (from outside).

In previous versions of three.js I was able to hack into renderer.properties to replace VBO with my custom one. However, after an upgrade to r86 three’s VBO are stored in WebGLAttributes module which is not exposed. Since now the storage is hidden from the outside, I can no longer hack into it from my external codes. Therefore I want to legalize such behavior, to prevent further struggles and hacks.

An example of what I might do with it is following:

	const geo = new THREE.BufferGeometry();
	geo.setDrawRange( 0, REAL_SIZE );
	// ...
	const ba = new THREE.BufferAttribute(_dummyArray, 3);
	ba.count = REAL_SIZE * 3;
	geo.setDrawRange( 0, REAL_SIZE );

	// HERE! set buffer-creator callback
	ba.onCreateCallback = function () {
		// I create it just for example, actually it can come from other lib
		const vertices = [];
		for ( i = 0; i < REAL_SIZE; i ++ ) {
			vertices.push( Math.random() * 2000 - 1000 );
			vertices.push( Math.random() * 2000 - 1000 );
			vertices.push( Math.random() * 2000 - 1000 );
		}
		const vbo = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
		// Return back to three.js
		return vbo;
	};

	geo.addAttribute('position', ba);
	// ...
	particles = new THREE.Points( geo, materials[0] );
	scene.add( particles );

More of it you can see here.

To summarize: sometimes you end up with preallocated GL buffer and a lack of an ability to use it in three.js BufferGeometry, where it would fit perflectly.

If it sounds reasonable, then I can also show an example of a patch, that makes the above code work:

		var buffer;

		if (attribute.onCreateCallback) {

			buffer = attribute.onCreateCallback();

		} else {

			buffer = gl.createBuffer();

			gl.bindBuffer( bufferType, buffer );
			gl.bufferData( bufferType, array, usage );

		}

		attribute.onUploadCallback();

Just add the condition to see if there is user-defined buffer-creator callback. In WebGLAttributes.js, that’s all I need.

If you want me to give more specific reasons for what I do with my buffers, I’ll be glad to answer. I can then create a PR with the above changes, if it makes sense.

Three.js version
  • r86+
Browser
  • All of them
  • Even more than that
OS
  • All of them

Thanks for your time! 😃

Author: Fantashit

1 thought on “Use external VBO

  1. Instead of trying to hack BufferAttribute… What about an API like this?

    var positions = new THREE.GLBufferAttribute( function ( gl ) {
    
    	const vertices = [];
    
    	for ( i = 0; i < REAL_SIZE; i ++ ) {
    		vertices.push( Math.random() * 2000 - 1000 );
    		vertices.push( Math.random() * 2000 - 1000 );
    		vertices.push( Math.random() * 2000 - 1000 );
    	}
    
    	const vbo = gl.createBuffer();
    	gl.bindBuffer( gl.ARRAY_BUFFER, vbo );
    	gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( vertices ), gl.STATIC_DRAW );
    	return vbo;
    
    } );
    geometry.addAttribute( 'position', positions );

Comments are closed.