Why are intensities of lights in GLTF Blender export not the same in Threejs?

Exporting lights with ‘punctional lights’ to GLTF/GLB and import the glb in ThreeJs the lights are waaaay overdriven so the whole scene is basically just white because the lights don’t have the same intensities.

I don’t understand this. I would expect light intensities to be normalized in sense of every tool using the same kind of values when using gltf.

Why isn’t the export of a Blender scene, imported in ThreeJs, the same as seen in Blender? And how to have this the same without the need to manually tweak all lights every time after an import?

Thanks in advance!

If you haven’t yet, enable renderer.physicallyCorrectLights = true. Without that there’s no way for three.js to match Blender. Next you may need to manually apply the conversions described in Intensity units when exporting point lights · Issue #564 · KhronosGroup/glTF-Blender-IO · GitHub, since those haven’t been merged into Blender yet.

1 Like

Thanks @donmccurdy ! I didn’t know about that setting, so have switched it on now. That helps a lot!
Does this mean the GLTF/GLB fileformats don’t have standardised lighting values?

After setting it to this value it still looks way off (compared to both Eevee and Cycles renderer in Blender), but that might be the other thing you’re talking about; the difference in understandings between power consumption (W) vs lighting output (W) as I understand? It might also have something to do with the fact that I’m using refractions and transparencies which got perhaps calculated differently (or isn’t supported?) in threejs.

[edit] Unfortunately when using the function as mentioned in the issue on github the lights still go in overdrive. When importing the GLTF, setting the renderer to the setting you mentioned and converting the intensity with the given function, the lights waaaaay too bright… so either this function isn’t right, or there is another thing wrong in the Blender exporter and/or Threejs Gltf importer. Or am I missing something here?

function blenderWattsToLumens(watt) {
    return (683 * watt) / (4 * Math.PI);
}

// ...
this.lamp.intensity = blenderWattsToLumens(this.lamp.intensity);
// ...

glTF does have clear standardized, physically-based units for lighting values. three.js hasn’t always had that (hence the renderer option that needs to be enabled here). Blender’s lighting units have not always been documented either, but fortunately they are these days. So any time a conversion involves “unknown units” on either end, no correct conversion is possible.

I’m afraid I don’t know exactly what conversion is needed in three.js to get the same results though. Tweaking in Gestaltor might be easier, I think it supports editing glTF lights losslessly.

You can see the current Blender export code here: glTF-Blender-IO/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py at bb488b245f0c83fdd566b43c2c762d469c044326 · KhronosGroup/glTF-Blender-IO · GitHub … clearly it’s doing that / (4 * Math.PI) step, but there are a number of edge cases (Cycles vs. Eevee, quadratic falloff) that I don’t fully understand.

Thanks. Thank god both GLTF, Blender and ThreeJs now have their systems defined. Now let’s hope they soon match up. There will probably always be something a little off, but right now it’s a complete different lighting setup, so having solved that would be a real time saver! :grinning:

To give an impression; this is the difference between Blender and ThreeJs here now, so it’s pretty off and some parts really blow/glow because it’s so bright it cannot handle it. I’m starting to wonder though if gamma correction could also play a little role here. It wouldn’t matter that mutch though.

I’m pretty impressed by how well Eevee performs in this case though, in comparisson to Cycles; it’s hard to see any difference!

In the example below all Threejs-versions are coming from just the GLTF import. No additional lighting was added and the intensities aren’t changed by code, except for the onces ‘with function’ (meaning the correction function as mentioned in the github issue thread of the Blender exporter).

There is a huge difference in both contrast and lighting intensities and it’s pretty much a complete different environment after import. Also when using the function in javascript it’s always wrong, so it looks like either the function is already implemented in the exporter (as I believe you think too) or the function is IMO not right or I am still missing something (else). Either way, I can’t get it here to be even close to the result in blender whatever I try.

It’s not a production project, so leave it for now. But hopefully one day the Gods of contrast and lighting have agreed :wink:

Thanks again for your quick responses and helpful comments and keep up the great work. It’s definitely getting way better every time. You guys work incredibly hard! I was also pleasantly surprised to notice no difference anymore in working with axis between blender and threejs! That’s great! :slight_smile:

Have a nice day.