tentone / potree-core

Potree point cloud viewer library core components for easier integration in a three.js project.
https://tentone.github.io/potree-core/
Other
177 stars 54 forks source link

Washed out colors when compared to similar `potree` scene #44

Closed towner-10 closed 1 month ago

towner-10 commented 1 month ago

I’m experiencing an issue where the colors are washed out compared to the standard potree viewer.

potree-core implementation potree-core

V.S.

potree implementation potree

Here is my React code to reproduce:

import { FlyControls, PointerLockControls } from '@react-three/drei';
import { Canvas, useFrame, useThree } from '@react-three/fiber';
import { PointSizeType, Potree, type PointCloudOctree } from 'potree-core';
import { useEffect, useState } from 'react';
import { cn } from '~/lib/utils';
import { useStore } from './store';

const potree = new Potree();

function Renderer() {
    const { size, shape, budget, setCameraPosition, setCameraRotation } = useStore();
    const scene = useThree((state) => state.scene);
    const [pointClouds, setPointClouds] = useState<PointCloudOctree[]>([]);

    useEffect(() => {
        potree.pointBudget = budget;

        (async () => {
            const result = await potree.loadPointCloud(
                'metadata.json',
                (url) => `/scans/testing_scan/output/${url}`
            );

            result.position.set(0, 0, 0);

                        // Ensure the axes are aligned with the world axes
            result.rotation.x = -Math.PI / 2;

            result.material.shape = shape;
            result.material.size = size;

            // Set the point size type to adaptive
            result.material.pointSizeType = PointSizeType.ADAPTIVE;

            // Set to proper shader
            result.material.updateShaderSource();

            console.log(result.material);

            scene.clear();
            scene.add(result);
            setPointClouds([result]);
        })();
    }, []);

    useEffect(() => {
        potree.pointBudget = budget;
    }, [budget]);

    useEffect(() => {
        if (!pointClouds.length) return;

        // Only ever one point cloud
        const pointCloud = pointClouds[0];

        pointCloud.material.shape = shape;
        pointCloud.material.size = size;
    }, [size, shape]);

    useFrame(({ gl, camera }) => {
        potree.updatePointClouds(pointClouds, camera, gl);
        gl.clear();
        gl.render(scene, camera);
        setCameraPosition([camera.position.x, camera.position.y, camera.position.z]);
        setCameraRotation([camera.rotation.x, camera.rotation.y, camera.rotation.z]);
    });

    return (
        <>
            <PointerLockControls selector="#potree-canvas">
                <FlyControls makeDefault movementSpeed={5} rollSpeed={0} />
            </PointerLockControls>
        </>
    );
}

export default function ({ className }: { className?: string }) {
    return (
        <div className={cn('relative h-full w-full rounded-lg border bg-card shadow-sm', className)}>
            <Canvas id="potree-canvas">
                <Renderer />
            </Canvas>
        </div>
    );
}
towner-10 commented 1 month ago

This is solved by making the input encoding matches the output:

result.material.inputColorEncoding = 1;
result.material.outputColorEncoding = 1;