Enhance numerous animated shapes in Three.js

Just dipping my toes into the world of Three.js and tinkering with it for fun. My goal is to create a simple dynamic full-screen background for a webpage. You can check out the example here:

function createHexagon( vertices, color ) {
    var geometry = new THREE.BufferGeometry();
    geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
    var material = new THREE.LineBasicMaterial( { color: color, opacity: Math.min((Math.random() / 5), 0.1), transparent: true } );

    var hexagon = new THREE.Line( geometry, material );
    return hexagon;
}

function initMatrix() {
    var color = defaultColor.getHex();
    var vertices;

    var x = ( width / -2 ) - 90;
    var y = height / -2;
    var deltaX = 120;
    var deltaY = 60;
    var time = 5.0;
    while( y < height / 2 ) {
        while( x < width / 2 ) {

            vertices = new Float32Array([
                0,  30, 0,
               20,   0, 0
            ]);
            var hexagon = createHexagon( vertices, color );
            scene.add( hexagon );  
            hexagon.position.set( x, y, 0 );

            vertices = new Float32Array([
               20,   0, 0,
               60,   0, 0
            ]);
            var hexagon = createHexagon( vertices, color );
            scene.add( hexagon );  
            hexagon.position.set( x, y, 0 );

            vertices = new Float32Array([
               60,   0, 0,
               80,  30, 0
            ]);
            var hexagon = createHexagon( vertices, color );
            scene.add( hexagon );  
            hexagon.position.set( x, y, 0 );

            x += deltaX;

        }

        x = ( width / -2 ) - 90;
        y += deltaY;
    }

    x = ( width / -2 ) - 30;
    y = ( height / -2 ) - 30;
    deltaX = 120;
    deltaY = 60;
    while( y < height / 2 ) {
        while( x < width / 2 ) {

            vertices = new Float32Array([
                0,  30, 0,
               20,   0, 0
            ]);
            var hexagon = createHexagon( vertices, color );
            scene.add( hexagon );  
            hexagon.position.set( x, y, 0 );

            vertices = new Float32Array([
               20,   0, 0,
               60,   0, 0
            ]);
            var hexagon = createHexagon( vertices, color );
            scene.add( hexagon );  
            hexagon.position.set( x, y, 0 );

            vertices = new Float32Array([
               60,   0, 0,
               80,  30, 0
            ]);
            var hexagon = createHexagon( vertices, color );
            scene.add( hexagon );  
            hexagon.position.set( x, y, 0 );          

            x += deltaX;
        }

        x = ( width / -2 ) - 30;
        y += deltaY;
    }
}

These are individual bufferGeometry lines (as seen in the functions above to create the background) that randomly rotate and change opacity on mouse hover using raycaster and TweenLite. The functionality is good, but the CPU usage spikes to nearly 100%.

I understand that grouping the lines into the same geometry would improve performance, however, I would lose the ability to independently animate each line with the raycaster, especially the opacity changes.

I've researched extensively and experimented with various approaches. The current method of rendering individual lines separately seems to yield the best results. Any suggestions or tips on optimizing this setup?

Answer №1

(An update from the original poster).

I have successfully devised a solution to my problem. I created a detailed geometry and assigned indices to the vertices along with their respective colors. While this method does not allow for opacity adjustments, it is efficient with the CPU usage at around 20%.

After carefully initializing the matrix, I proceeded to define the scene, camera, renderer, raycaster, and mouse elements. Additionally, I set up the necessary attributes such as line positions, colors, geometry, and materials for the 3D visualization.

The matrix was created with a specific pattern calculated based on the screen dimensions and coordinates. Random colors were assigned to each line segment, adding a dynamic aspect to the visual output.

Through a series of functions, I was able to animate changes in both color and coordinates of the lines when interacting with them using the mouse. The render function updates the scene based on the mouse position to create a dynamic visual effect.

A Codepen link showcasing this implementation can be found <a href="https://codepen.io/ThoughtsRiff/pen/yRJgvv?editors=1111" rel="nofollow noreferrer">here</a>.

Feel free to explore and interact with the live demo!

Answer №2

I came across a solution. I created a complete geometry and assigned indices to vertices along with corresponding colors. The only downside is that adjusting opacity seems to be a challenge using this method, but the performance is satisfactory with CPU usage around 20%.

document.addEventListener('DOMContentLoaded', main);

var width = screen.width;
var height = screen.height;
var camera, scene, renderer, raycaster, mouse;
var rayColor = new THREE.Color(0x0640C2);
var rayColor2 = new THREE.Color(0xCC311B);
var colors;
var linesPositions, originalPositions;
var linesMesh;
var geometry;
var intersects;

var stats;

function initMatrix() {

    var AlinesPositions = [];

    var x = (width / -2) - 80;
    var y = (height / -2) - 60;
    var deltaX = 120;
    var deltaY = 60;

    while (y <= (height / 2)) {

        while (x <= (width / 2)) {

            // Populate AlinesPositions array
            x += deltaX;

        }

        x = (width / -2) - 80;
        y += deltaY;

    }

    // Other matrix initialization logic
}

function init() {
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(120, width / height, 1, 1000);
    camera.position.set(0, 0, 200);
    camera.lookAt(0, 0, 0);

    initMatrix();

    raycaster = new THREE.Raycaster();
    raycaster.linePrecision = 20;

    mouse = new THREE.Vector2();

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(width, height);
    document.body.appendChild(renderer.domElement);
}

