Enhance the performance of three.js for rendering a complex mesh

Currently, I am tackling a project that involves 59k points, where each point needs to be depicted as a cube in three.js.

Although I have merged all the geometries into one mesh to enhance performance, the rendering speed is still quite sluggish (around 10-30 fps).

To meet the project requirements of smooth operation (ideally at 40-60 fps), I am seeking ways to optimize the process further.

Below is the snippet of code responsible for creating the mesh and scene:

function init() {

camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);

camera.position.set(230.09813315369976, 233.67707474083232, -181.06937619976165);
camera.updateProjectionMatrix();

THREE.currentCamera = camera;

if (controlsEnabled) {
    controls = new THREE.OrbitControls(camera);
    controls.damping = 0.2;
}
scene = new THREE.Scene();

geometry = new THREE.Geometry();
material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false});
console.log("Adding " + locations.length + " voxels");

var matrix = new THREE.Matrix4();

$.each(locations, function (index, value) {
    geo = new THREE.BoxGeometry(1, 1, 1);

    matrix.makeTranslation(
            value['x'],
            0,
            value['y']
            );

    geometry.merge(geo, matrix);
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
axes = new THREE.AxisHelper(100);
scene.add(axes);
camera.lookAt(mesh);
raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 1);
var element = renderer.domElement;
document.getElementById('page-wrapper').appendChild(renderer.domElement);
document.addEventListener('mousemove', onDocumentMouseMove, false);
window.addEventListener('resize', onWindowResize, false);
var flag = 0;
element.addEventListener("mousedown", function () {
    flag = 0;
}, false);
element.addEventListener("mousemove", function () {
    flag = 1;
}, false);
element.addEventListener("mouseup", function () {
    if (flag === 0) {
        console.log("click");
        doRaycast = true;
    }
    else if (flag === 1) {
        console.log("drag");
    }
}, false);
$('#loading-vis').hide();
animate();

}

Answer №1

Optimizing by batching geometry into as few draw calls as possible may seem straightforward, but the process is more complex than it appears at first glance.

While I can't provide a detailed explanation of what happens behind the scenes, one effective approach is to issue draw calls with fewer than 65536 triangles (2^16) in a "triangle soup."

In your case, it seems that batching everything into a single geometry caused issues either with the indexed geometry or resulted in the geometry being split back into fewer pieces unintentionally.

The solution is not to batch everything into one geometry, but rather to split it into multiple geometries, each containing less than 65536 triangles.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps are needed to incorporate the Google My Business API into a React application?

I'm curious about how to embed Google My Business API into a React application. I want to display the Google reviews on my website. I've been browsing through the Google documentation but haven't come across a comprehensive guide. Any assis ...

Spinning a rectangular grid with JavaScript

I am currently developing my own version of Tetris. My main focus at the moment is creating a function that can rotate a 2D variable array by 90 degrees (or -90). For instance, if we have an array like: "-T-", "TTT" The expected outpu ...

Missing pieces of data | Utilizing React and Redux Toolkit

I'm facing a problem that's keeping me up for almost 24 hours. I just finished coding this slice, but when I submit the data, only the automatically generated ID is returned. Let me explain further - I have a skill component with two input forms ...

Can a Handlebar variable be accessed using an external .js file?

Hello there! Despite the ongoing pandemic, I hope you are doing well. Currently, I'm deep into a school project and seem to have hit a roadblock that I can't maneuver around. My main dilemma lies in finding a way to access the data communicated b ...

Troubleshooting Vue: Why is my component not visible when using v-form and v-text-field components in Vuetify?

Attempting to implement the v-form and v-text-field components from the Vuetify node package. <template> <v-form> <v-text-field label="Test" type="foo"></v-text-field> <v-text-field label="bar&q ...

Encountering a glitch when utilizing framer-motion's Animated Presence feature

I am working on a React slider where new data replaces old data whenever the user clicks on the Next or Previous button. To enhance the slider with beautiful animations, I decided to use framer motion. The animations are almost perfect, but for some reason ...

Oops! Looks like the react-redux context value couldn't be found in your React Native Expo App. Make sure to wrap the component in a <Provider> to resolve this issue

I encountered an issue while attempting to run my React-Native application. My goal is to develop a React-Native app that includes a BottomNavBar and drawer navigation. To manage the state, I am implementing Redux-Toolkit. Despite following the provided do ...

HTML Buttons Remain Selected After Being Clicked

Currently working on a calculator app for a class project but I've hit a roadblock while setting up keyboard listeners. The keyboard functionality is fine, however, when it comes to clicking on buttons, specifically the non-keyboard functions, they re ...

Engaging with the crossrider sidepanel extension

When it comes to the crossrider sidepanel, I prefer using an iframe over js-injected html to avoid interference with the rest of the page. However, I am struggling to establish any interaction between my browser extension and the iframe. I believe adding ...

Speed of scrolling on a biquadratic Bezier curve

I recently came across a fascinating website called that showcases a unique scrolling behavior. It gives the illusion of moving between slides (screens) with snappy scrolling, when in reality, the website actually scrolls continuously. The transitions bet ...

I'm a beginner in jest and I'm curious, how should I go about writing a test for this

Below is a method I have called onViewed: onViewed() { const { current } = this.state; this.slides[current] = { ...this.slides[current], viewed: true }; const filtered = _.filter(this.slides, slide => slide.section === this.slides[current].s ...

Implement dynamic options in dropdown menu using JQuery AJAX call to retrieve data in JSON format

I am currently diving into the world of JQuery and exploring AJAX requests. Sample Code: Javascript: success: function(json) { console.log(json); var $el = $("#system"); $el.empty(); // removing old options $el.append($( ...

The value retrieved from the event handler function's state does not match the anticipated value

While debugging, I often minimize this particular component to understand its behavior later on. It was quite challenging to pinpoint the issue due to some intricate logic in place. Nonetheless: import { useContext, useEffect, useState } from "react&q ...

modifying the properties of arrow head in the ArrowHelper class in Three.js

While using the arrow helper class, I came across this example . Following it, I managed to make the arrow work. However, the size of the arrowhead is larger than what I desire. My current code snippet looks like this: var direction = new THREE.Vector3(). ...

Obtain the name of the client's computer within a web-based application

I am working on a Java web application that requires the computer name of clients connecting to it. Initially, I attempted to retrieve this information using JavaScript and store it in a hidden form field. However, I discovered that JavaScript does not hav ...

What is causing the delay in making ajax calls with a specified timing?

I have a problem with calling an action on a controller using Ajax in my MVC5 application. I need to make the call 10 times with a 2-second delay between each call. Here is the code snippet that I've implemented: $(document).ready(function () { ...

Having Trouble with Shopify's Asynchronous Ajax Add to Cart Feature?

I have developed a unique Shopify page design that allows users to add multiple items to their cart using Shopify's Ajax API. I've created a test version of the page for demonstration: Below is the current javascript code I am using to enable as ...

Is it possible to conceal my Sticky Div in MUI5 once I've scrolled to the bottom of the parent div?

Sample link to see the demonstration: https://stackblitz.com/edit/react-5xt9r5?file=demo.tsx I am looking for a way to conceal a fixed div once I reach the bottom of its parent container while scrolling down. Below is a snippet illustrating how I struct ...

Creating an object with a property in typescript

Recently, I made the switch from JavaScript to TypeScript and now I am in the process of converting a lot of my code. I used to frequently use this snippet in JavaScript (which has been converted to TypeScript): function isObject (payload: any): payload ...

put two elements next to each other in a single row

This specific section contains an image positioned at the top, followed by two other components (within <ItemsContainer/>) at the bottom which display as separate rows. I am trying to place these two items (a grid and a chart) side by side within the ...