OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

ThreeJS scene slows down considerably as I add objects and try to dispose of them

  • Thread starter Thread starter docaberle
  • Start date Start date
D

docaberle

Guest
I'm dynamically creating a pulse wave display generator. I've taken it down to bare bones so the code is shorter. Runs really smooth when I start, but as I scrub the frequency bar the playback slows down considerably like when moving the scene left and right with the right mouse button. I'm guessing since I keep creating a new Buffer Geometry object each time I change the frequency and I'm somehow not disposing of it properly, that I end up taxing my GPU significantly. Or am I calling animate() or init() way too much? Or not disposing of my objects properly? Or is plotting 400,000 lines just way too much when I put the frequency at 100,000? Kinda new to threejs. Hoping it's something obvious.

Code:
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';

// Canvas
const canvas = document.querySelector('canvas.webgl');
let SCREEN_WIDTH = window.innerWidth;
let SCREEN_HEIGHT = window.innerHeight;

var scene, camera, renderer;
var frequencySuperPulse = 10000;
var startXPos, controls;
var geomSuperPulse, matSuperPulse, posSuperPulse, paSuperPulse, linesSuperPulse;;


// Camera - Scene - Renderer Initialization
scene = new THREE.Scene();
camera = new THREE.OrthographicCamera (SCREEN_WIDTH/-2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_HEIGHT/-2, 150, 1000);
camera.position.z = 200;
renderer = new THREE.WebGLRenderer({antialias:true, canvas: canvas});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// LIGHTS
const dirLight = new THREE.DirectionalLight( 0xffffff, 0.4 );
dirLight.position.set( 0, 0, 1 ).normalize();
scene.add( dirLight );

// ORBIT CONTROLS
controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enableRotate = false;
controls.zoomSpeed = 5;
controls.zoomToCursor = true;
controls.addEventListener( 'change', getControlsZoom );
var zoomResult = document.getElementById( 'zoom' );
function getControlsZoom( )
{
        zoomResult.innerHTML = 'Zoom = '+(Math.round(camera.zoom));
}

// GUI
const parameters = {
    frequencySuperPulse: frequencySuperPulse, //The second frequncy is the variable up at the top for initial value
};
function updateWaveformfrequencySuperPulse() {
    frequencySuperPulse = parameters.frequencySuperPulse;
    scene.remove(linesSuperPulse);
    geomSuperPulse.dispose();
    matSuperPulse.dispose();
    init();
}
const gui = new GUI({width: 400, title:'Laser Controls'});
const waveformoptionsSuperPulse = gui.addFolder( 'Super Pulse' );
waveformoptionsSuperPulse.add( parameters, 'frequencySuperPulse', 10000, 100000, 10000).onChange( updateWaveformfrequencySuperPulse ).name('Frequency (Hz)');
waveformoptionsSuperPulse.open();

function init() {
    // Add Super Pulse Waveform...
    geomSuperPulse = new THREE.BufferGeometry();
    geomSuperPulse.setAttribute("position", new THREE.BufferAttribute(new Float32Array(15*frequencySuperPulse), 3));
    posSuperPulse = geomSuperPulse.getAttribute("position");
    paSuperPulse = posSuperPulse.array;
    for (let line_index= 0; line_index < frequencySuperPulse; line_index++) {
        startXPos = -200 + line_index*500/frequencySuperPulse;          //Need five points to describe a cycle.
        
        //Point 1
        paSuperPulse[15*line_index] = startXPos;
        paSuperPulse[15*line_index+1] = 0;
        paSuperPulse[15*line_index+2] = 0;
        //Point 2
        paSuperPulse[15*line_index+3] = startXPos;
        paSuperPulse[15*line_index+4] = 13000;
        paSuperPulse[15*line_index+5] = 0;
        //Point 3
        paSuperPulse[15*line_index+6] = startXPos + 35*10**-9 * 500;
        paSuperPulse[15*line_index+7] = 13000;
        paSuperPulse[15*line_index+8] = 0;
        //Point 4
        paSuperPulse[15*line_index+9] = startXPos + 35*10**-9 * 500;
        paSuperPulse[15*line_index+10] = 0;
        paSuperPulse[15*line_index+11] = 0;
        //Point 5
        paSuperPulse[15*line_index+12] = startXPos + 500/frequencySuperPulse;
        paSuperPulse[15*line_index+13] = 0;
        paSuperPulse[15*line_index+14] = 0;
    }
    
    matSuperPulse = new THREE.LineBasicMaterial({color: 0xffffff});
    linesSuperPulse = new THREE.Line(geomSuperPulse, matSuperPulse);
    scene.add(linesSuperPulse);
    animate();
}

