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

Luma takes over the scene depth and conflicts with threejs GLTFs. #31

Open
ChristopherTrimboli opened this issue Jul 18, 2024 · 2 comments

Comments

@ChristopherTrimboli
Copy link

Screencast.from.2024-07-18.12-34-29.webm
  useEffect(() => {
    Object.values(materials).forEach((material) => {
      material.depthTest = false;
      material.needsUpdate = true;
    })

    Object.values(nodes).forEach((node) => {
      node.renderOrder = 9000;
    })
  }, [materials, nodes])

I've tried stuff like this to no avail.

@bill9109
Copy link

Did you find a way to solve this problem?

@ChristopherTrimboli
Copy link
Author

I found the solution... finally...

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx [email protected] ./public/glbs/simple-brown-desk.glb --output ./app/components/gltf/SimpleBrownDesk.tsx 
Author: Thunder (https://sketchfab.com/thunderpwn)
License: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
Source: https://sketchfab.com/3d-models/simple-dirty-desk-fec8ded4a31549be8aaaad7c9bf414d2
Title: Simple dirty Desk
*/

import * as THREE from "three";
import React, { useEffect, useMemo } from "react";
import { useGLTF } from "@react-three/drei";
import { GLTF } from "three-stdlib";

type GLTFResult = GLTF & {
  nodes: {
    Cube__0: THREE.Mesh;
  };
  materials: {
    ["Scene_-_Root"]: THREE.MeshStandardMaterial;
  };
};

export function Model(props: JSX.IntrinsicElements["group"]) {
  const { nodes, materials } = useGLTF(
    "/glbs/simple-brown-desk.glb"
  ) as GLTFResult;

  /**
   * Clone all materials to ensure each instance has its own unique material.
   * This prevents shared state conflicts when materials are modified elsewhere
   * (e.g., by LumaSplats or other scene components).
   */
  const clonedMaterials = useMemo(() => {
    const newMaterials: Record<string, THREE.MeshStandardMaterial> = {};

    Object.entries(materials).forEach(([key, material]) => {
      const clonedMaterial = material.clone();

      if (clonedMaterial.map) {
        clonedMaterial.map = clonedMaterial.map.clone();
      }

      if (clonedMaterial.normalMap) {
        clonedMaterial.normalMap = clonedMaterial.normalMap.clone();
      }
      if (clonedMaterial.roughnessMap) {
        clonedMaterial.roughnessMap = clonedMaterial.roughnessMap.clone();
      }

      newMaterials[key] = clonedMaterial;
    });

    return newMaterials;
  }, [materials]);

  /**
   * Cleanup function to dispose of cloned materials when the component unmounts
   * or when materials change. This prevents memory leaks.
   */
  useEffect(() => {
    return () => {
      Object.values(clonedMaterials).forEach((material) => {
        material.dispose();

        if (material.map) material.map.dispose();
        if (material.normalMap) material.normalMap.dispose();
        if (material.roughnessMap) material.roughnessMap.dispose();
      });
    };
  }, [clonedMaterials]);

  return (
    <group {...props}>
      <group scale={0.01}>
        <mesh
          geometry={nodes.Cube__0.geometry}
          material={clonedMaterials["Scene_-_Root"]}
          rotation={[-Math.PI / 2, 0, 0]}
          scale={1.166}
        />
      </group>
    </group>
  );
}

useGLTF.preload("/glbs/simple-brown-desk.glb");

image

My guess is GLTFJSX virtual scene bugs this out.

Add this clonedMaterials system into the GLTF component.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants