question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Should lightmaps be effected by physicallyCorrectLights? (they are currently)

See original GitHub issue

In a scene with no lights, and no environment map I would expect an object with a lightmap to look quite close to the raytraced result in Blender when using a lightmap generated from that scene in Blender. (assuming you select a similar tone mapping and output encoding in both, and used an HDR lightmap).

With physicallyCorrectLights disabled, the result is quite close: image left Three (Mozilla Hubs) | right Blender

with it enabled the object is a good deal darker than expected: image

Digging into the code this difference makes sense as when physicallyCorrectLights is disabled the lightmap value is multiplied by PI. https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js#L11

I admittedly don’t fully understand all the math going on here, but from what I understand the multiplication by PI here when physicallyCorrectLights is disabled is to cancel out the multiplication by 1/PI in the BRDF_Diffuse_Lambert, but does it actually make sense for 1/PI to be applied to lightmap data? Based on what I am seeing I am starting to think this is already “factored in” when raytracing the lightmap… I also noticed that with a MeshBasicMaterial the result is the same “correct” brightness whether or not physicallyCorrectLights is enabled. I know it is an “unlit” material, but I would expect purely pre-computed indirect diffuse light to behave the same in either case with no other lighting in the scene.

There are a whole lot of factors at play in computing the final output color both in three and in Blender, so it’s possible there is something fundamentally incorrect about my assumption that things should even be able to look the same. But the fact that things look almost entirely correct when simply multiplying the lightmap values by PI (to cancel out the 1/PI) makes me think otherwise.

From reading through a lot of the discussions on the different iterations of the physically based lighting (and adding, removing, and adding again of the 1/PI term in the BRDFs) I kept running into @WestLangley and @bhouston, so maybe one of you two may be able to shed some light (pun intended) on the expected behavior here? I would also particularly like to understand what @WestLangley meant by // factor of PI should not be present; included here to prevent breakage which was added as a comment many years ago and then subsequently propagated to a few other places, and eventually ended up now in the #ifndef PHYSICALLY_CORRECT_LIGHTS I referenced above.

Its a bit tricky to provide a working example of this exact model since its using a GLTF with some custom extensions. I can put together a simplified example if it would be helpful but I don’t think the exact model or lightmap matters very much, its really a question of what precisely is the expected data in lightmaps and if that data should be effected by the physicallyCorrectLights setting.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:24 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
WestLangleycommented, Feb 6, 2022

@cptSwing

Well, this is unfortunate…

For Physical, Standard, Phong, and Lambert – materials that “respond to light” – light maps in three.js only brighten the scene.

For MeshBasicMaterial, which does not respond to light, support for light maps was added long ago and retained for backwards-compatibility. In that case, if the product of the light map value and the light map intensity is less than 1, it will render darker than the equivalent scene having no light map at all.

Granted, this is confusing, but it was a way to shoehorn light map support into MeshBasicMaterial.

0reactions
cptSwingcommented, Feb 6, 2022

In three.js, lightmaps are additive to total incoming, indirect light.

Sorry for butting in here, but as I’ve seen this mentioned a couple of times all over the web: This does not refer to the actual shader math when adding a lightmap texture’s effect to the render, does it? From my experimenting, a lightmap in threejs seems to be multiplied with the final result (ie darkening the underlying albedo), not adding to it, yes?

Read more comments on GitHub >

github_iconTop Results From Across the Web

WebGLRenderer#physicallyCorrectLights – three.js docs
The maximum number of uniforms that can be used in a vertex shader. - precision: The shader precision currently being used by the...
Read more >
Optimize light maps - Arm Developer
Light maps vary in size depending on the settings they are baked with. We must minimize memory usage on mobile platforms, so lightmap...
Read more >
Three.js Shadows
So, moving on to shadow maps, there are 3 lights which can cast shadows. The DirectionalLight , the PointLight , and the SpotLight...
Read more >
Lightmap Parameters - Unity - Manual
This allows you to create presets optimised for different types of objects or for ... It is applied to all baked lightmaps, so...
Read more >
Physically Based Rendering and Lighting | Discover three.js
physicallyCorrectLights = true; return renderer; } ... There are a few more parameters we need to tweak to get colors and lighting working...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found