Skip to main content

ScreenCuller

๐Ÿš… Managing Performanceโ€‹


There are occasions when your scene has too many components. Multiple components being rendered simultaneously lengthens computation timeโŒ›๏ธ and degrades performance.๐ŸŒก๏ธ

First, let's set up a simple scene!

๐Ÿ‘€ If you haven't started there, check out that tutorial first!

In this tutorial, we will use ScreenCuller to improve performance by reducing unnecessary computations.๐Ÿš€ This tutorial will show you how to manage a complex scenario with a lot of elements in an effective way.๐Ÿฆพ

๐Ÿงฐ Creating Screen Cullerโ€‹


Although adding Screen Culler to your project can appear difficult, it is actually rather easy. Now, we will add Screen Culler Component. This will create a Screen Culler which is now ready to be used.

const culler = new OBC.ScreenCuller(components);

Additionally, we will activate the culler.renderDebugFrame so that we can see the 2D screen of the elements that are not occluded.๐Ÿ’ป Also, we will get the domElement and attach it to the body so that we can see this frame in real-time.๐Ÿ“Š

culler.renderDebugFrame = true;
const debugFrame = culler.renderer.domElement;
document.body.appendChild(debugFrame);
debugFrame.style.position = 'absolute';
Randomising the Cube Placement

We'll write a quick utility function that returns a random number between 0 and the specified upper limit. You can use this for a variety of purposes, but for this tutorial it will be used to generate random positions for cube placement.๐Ÿ“Œ

function getRandomNumber(limit) {
return Math.random() * limit;
}

๐Ÿงฑ Adding a lot of 3D Objectsโ€‹

We'll add the Simple 3D Cube and do it 300 times!๐Ÿคฏ Components are built using Three.js, making it simple to use any three.js code. For our cube, we'll generate box geometry and use basic material.

const cubes = [];
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshLambertMaterial({ color: 'red' });

๐Ÿงช Generate Multiple Cubesโ€‹

Now, using the getRandomNumber() method we previously created, we will add the 300 cube meshes to our scene and randomly position them. We'll add the cube to the scene and adjust its position between 0 and 10. Additionally, we will add meshes to the culler object, which will help SimpleCuller to recognize and draw the elements that are visible to the camera. To do this, culler.add(cube) will be used.

function regenerateCubes() {
resetCubes();
for (let i = 0; i < 300; i++) {
const cube = new THREE.Mesh(geometry, material);
cube.position.x = getRandomNumber(10);
cube.position.y = getRandomNumber(10);
cube.position.z = getRandomNumber(10);
cube.updateMatrix();
scene.add(cube);
culler.add(cube);
cubes.push(cube);
}
}

๐Ÿงน Cleaning the Sceneโ€‹

Now that we know how to create multiple cubes, we will write a function to remove the cubes from scene on demand. resetCubes() iteratively removes the cubes using cube.removeFromParent.

function resetCubes() {
for (const cube of cubes) {
cube.removeFromParent();
}
cubes.length = 0;
}

๐Ÿ“ข Rendering Cubesโ€‹

With everything ready, we will call regenerateCubes() which will generate cubes and add them to scene.

regenerateCubes();

Here comes the most crucial part! The core aim of ScreenCuller is to output just those components that are visible to the camera. culler.needsUpdate = true instructs the ScreenCuller to render the updated view. Remember to update culler every time the camera is updated โ• For this tutorial, we are updating the culler on the click of button. ๐Ÿ–ฑ

culler.needsUpdate = true;

Great job! ๐ŸŽ‰ Now you know how to optimise your 3D scene using a Screen Culler component! ๐Ÿ’ช Your BIM app will now have unmatched performance and can render huge scenes easily. ๐Ÿš€ Let's keep it up and check out another tutorials!