pmndrs / drei

🥉 useful helpers for react-three-fiber
https://drei.pmnd.rs/
MIT License
7.82k stars 642 forks source link

BVH rebuilds its internal tree at each frame which makes it unusable #1715

Open merwaaan opened 7 months ago

merwaaan commented 7 months ago

Problem description:

The BVH component rebuilds its internal tree at each frame, which makes it unusably slow.

It uses a useEffect without dependencies, so the effect and its cleanup function are ran at each render. The effect computes an internal tree for each child mesh that does not have one. The cleanup destroys those trees. So at each render, all the trees are recomputed which is very slow for large meshes.

Given that this component aims at speeding up raycasting for large meshes, this behavior makes it unusable.

Relevant code:

https://github.com/pmndrs/drei/blob/3a3e3ec9c5292144df8e12ec3759af46ffdca74a/src/core/useBVH.tsx#L79-L106

mynameisgump commented 7 months ago

If you're looking for a potential work around I had luck with this issue previously by memoizing the BVH component wrapped around the meshes I wanted to use it on. Example:

const Example1 = () => (
  // This will re-calc the bounds tree on re-render and cause lag
  <Canvas>
    <Bvh>
      <BigMesh />
    </Bvh>
  </Canvas>
);
const Example2 = () => {
  // Bounds tree is only calculated once since BVH component persists on re-render
  const bvhMesh = useMemo(
    () => (
      <Bvh>
        <BigMesh />
      </Bvh>
    ),
    []
  );
  return <Canvas>{bvhMesh}</Canvas>;
};
mynameisgump commented 7 months ago

Solved by https://github.com/pmndrs/drei/pull/1718#issue-1993705837, so issue can be closed