Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for hiding, deleting, or managing individual instances in InstancedMesh #30403

Closed
Pulkit0729 opened this issue Jan 26, 2025 · 1 comment
Milestone

Comments

@Pulkit0729
Copy link

Description

Currently, THREE.InstancedMesh is great for rendering large numbers of instances efficiently, but managing individual instances (e.g., hiding or deleting them) is not directly supported. Adding these features would improve usability for developers creating dynamic scenes while retaining the performance benefits of InstancedMesh
Proposed API:

// Hide instance
instancedMesh.hideInstance(index);

// Show instance with position, rotation, and scale
instancedMesh.showInstance(index, position, rotation, scale);

// Delete instance (mark as inactive or remove from rendering)
instancedMesh.deleteInstance(index);

Use Cases:

  1. Hiding instances when they are no longer needed in dynamic gameplay.
  2. Deleting instances to manage resources in real-time applications.
  3. Animating or interacting with individual instances in visualization projects.

Solution

We can create more matrices for controlling visiblity or other properties, and add it into instance mesh vertex shaders and fragment shaders.

import * as THREE from 'three';

class CustomInstancedMesh extends THREE.InstancedMesh {
  constructor(geometry, material, count) {
    super(geometry, material, count);
    this.instanceStates = new Array(count).fill(true); // Track visibility
  }

  hideInstance(index) {
    if (index >= 0 && index < this.count) {
      this.instanceStates[index] = false;
      const matrix = new THREE.Matrix4();
      matrix.makeScale(0, 0, 0); // Scale it down to "hide"
      this.setMatrixAt(index, matrix);
      this.instanceMatrix.needsUpdate = true;
    }
  }

  showInstance(index, position, rotation, scale) {
    if (index >= 0 && index < this.count) {
      this.instanceStates[index] = true;
      const matrix = new THREE.Matrix4();
      const quaternion = new THREE.Quaternion();
      quaternion.setFromEuler(new THREE.Euler(...rotation));

      matrix.compose(position, quaternion, scale);
      this.setMatrixAt(index, matrix);
      this.instanceMatrix.needsUpdate = true;
    }
  }

  deleteInstance(index) {
    this.hideInstance(index); // Optional: Just hide it for now
    this.instanceStates[index] = null; // Mark as "deleted"
  }
}

Alternatives

NA

Additional context

No response

@gkjohnson
Copy link
Collaborator

gkjohnson commented Jan 27, 2025

If you'd like to hide meshes you can use a small scale matrix as you've suggested. Otherwise BatchedMesh supports instancing with the ability to hide individual items in addition to other optional performance features like frustum culling and sorting. I don't feel we need to change InstancedMesh in this case.

@Mugen87 Mugen87 closed this as not planned Won't fix, can't repro, duplicate, stale Jan 27, 2025
@Mugen87 Mugen87 added this to the r173 milestone Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants