giulioz Github contribution chart
giulioz Github Stats
giulioz Most Used Languages

Activity

01 Oct 2022

Giulioz

started

Started On 01 Oct 2022 at 01:10:22

Giulioz

started

Started On 30 Sep 2022 at 09:35:15

Giulioz

Built

Pushed On 25 Sep 2022 at 02:41:38

Giulioz

Added fixedZ option

Pushed On 25 Sep 2022 at 02:37:16

Giulioz

started

Started On 24 Sep 2022 at 06:12:18

Giulioz

started

Started On 22 Sep 2022 at 09:06:45

Giulioz

started

Started On 21 Sep 2022 at 09:54:40

Giulioz

started

Started On 19 Sep 2022 at 09:36:02

Giulioz

started

Started On 18 Sep 2022 at 09:15:10

Giulioz

started

Started On 15 Sep 2022 at 02:02:51

Giulioz

started

Started On 13 Sep 2022 at 03:49:07

Giulioz

started

Started On 05 Sep 2022 at 09:54:38

Giulioz

started

Started On 05 Sep 2022 at 08:25:26

Giulioz

started

Started On 04 Sep 2022 at 08:53:57

Giulioz

started

Started On 03 Sep 2022 at 02:54:10

Giulioz

started

Started On 01 Sep 2022 at 09:06:38

Giulioz

started

Started On 31 Aug 2022 at 09:43:50

Giulioz

New interop

Pushed On 28 Aug 2022 at 11:43:52

Giulioz

Cleanup

Pushed On 28 Aug 2022 at 11:43:52

Giulioz

Moved to optional

Pushed On 28 Aug 2022 at 11:18:18

Giulioz

Build VMM32

Pushed On 28 Aug 2022 at 11:18:18

Giulioz

started

Started On 27 Aug 2022 at 09:07:05

Giulioz

started

Started On 23 Aug 2022 at 09:26:23

Giulioz

started

Started On 22 Aug 2022 at 09:21:18
Issue Comment

Giulioz

Memory Leak in LineGeometry

Describe the bug

Calling the setPositions function of LineGeometry or LineSegmentsGeometry multiple times results in a memory leak that can crash the application. This happens because every time its called it creates a new Float32Array, InstancedInterleavedBuffer and two InterleavedBufferAttribute, instead of reusing the old ones.

To Reproduce

Steps to reproduce the behavior:

  1. Create a scene with ~400 Line2s
  2. During every frame, call setPositions on their geometry to update them
  3. Let it run for some seconds
  4. The entire browser freezes and the WebGL context gets lots

Code

import * as THREE from "https://unpkg.com/three/build/three.module.js";
import { Line2 } from "https://unpkg.com/three/examples/jsm/lines/Line2.js";

var lines, renderer, scene, camera;

// Increase this number until it crashes (100 is enough for firefox)
const n = 5;

init();
animate();

function init() {
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(window.devicePixelRatio);
  document.body.appendChild(renderer.domElement);

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(
    40,
    window.innerWidth / window.innerHeight,
    0.1,
    10000
  );
  camera.position.set(0, 0, 4);

  lines = new Array(n).fill(0).map(() => new Line2());
  lines.forEach((line) => scene.add(line));
}

function animate(t) {
  requestAnimationFrame(animate);

  lines.forEach((line, i) => {
    line.material.resolution.set(window.innerWidth, window.innerHeight);
    const x = Math.cos(t + i / 20) * 2;
    const y = Math.sin(t + i / 20) * 2;
    line.geometry.setPositions([x, y, 0, x * 2 * (i / n), y * 2 * (i / n), 0]);
  });
  renderer.render(scene, camera);
} 

Live example

Expected behavior

Not crash, reusing the same attributes.

Screenshots

Not necessary.

Platform:

  • Device: [Desktop]
  • OS: [MacOS]
  • Browser: [Chrome, Firefox]
  • Three.js version: [dev, r143]

Forked On 20 Aug 2022 at 04:02:20

Giulioz

LineSegmentsGeometry.setPositions(), and the other "set" methods in the file, are intended to be called only once.

LineSegmentsGeometry.setPositions(), and the other "set" methods in the file, are intended to be called only once.

Well, I guess at least now there are at least two times on the web this detail is mentioned. Closing the issue as there is now info on how to avoid this and a solution on the issue itself.

Commented On 20 Aug 2022 at 04:02:20
Issue Comment

Giulioz

Memory Leak in LineGeometry

Describe the bug

Calling the setPositions function of LineGeometry or LineSegmentsGeometry multiple times results in a memory leak that can crash the application. This happens because every time its called it creates a new Float32Array, InstancedInterleavedBuffer and two InterleavedBufferAttribute, instead of reusing the old ones.

To Reproduce

Steps to reproduce the behavior:

  1. Create a scene with ~400 Line2s
  2. During every frame, call setPositions on their geometry to update them
  3. Let it run for some seconds
  4. The entire browser freezes and the WebGL context gets lots

Code

import * as THREE from "https://unpkg.com/three/build/three.module.js";
import { Line2 } from "https://unpkg.com/three/examples/jsm/lines/Line2.js";

var lines, renderer, scene, camera;

// Increase this number until it crashes (100 is enough for firefox)
const n = 5;

init();
animate();

function init() {
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(window.devicePixelRatio);
  document.body.appendChild(renderer.domElement);

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(
    40,
    window.innerWidth / window.innerHeight,
    0.1,
    10000
  );
  camera.position.set(0, 0, 4);

  lines = new Array(n).fill(0).map(() => new Line2());
  lines.forEach((line) => scene.add(line));
}

function animate(t) {
  requestAnimationFrame(animate);

  lines.forEach((line, i) => {
    line.material.resolution.set(window.innerWidth, window.innerHeight);
    const x = Math.cos(t + i / 20) * 2;
    const y = Math.sin(t + i / 20) * 2;
    line.geometry.setPositions([x, y, 0, x * 2 * (i / n), y * 2 * (i / n), 0]);
  });
  renderer.render(scene, camera);
} 

Live example

Expected behavior

Not crash, reusing the same attributes.

Screenshots

Not necessary.

Platform:

  • Device: [Desktop]
  • OS: [MacOS]
  • Browser: [Chrome, Firefox]
  • Three.js version: [dev, r143]

Forked On 20 Aug 2022 at 03:41:30

Giulioz

I did that in my solution, but still it seems an abstraction leak having to rely on mutating the buffers directly, when a method could do that for you.

Also I couldn't find any info anywhere in the docs about the fact that "set" methods are intended to be called just once. What about calling it setInitialPositions or something like that, and adding a method updatePositions to do this without crashing the browser? I'm seeing a lot of code online that is calling setPositions every frame without knowing this detail, at least a comment could help.

For anyone interested, this is how I've done it:

const attributeStarts = line.geometry.getAttribute("instanceStart");
for (let i = 0; i < points.length - 3; i += 3) {
  attributeStarts.array[2 * i] = points[i];
  attributeStarts.array[2 * i + 1] = points[i + 1];
  attributeStarts.array[2 * i + 2] = points[i + 2];

  attributeStarts.array[2 * i + 3] = points[i + 3];
  attributeStarts.array[2 * i + 4] = points[i + 4];
  attributeStarts.array[2 * i + 5] = points[i + 5];
}
attributeStarts.needsUpdate = true;
line.geometry.computeBoundingBox();
line.geometry.computeBoundingSphere(); 

Commented On 20 Aug 2022 at 03:41:30

Giulioz

Added stuff

Pushed On 14 Aug 2022 at 07:18:03

Giulioz

started

Started On 14 Aug 2022 at 11:12:41

Giulioz

Readme

Pushed On 14 Aug 2022 at 10:11:11

Giulioz

Fix CI

Pushed On 14 Aug 2022 at 10:07:28