-
Notifications
You must be signed in to change notification settings - Fork 319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Intensity units when exporting point lights #564
Comments
As far as I understand Power field in light settings denotes wattage emitted by light source, not consumed, otherwise everything may be even more difficult. I've done some back-of-the-envolope computation, so here it goes:
Computations are a bit subtler for spot lights: I am not totally sure we should have this very watt -> lumen conversion, but at least it gets the physical units correct, the rest I guess should be handled by gltf model consumer. |
Any chance to get this tagged as a bug? The units for the light intensity seems to be wrong. According to the glTF specs:
the exported units should be as specified in the glTF specs. |
Tagged as bug |
…ronos Blender exporter See KhronosGroup/glTF-Blender-IO#564
Not for nothing, but it took me about three hours of searching to find this thread so that I could find out how to convert watts to lumens because I'm primarily a designer with a limited math background. I'm currently trying to import a gltf into three.js that was exported from blender by another designer. On one hand, thank you so much for posting those formulas. On the other, is there any idea when the fix for this might be implemented? Thank you! |
Raises hand ✋ Add one more developer to the list of "People who sunk multiple hours into figuring out the issue in their code only to learn it was a problem in Blender's export." It would be really great if this could be fixed! |
How about we start by writing a function to do this conversion from Blender watts to the correct value for glTF for point lights, area lights and sun lights, then validate the conversion is correct, and if it is then it should be fairly trivial to just throw it into the code.
Based on that, it seems like the function would be roughly: import math
# Convert Blender Point light watts units to Candela for glTF spec
def blender_watts_to_lumens(watt):
return (683 * watt) / ( 4 * math.pi) I wrote a little test to output results and this is what I got from that function: import math
def blender_watts_to_lumens(watt):
return (683 * watt) / ( 4 * math.pi )
values = [0.1, 0.2, 0.5, 1.0, 2, 5, 10, 20, 50, 100]
for i in values:
print(str(i) + " Blender Watts = " + str(blender_watts_to_lumens(i)))
@4DA Does that look correct in your opinion? |
You can find the current export code here: glTF-Blender-IO/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py Lines 64 to 84 in bb488b2
There are some edge cases around Cycles vs. Eevee and falloff that would probably require some manual testing here, I'm not sure this is quite as simple as just plugging in a watts-to-lumens conversion formula unfortunately. |
Forgive me if this has already been discussed here or elsewhere, but it's worth noting Blender's manual that explains how the power of lights are calculated. It doesn't seem to be particularly standard with other software since it specifies:
It goes on to list a couple handy conversion charts. |
@mindinsomnia Thanks for jumping ahead and providing the conversion functions. Is it a good idea to pick the luminous efficacy of 555nm wavelength light (essentially a green laser) as conversion reference? The luminous efficacy depends on the type of light (see examples). I'd argue most Blender users try to replicate the sun or consumer lights (LED, halogen or incandescent lights) whose luminous efficacy is a lot lower. I'm not an expert, but it seems the most physically accurate way would be to defer the luminous efficacy off of the light's color, right? (No idea how to calculate that though; maybe blend 3 defined values based on RGB factors). edit: Furthermore the luminous efficacy differs between day and night, but we need to draw the line somewhere and since I'm not aware of renderers that replicate human night vision, I'd say ignore that. |
Also: For directional lights we need to convert W/m² to lux (i.e. lumen/m²), so no need to divide by the area of a sphere, right? |
…ect `GLTF`/`KHR_punctual_lights` units.
Lumens are *not* actually a physical unit. They are a perceptual unit, and this leads to all sorts of issues. - Lumens makes RGB difficult to process and reason about, because the same physical power of blue and red produces fewer perceptual lumens than does green. - Lumens produce very big numbers, in the hundreds for a household lightbulb. This may be petty, but is a compatibility issue when viewers and their importers expect numbers around the 0.0-10.0 range. - Lumens (perceptual luminance) are not actually convertible from watts (physical radiance), which are what authoring programs and rendering pipelines work in. This has two consequences: - In logistical terms, it makes implementation of exporters and importers tricky. E.G. KhronosGroup/glTF-Blender-IO#564 was held up for over three years (and is still open) because nobody figured out the conversion function. Other projects, including Three.JS, and the official Khronos Group reference GLTF viewer, seem to also have just ignored the units part of the spec. - In mathematical terms, it means that there is not actually a canonical way to convert from physical watts in authoring and display programs to perceptual lumens for GLTF, or vice versa. They measure different things, so at best you can have a wild guess based on situational equivalence given a bunch of arbitrary assumptions. E.G. 594lm, 609lm, 572lm, and 0.2lm are all equally valid conversions for 1W, depending on the exact wavelength and luminous efficiency function you're using. **This means that as written, the spec's behaviour is actually undefined relative to physically based workflows;** It is actually not possible to build a physically accurate pipeline using lumens as specified in `KHR_lights_punctual`, because the unit itself does not represent a physical quantity. Due to low previous adoption of the lumens unit from the spec (possibly partly due to the aforementioned issues), the disruption from this should hopefully be minimial. I have not found any examples that actually implement or use the lumens units from the spec, including both the Three.JS and official Khronos Group reference GLTF viewers. In any case applications are free to maintain their present, already non-conformant behaviour, and adopt the new behaviour if they wish. See KhronosGroupGH-2213.
Further discussion in KhronosGroup/glTF repository — The conversion does not seem to be correct with just a watts-to-lux formula, unfortunately. |
FYI – @will-ca has opened a PR with a proposed fix in #1760, testing would be welcome! Important to note that when exporting with physically-based units (per the glTF spec) you will almost certainly need to adjust the exposure in your viewer. The PR does include a second "compatibility" mode that exports a unitless light intensity value. That isn't spec-compliant or physically-based, but seems to be a common workflow and may work out of the box in viewers without exposure controls. |
Just downloaded blender the other day and this still seems to be an issue. Blender shipped with 4.0.44 Not sure why this is closed? |
@DrewImm the unit conversions are implemented, with a few different options in the exporter settings. Note that getting your lighting to appear identical in an application outside Blender remains difficult - the application's exposure and tone mapping come into play, for one thing, and an exposure of "1" is not necessarily the same in one application as in another. If you feel there's a bug in the Blender exporter, though, please feel free to file an issue – we'd need a |
Thanks @donmccurdy!! I found the Lighting dropdown and tried Unitless, which seems way closer to what I'd expect. Is there documentation on the options? |
Not more than is in the tooltips, at the moment. Short summary:
To get a perfect reproduction (or as close as you can get, given inherent differences in applications...) I think you would need to also transfer the exposure and tone mapping to the target application, and I don't have a simple answer on how to do that. |
Blender uses watts as units for power of point light sources.
On the other hand, KHR_punctual_lights use lm/sr as light intensity units.
I can see that values from point light power settings are directly written to gltf file without watts -> lumen -> candela conversion.
The text was updated successfully, but these errors were encountered: