pmndrs / react-three-fiber

🇨🇭 A React renderer for Three.js
https://docs.pmnd.rs/react-three-fiber
MIT License
27.62k stars 1.6k forks source link

How do I use PointNodeMaterials in React Three Fiber? #3140

Closed Ludobico closed 10 months ago

Ludobico commented 10 months ago

Hello, I've come across some source code that implements a GLTF model animated with ThreeJS as a PointCloud.

When I tried to change it to react format with this code and use it, I got this error.

Uncaught TypeError: Cannot read properties of undefined (reading 'value')

and this is the code that i used

import * as THREE from 'three';
import { uniform, skinning, PointsNodeMaterial } from 'three/examples/jsm/nodes/Nodes.js';

const GltfModel = () => {
  let scene, mixer;
  const gltf = useLoader(GLTFLoader, '/models/Michelle.glb');
  mixer = new THREE.AnimationMixer(gltf.scene);
  const action = mixer.clipAction(gltf.animations[0]);
  scene = new THREE.Scene();

  action.play();
  gltf.scene.traverse((mesh) => {
    if (mesh.isMesh) {
      mesh.visible = false;
      const materialPoints = new PointsNodeMaterial();
      materialPoints.colorNode = uniform(new THREE.Color());
      materialPoints.positionNode = skinning(mesh);

      const pointCloud = new THREE.Points(mesh.geometry, materialPoints);
      scene.add(pointCloud);
    }
  });
  scene.add(gltf.scene);
  useFrame((state, delta) => {
    mixer.update(delta);
  });
  return <primitive object={scene} scale={1} position={[0, 1, 0]} />;
};

const Scene = () => {
  const aspect_ratio = window.innerWidth / window.innerHeight;
  const cameraRef = useRef();
  const cameraHandler = () => {
    // console.log(cameraRef.current);
  };
  const pervPosition = new THREE.Vector3(1.03, 0.95, 1.1);
  return (
    <>
      <directionalLight intensity={5} />
      <OrbitControls enableRotate={true} onChange={cameraHandler} />
      <PerspectiveCamera
        makeDefault
        aspect={aspect_ratio}
        castShadow={true}
        far={1000}
        focus={10}
        fov={75}
        near={0.1}
        position={pervPosition}
        rotation={[-0.71, 0.62, 0.46]}
        ref={cameraRef}
      />
      <Light />
      {/* <PointGltfModel /> */}
      <GltfModel />
      {/* <GeometryScene /> */}
    </>
  );
};

const ThreeContainer = () => {
  return (
    <div className="scene_container">
      <Canvas style={{ width: '100vw', height: '100vh' }}>
        <Scene />
      </Canvas>
    </div>
  );
};

How do I fix it?

I'll also share the code implemented in threejs.

https://threejs.org/examples/?q=point#webgpu_skinning_points