function main() {

    init();
    animate();

}

function animate() {

    requestAnimationFrame(animate);
    render();

}

var intersected = [];

// Other functions like removeX, alterate, onMouseMove, etc.

For the full code, you can check it out in this Codepen link.

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

Using Javascript to validate passwords and Bootstrap for design enhancements

I've been working on learning Javascript and some basic HTML using bootstrap v5 recently. One of the tasks I'm currently tackling is creating a Sign-in form and implementing validation for the required fields. While following the Bootstrap docu ...

The name 'withStyles' is nowhere to be found

import * as React from "react"; import Button from "@material-ui/core/Button"; import * as PropTypes from "prop-types"; import {WithStyles} from '@material-ui/core'; import "./App.css"; import PageTwo from "./components/PageTwo"; ...

What is the best way to utilize functions in Express to dynamically display content on my Jade template?

I have successfully implemented a user registration and login page, but now I need to determine what content to display based on whether the user is logged in. I found this solution: app.use(function(req, res, next) { db.users.find({rememberToken: req.c ...

Attaching an External JSON Data File in JSFiddle

Can external JSON Data be linked within JSFiddle? Here is the code snippet I'm using to fetch the JSON Data: var xhr = new XMLHttpRequest(); xhr.open('GET', url: 'www.myurl.com/js/data/data.json', true); xhr.send(null); I have ...

Strategies for avoiding text selection interference with onMouseMove event

I am in the process of adding a "resize handle" to adjust the width of my left navigation panel. This handle, represented by a div, triggers an onMouseDown() event that calculates the necessary widths and applies them to the relevant elements during subseq ...

Issues with image uploads in Node.js database storage

Trying to update an image using the put method is resulting in a 'filename' undefined error. Interestingly, the image updates successfully when editing without changing the image. The code snippet below shows the implementation: app.put('/a ...

`The header navigation is not responding to window resizing functionality`

I am currently developing a header navigation that consists of a logo on the left side, a profile icon on the right side, and some navigation links in the middle. A left slide menu has been implemented to trigger when the window width is less than 700px. ...

The NGINX reverse proxy fails to forward requests to an Express application

I am currently in the process of setting up a dedicated API backend for a website that operates on /mypath, but I am encountering issues with NGINX not properly proxying requests. Below is the nginx configuration located within the sites-enabled directory ...

Can you explain the inner workings of the sort function in JavaScript, including how it utilizes the compare

I'm curious about how the sort function operates in JavaScript, specifically in conjunction with the compare function. According to what I've read, if you have an array and use the code array.sort(compare), it's stated that if the compare fu ...

Is it possible to resend an AJAX request using a hyperlink?

Is it possible to refresh only the AJAX request and update the content fetched from an external site in the code provided below? $(document).ready(function () { var mySearch = $('input#id_search').quicksearch('#content table', ...

Submitting Files with jQuery AJAX in the ASP.NET MVC Framework

Currently, I am working on an application that requires me to upload a file using AJAX. I have implemented the jQuery.form library for this purpose, but strangely, when the action is triggered, the controller receives an empty list of files. Below is the H ...

Updating two separate <DIV> elements with a single AJAX request

Can two different targeted DIVs be updated simultaneously using a single ajax call? Consider the index.html code snippet below: <script> xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.rea ...

The 'data' variable is not defined in the React custom hook Pagination

I am currently working with an API that shows music categories on a browser, and I'm attempting to create a custom pagination hook. However, I keep encountering an error stating "object is not iterable." I am new to custom hooks and would appreciate a ...

Is there a way to retrieve nested data from a JSON API response?

Trying my hand at creating a basic CLI cryptocurrency tracker app. The app runs a successful API call and provides the following output: [ { exchange: 'binance', base: 'ADA', quote: 'BTC', price_quote: '0.000 ...

Preventing PCs from accessing a specific webpage: A step-by-step guide

I am currently using the code below to block phones: if { /Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i .test(navigator.userAgent)) { window.location = "www.zentriamc.com/teachers/error ...

Save the content of the textbox on the webpage automatically, no need for a webservice or settimeout

Is there a way to save the text entered in a textbox on a webpage automatically, without relying on a webservice or the settimeout function? Any help would be greatly appreciated.Thank you in advance. ...

Error: The function sendFile does not exist in the method res.status(...)

As a newcomer to this field, I must apologize if my issue has an obvious solution. However, I am encountering the following error: TypeError: res.status(...).sendFile is not a function at app.get (/root/discordtest/server.js:10:19) at callbacks (/ ...

How can one properly utilize material-ui CSS?

Just starting out with material-ui and react, I'm currently following this palette customization guide from Material-UI. However, when attempting to replicate the example shown, I encountered the error: Cannot read property 'prepareStyles' ...

Add a third-party library file to Visual Studio

I'm currently working in Visual Studios and attempting to utilize the library provided at . However, I am encountering difficulties when trying to import the library. I have added the file to the project and attempted to use it within the Book.js (Vi ...

What is the optimal approach for importing node modules using var or const?

When it comes to requiring node modules like express or bodyParser, the commonly used keyword to create a variable and assign the module is var. However, is it possible to use const to declare such modules instead? In other words, instead of the following: ...