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

Troubleshooting InstancedMesh2 in R3F: culling issues / manual instance creation #91

Open
raptyk opened this issue Jul 30, 2024 · 4 comments

Comments

@raptyk
Copy link

raptyk commented Jul 30, 2024

I am trying to use component InstancedMesh2 in my R3F based project. I am manually creating instances and adding to the scene. Before rendering I call updateCulling however nothing happens, i.e. the number of rendered objects remains the same despite, for example, a different camera placement. What am I doing wrong ? Can I use InstancedMesh2 in this way (e.g. without initializing the “main” object from the library) ?

chrome_rwGQt6rrN5

const GridPureJSIM2: React.FC<GridProps> = ({ grid, size = 200 }) => {
    const { scene, camera } = useThree();
    const gridHalfSize = size / 2;
    const countX = grid.length;
    const countY = grid[0].length;

    const visibleSquares = useMemo(() => {
        const squares = [];
        for (let x = 0; x < countX; x++) {
            for (let y = 0; y < countY; y++) {
                if (grid[x][y].visible) {
                    squares.push([x - gridHalfSize, y - gridHalfSize]);
                }
            }
        }
        return squares;
    }, []);

    const geometry = new THREE.BoxGeometry(1, 1, 0.1);
    const material = new THREE.MeshBasicMaterial({ color: 'darkblue' });


// MAIN PART :

    const trees = new InstancedMesh2(geometry, material, visibleSquares.length, {
        behaviour: CullingStatic,
        onInstanceCreation: (obj, i) => {
            // const [x, y, z] = visibleSquares[i];
            // obj.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2).setPosition(x + 0.5, 0.01, y + 0.5));
        }
    });

    React.useEffect(() => {
        for (let i = 0; i < visibleSquares.length; i++) {
            const [x, y, z] = visibleSquares[i];
            trees.setMatrixAt(i, new THREE.Matrix4().makeRotationX(Math.PI / 2).setPosition(x + 0.5, 0.01, y + 0.5));
        }

        trees.updateMatrix();
        camera.updateMatrixWorld(true);
        scene.add(trees);

        return () => {
            scene.remove(trees);
            trees.dispose();
            geometry.dispose();
            material.dispose();
        };
    }, [visibleSquares, scene]);

    useFrame(() => {
        trees.updateCulling(camera);
    }, -1); //before render**

    return null;
};

export default GridPureJSIM2;
@agargaro
Copy link
Owner

When using CullingStatic it's necessary to initialize the matrices of all instances inside the onInstanceCreation callback, because this creates a BVH that can no longer be modified (that's why it's static).

However, I will soon release a new library, completely rewritten, with better performance and more features, including sorting, dynamic BVH, and no more need to call updateCulling manually.

Repository of new library: https://github.com/three-ez/instanced-mesh

I am glad to see my library also used with r3f, if you want we can write each other on discord so I can let you try the new library too.

@agargaro
Copy link
Owner

I have prepared an example for you with the new library:

https://stackblitz.com/edit/three-ez-instancedmesh2-test?file=src%2Fmain.ts

What do you think? :)

@raptyk
Copy link
Author

raptyk commented Aug 1, 2024

Thanks for the quick response and the prepared example! It looks very promising! Despite the large number of objects fps are at maximum level. Everything works as it should.

However, I will soon release a new library, completely rewritten, with better performance and more features, including sorting, dynamic BVH, and no more need to call updateCulling manually.

So far I have been using the https://www.npmjs.com/package/@three.ez/instanced-mesh version.
I searched the npm repository by name and found https://www.npmjs.com/package/@three.ez/instanced-mesh-test/v/0.0.4 - is this the current "beta" version I should use ?

@agargaro
Copy link
Owner

agargaro commented Aug 1, 2024

is this the current "beta" version I should use ?

Yes. It's a test package which I will remove later (be sure to use the latest version). Once I'm done I will post again on the '@three.ez/instanced-mesh' package.

I am not very convinced about how to initialize BVH, so I will definitely change the API a bit.

I am open to advice on how to simplify the use of the library 😄

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