I’m new to computer graphics, so want to apologize ahead, question will touch multiple topics. Would really appreciate at least some hints, or links to resources. Got stuck conceptually.
My task is to be able to render a lot of meshes (100,000 - 400,000) in 2D. All of them are going to be rather simple - Rectangles, Ellipses, Stars, Polygons, Curves. The scene would be a space 20 000px x 20 000px, with a “camera” observing only a part of the scene, e.g. 1000x1000 (don’t know how to make it yet, however it’s not the point of my question). These shapes could be modified - scaled, dragged, filled with a certain color, given an outline, changing border radius, etc. The closest analogous is Figma.
Was using WebGl and Three.js. Was trying to make a test - to render 100 000 of Rectangles onto the screen, and trying to animate movement of one of them. (As i understand, if we are moving even a single mesh, we are initiating the whole redrawing cycle, of all meshes out there).
- WebGl - I’ve created 100 000 instances of a custom
class Rectangle
, that holds 6 vertices, and translation vector -translation = [0, 0]
.
let rects = [...] // 100000 new Rectangle()
for (let rect of rects) {
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(rect.verticies),
gl.STATIC_DRAW
);
drawRect(rect.translation)
}
let positionLocation = gl.getAttribLocation(program, "a_position");
function drawRect(translation_vec) {
// gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.uniform2fv(translationLocation, translation_vec);
// 6 verticies per rect
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
This approach wouldn’t allow me to make a translation normally(in case i would like to drag and drop rectangle to a different position). Because it takes 1-2 seconds to redraw everything. Is there a better, and more performant way of doing so?
- Three.js - I’ve tried to accomplish the same goal. First, approached to to use
PlaneGeometry
class, using it to createMesh
.
for (let plane of meshes) {
// plane - is a Three.js Mesh instance, with material and geometry
scene.add(plane)
}
At 10 000 of meshes my browser lagged, and then was closed.
There are couple of suggestions, that I’ve faced, trying to figure out how to render a big amount of 2D Meshes. There were two of them. Either using InstancedMesh
, that allows to render all these shapes at once, at one rendering cycle. However, it restricts an opportunity to have Meshes of a different size. They can be positioned anywhere in the world, but should all be the same.
Or using BufferGeometry
what puts me back to the problem 1. That i don’t know how to make rendering and transforming more performant. I hoped, that Three.js can provide some optimized abstraction.
Sorry, it’s too long. I would appreciate any advises. Maybe the approach I’m talking is wrong conceptually, and you can advise what to do in this situation, considering the goal needs to be accomplished.