function animate() {
    posSuperPulse.needsUpdate = true;
    controls.update();
    renderer.render(scene,camera);
    requestAnimationFrame(animate);
}
init();

<p>I'm dynamically creating a pulse wave display generator. I've taken it down to bare bones so the code is shorter. Runs really smooth when I start, but as I scrub the frequency bar the playback slows down considerably like when moving the scene left and right with the right mouse button. I'm guessing since I keep creating a new Buffer Geometry object each time I change the frequency and I'm somehow not disposing of it properly, that I end up taxing my GPU significantly. Or am I calling animate() or init() way too much? Or not disposing of my objects properly? Or is plotting 400,000 lines just way too much when I put the frequency at 100,000? Kinda new to threejs. Hoping it's something obvious.</p>
<pre><code>import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';

// Canvas
const canvas = document.querySelector('canvas.webgl');
let SCREEN_WIDTH = window.innerWidth;
let SCREEN_HEIGHT = window.innerHeight;

var scene, camera, renderer;
var frequencySuperPulse = 10000;
var startXPos, controls;
var geomSuperPulse, matSuperPulse, posSuperPulse, paSuperPulse, linesSuperPulse;;


// Camera - Scene - Renderer Initialization
scene = new THREE.Scene();
camera = new THREE.OrthographicCamera (SCREEN_WIDTH/-2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_HEIGHT/-2, 150, 1000);
camera.position.z = 200;
renderer = new THREE.WebGLRenderer({antialias:true, canvas: canvas});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// LIGHTS
const dirLight = new THREE.DirectionalLight( 0xffffff, 0.4 );
dirLight.position.set( 0, 0, 1 ).normalize();
scene.add( dirLight );

// ORBIT CONTROLS
controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enableRotate = false;
controls.zoomSpeed = 5;
controls.zoomToCursor = true;
controls.addEventListener( 'change', getControlsZoom );
var zoomResult = document.getElementById( 'zoom' );
function getControlsZoom( )
{
zoomResult.innerHTML = 'Zoom = '+(Math.round(camera.zoom));
}

// GUI
const parameters = {
frequencySuperPulse: frequencySuperPulse, //The second frequncy is the variable up at the top for initial value
};
function updateWaveformfrequencySuperPulse() {
frequencySuperPulse = parameters.frequencySuperPulse;
scene.remove(linesSuperPulse);
geomSuperPulse.dispose();
matSuperPulse.dispose();
init();
}
const gui = new GUI({width: 400, title:'Laser Controls'});
const waveformoptionsSuperPulse = gui.addFolder( 'Super Pulse' );
waveformoptionsSuperPulse.add( parameters, 'frequencySuperPulse', 10000, 100000, 10000).onChange( updateWaveformfrequencySuperPulse ).name('Frequency (Hz)');
waveformoptionsSuperPulse.open();

function init() {
// Add Super Pulse Waveform...
geomSuperPulse = new THREE.BufferGeometry();
geomSuperPulse.setAttribute("position", new THREE.BufferAttribute(new Float32Array(15*frequencySuperPulse), 3));
posSuperPulse = geomSuperPulse.getAttribute("position");
paSuperPulse = posSuperPulse.array;
for (let line_index= 0; line_index < frequencySuperPulse; line_index++) {
startXPos = -200 + line_index*500/frequencySuperPulse; //Need five points to describe a cycle.

//Point 1
paSuperPulse[15*line_index] = startXPos;
paSuperPulse[15*line_index+1] = 0;
paSuperPulse[15*line_index+2] = 0;
//Point 2
paSuperPulse[15*line_index+3] = startXPos;
paSuperPulse[15*line_index+4] = 13000;
paSuperPulse[15*line_index+5] = 0;
//Point 3
paSuperPulse[15*line_index+6] = startXPos + 35*10**-9 * 500;
paSuperPulse[15*line_index+7] = 13000;
paSuperPulse[15*line_index+8] = 0;
//Point 4
paSuperPulse[15*line_index+9] = startXPos + 35*10**-9 * 500;
paSuperPulse[15*line_index+10] = 0;
paSuperPulse[15*line_index+11] = 0;
//Point 5
paSuperPulse[15*line_index+12] = startXPos + 500/frequencySuperPulse;
paSuperPulse[15*line_index+13] = 0;
paSuperPulse[15*line_index+14] = 0;
}

matSuperPulse = new THREE.LineBasicMaterial({color: 0xffffff});
linesSuperPulse = new THREE.Line(geomSuperPulse, matSuperPulse);
scene.add(linesSuperPulse);
animate();
}

function animate() {
posSuperPulse.needsUpdate = true;
controls.update();
renderer.render(scene,camera);
requestAnimationFrame(animate);
}
init();
</code></pre>
 

Online statistics

Members online
0
Guests online
3
Total visitors
3
Top