Cannot get HDRI Lighting to work with RGBELoader

Hello, threejs novice here. Title: I am having trouble putting the HDRI as lighting for my model using react-three-fiber. My code is as following:

import React, {Suspense, useEffect, useRef} from 'react';
import {Canvas, useThree} from 'react-three-fiber';
import {PMREMGenerator} from "three/src/extras/PMREMGenerator";
import {RGBELoader} from "three/examples/jsm/loaders/RGBELoader";
import {UnsignedByteType} from "three";
import hdr from "path_to_.hdr";

const Model = ({ gltf }) => {
  const groupRef = useRef();

  const { gl, scene } = useThree();
  const pmremGenerator = new PMREMGenerator(gl);
  const loader = new RGBELoader();
  loader.setDataType(UnsignedByteType);
  pmremGenerator.compileEquirectangularShader();

  useEffect(() => {
    loader.load(
        hdr,
        texture => {
          const textureData = pmremGenerator.fromEquirectangular(texture).texture;
          scene.environment = textureData;
          texture.dispose();
          pmremGenerator.dispose();
        }
    )
  }, [scene, loader, pmremGenerator]);

  return (
      <group ref={groupRef}>
        <primitive object={gltf.scene} dispose={null} />
      </group>
  )
};

const ThreeDeeModel = (props) => {

  return (
      <Canvas>
        <Suspense fallback={<mesh/>}>
          <Model {...props}/>
        </Suspense>
      </Canvas>
  )
};

export default (ThreeDeeModel);

I have been following the similar topics for a while but couldn’t figure where it go wrong. For me now the only thing I’m sure is that:

  1. I can load the textureData correctly
  2. My model appears on the browser (covered in black)

Appreciate every help, thanks a lot for reading.

Can you please share the HDR file in this thread?

Hi Mugen, sure here’s the file:

I managed to set textureData to scene.background, but setting it to scene.environment doesn’t yield the effect. I’ve also tried with another .hdr file, also nothing happened.
The original hdr: file.hdr.zip (1.9 MB)
Another hdr file that I tried with: royal_esplanade_1k.hdr (1.6 MB)
My package.json if it helps:

    "react-three-fiber": "^4.2.0",
    "three": "^0.112.1",

Turned out that it is because my model isn’t exported correctly and therefore the environment lighting does not get reflected upon it. When I use another model, it works perfectly with both HDRI. I will update my answer soon for more details.

1 Like

here’s a working example: https://codesandbox.io/s/r3f-ibl-envmap-normalmap-50y03?file=/src/components/Environment.js

about the code you posted, i would recommend not putting side-effects into the render function. the generator, the rgbeloader, shader compilation, all this stuff will be re-instanciated and execute on every render. it should live within the useEffect.

since the environment is a global thing i would also make it a separate component instead of having it tied to some model. this allows you to effortlessly put it into the scene, or not.

1 Like

Thank you for the code example, I am able to get it work now!
One question though, it is said in the documentation of react-three-fiber that userLoader is experimental. Is it safe enough to use this hook now in production code?

yes, its fine. i think that warning is just a left over.

1 Like