Are there any guides for HDR setups for novices?

so i appriciate it maybe an indepth topic, however im struggling to get to grips with what is required to use HDR files for lighting, ive gone throught all the examples (specifically this one) I can find, but for someone new to it there seems to be a distinct lack of documentation(or at least im missing it).

I can see the use of a HDRCubeTextureLoader, but what are the pmremGenerator and pmremCubeUVPacker for and really do I even need to care?

It also appears you have to do this…

renderer.gammaInput = true
renderer.gammaOutput = true;

but that has a //??? next to it in the example!

for a layman like myself, could you break it into two basic steps…

Step 1 - Create the Cube texture loader tells the renderer to use th hdr for the lighting.

	new THREE.CubeTextureLoader().load( rgbmUrls, function ( rgbmCubeMap ) {
					rgbmCubeMap.encoding = THREE.RGBM16Encoding;
					var pmremGenerator = new THREE.PMREMGenerator( rgbmCubeMap );
					pmremGenerator.update( renderer );
					var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
					pmremCubeUVPacker.update( renderer );
					rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
				} );

Step 2- make sure the envMap of the material is set to use hdrCubeRenderTarget.texture


The question marks refer only to the gammaInput statement. This line is actually not necessary in this example since Texture.encoding determines how the texture is encoded and how the decoding should happen in the shader.

Basically yes, since these entities allow the correct usage of environment maps in context of physically based rendering. MeshStandardMaterial is based on a metalness/roughness workflow. In order to implement the concept of roughness correctly with environment maps, you need to do some preparation. PMREMGenerator creates multiple versions of the map based on different roughness values and also creates the corresponding mipmaps. PMREMCubeUVPacker just takes all these texture data and transforms them into a single texture for rendering (you can see this texture for debugging purposes on the floor of the example). While rendering, the fragment shader picks an appropriate version of the environment map based on the respective roughness value of the material.

Whenever you use MeshStandardMaterial, you should also use prefiltered mipmaped radiance environment maps.

More information about this topic right here:


thank you very much for the reply, I’ve given the link a scan, and it certainly seems interesting/useful but will give it a full read when time permits.

Would you by chance be able to comment on whether my very basic break down of the steps is correct and sufficient to light a scene?

No, the creation of an instance of CubeTextureLoader does not affect the renderer in any way.

Im pretty new to the whole topic, just wondering: The prefiltered mipmaped radiance environment maps are generated on runtime - is it also possible to load somehow maps which were computed and saved before?
Something like BabylonJS is doing with IBL Baker?
I mean, generating them on runtime is actually really nice and makes the everything dynamic. But what about the performance impact? Is this better than loading a precomputed map?

Another question about the hdr env example

I had some trouble to set the hdrCubeRenderTarget.texture as the envMap after the pmremGenerator and pmremCubeUVPacker.
When loading a CubeMapTexture, I can easily assign the CubeTextureLoader to the envMap of the material.
In the hdr example, this is not possible for me. In the example, this is done in the render() function. Is this a need? It only works for me in the render() function like this:

var newEnvMap = standardMaterial.envMap;
			newEnvMap = hdrCubeRenderTarget ? hdrCubeRenderTarget.texture : null;
			standardMaterial.envMap = newEnvMap;
			standardMaterial.needsUpdate = true;

Hey, @Mugen87, do you know if there’s documentation in the works for THREE.PMREMGenerator? I see the TypeScript declaration files have been added, but I think the description you wrote above would be very helpful in the docs section :wink:

1 Like

Unfortunately, my text is not 100% correct anymore since three.js has a new PMREMGenerator implementation since R112. For example, PMREMCubeUVPacker does not exist anymore.

The developer of the new PMREMGenerator has written some comments inside the class which could be used for a documentation page. Maybe it’s best to create a feature request at github.

1 Like