How to match Blender color in R3F

Hello,

I’m working on a scene using react three fiber and no matter what I try I can’t get the colors similar to the ones I can get in Blender - they just look too vibrant. I’ve tried setting and unsetting the tonemapping in both R3F and Blender and nothing is working.

Here’s what I’m trying to achieve and my color management settings in blender:

And here is what my scene looks like in R3F:

Here is how the scene is set up:

function DirectionalLightWithHelper() {
    const light = useRef();
    useHelper(light, DirectionalLightHelper, 1, 'crimson');

    const shadow = useRef();
    useHelper(shadow, CameraHelper);

    return (
        <directionalLight
            ref={light}
            intensity={5}
            position={[0, 10, 0]}
            rotation={[-Math.PI / 2, 0, 0]}
            castShadow
        >
            <orthographicCamera
            attach='shadow-camera'
            ref={shadow}
            args={[-2.5, 2.5, 2.5, -2.5]}
        />
        </directionalLight>
    );
}

function DirectionalLightAndHelper() {
    const light = useRef();
    useHelper(light, DirectionalLightHelper, 1, 'green');

    const shadow = useRef();
    useHelper(shadow, CameraHelper);

    return (
        <directionalLight
            ref={light}
            intensity={5}
            position={[2.37, 1.68, -2.62]}
            rotation={[-71.77, -0.08, -35.33]}
            castShadow
        >
            <orthographicCamera
                attach='shadow-camera'
                ref={shadow}
                args={[-2.5, 2.5, 2.5, -2.5]}
            />
        </directionalLight>
    );
}
const About = () => {
    return (
        <section className={"section-bg"}>
            <div className={"BgContainer"}>
                <div className={"w-full h-full absolute inset-0 p-6"}>
                    <Canvas className={"w-full h-full rounded-[50px]"} shadows>

                        <Environment
                            files="/textures/SUBWAY_Q_TRAIN.exr"
                            environmentIntensity={.2}
                        />

                        <OrbitControls />

                        {/*camera*/}
                        <PerspectiveCamera
                            makeDefault={true}
                            far={1000}
                            near={0.1}
                            fov={20.968}
                            position={[7.569, 1.329, -1.365]}
                            rotation={[-2.736, 1.419, 2.714]}
                        />

                        {/*lights*/}

                        <pointLight
                            intensity={1}
                            decay={2}
                            position={[-1.277, 0.618, -1.638]}
                            rotation={[-Math.PI / 2, 0, 0]}
                            castShadow = {true}
                        />

                        {/*<directionalLight
                            intensity={5}
                            position={[0, 2.93, 0]}
                            castShadow={true}
                        />*/}

                        <DirectionalLightWithHelper />

                        {/*<directionalLight
                            intensity={5}
                            position={[2.37, 2.62, 1.68]}
                            rotation={[-71.77, -0.08, -35.33]}
                            castShadow={true}
                        />*/}

                        <DirectionalLightAndHelper />

                        <Wormpile />

                    </Canvas>

Hi,

if the scene is static, the best way to match Blender is to bake your textures in Blender and load them into threejs.

Otherwise you can only get close to what you see in Blender by playing with:

  • Lighting
  • ToneMapping
  • colorSpace
  • postprocessing

Note that Blender defaults to AgX tone mapping, and R3F defaults to ACES Filmic but can be configured to AgX. I suspect that’s one part of it, and most of the remainder is lighting.

How would I go about changing it to AgX out of curiosity?

In three.js:

renderer.toneMapping = THREE.AgXToneMapping;

In R3F I think it’s something like <Canvas gl={{ toneMapping: THREE.AgXToneMapping }}> ... but see discussion in Confusing tone mapping configuration · Issue #1547 · pmndrs/react-three-fiber · GitHub if that doesn’t work.

I was able to get that to work, however I’m still getting colors that are washed out even when adjusting my lighting setup.

If any of these materials are metallic you may need more environment lighting than the 0.2 intensity you’ve enabled, or (perhaps preferably) to disable the material’s metalness. But an exact match from two different engines is not guaranteed, there is no shortcut I’m aware of except to configure lighting and/or color grading (in three.js) until you have a result you’re happy with.