Skip to content

Commit

Permalink
Switches lm/m^2 to W/m^2 and lm/r^2 to W/r^2 in KHR_lights_punctual.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
will-ca committed Oct 12, 2022
1 parent 2a9996a commit 4de2d01
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions extensions/2.0/Khronos/KHR_lights_punctual/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ All light types share the common set of properties listed below.
|:-----------------------|:------------------------------------------| :--------------------------|
| `name` | Name of the light. | No, Default: `""` |
| `color` | RGB value for light's color in linear space. | No, Default: `[1.0, 1.0, 1.0]` |
| `intensity` | Brightness of light in. The units that this is defined in depend on the type of light. `point` and `spot` lights use luminous intensity in candela (lm/sr) while `directional` lights use illuminance in lux (lm/m<sup>2</sup>) | No, Default: `1.0` |
| `intensity` | Brightness of light in. The units that this is defined in depend on the type of light. `point` and `spot` lights use luminous intensity in W/sr while `directional` lights use illuminance in W/m<sup>2</sup> | No, Default: `1.0` |
| `type` | Declares the type of the light. | :white_check_mark: Yes |
| `range` | Hint defining a distance cutoff at which the light's intensity may be considered to have reached zero. Supported only for `point` and `spot` lights. Must be > 0. When undefined, range is assumed to be infinite. | No |

Expand All @@ -105,15 +105,15 @@ A recommended implementation for this attenuation with a cutoff range is as foll

### Directional

Directional lights are light sources that act as though they are infinitely far away and emit light in the direction of the local -z axis. This light type inherits the orientation of the node that it belongs to; position and scale are ignored except for their effect on the inherited node orientation. Because it is at an infinite distance, the light is not attenuated. Its intensity is defined in lumens per metre squared, or lux (lm/m<sup>2</sup>).
Directional lights are light sources that act as though they are infinitely far away and emit light in the direction of the local -z axis. This light type inherits the orientation of the node that it belongs to; position and scale are ignored except for their effect on the inherited node orientation. Because it is at an infinite distance, the light is not attenuated. Its intensity is defined in watts per square metre (W/m<sup>2</sup>).

### Point

Point lights emit light in all directions from their position in space; rotation and scale are ignored except for their effect on the inherited node position. The brightness of the light attenuates in a physically correct manner as distance increases from the light's position (i.e. brightness goes like the inverse square of the distance). Point light intensity is defined in candela, which is lumens per square radian (lm/sr).
Point lights emit light in all directions from their position in space; rotation and scale are ignored except for their effect on the inherited node position. The brightness of the light attenuates in a physically correct manner as distance increases from the light's position (i.e. brightness goes like the inverse square of the distance). Point light intensity is defined in watts per square radian (W/sr).

### Spot

Spot lights emit light in a cone in the direction of the local -z axis. The angle and falloff of the cone is defined using two numbers, the `innerConeAngle` and `outerConeAngle`. As with point lights, the brightness also attenuates in a physically correct manner as distance increases from the light's position (i.e. brightness goes like the inverse square of the distance). Spot light intensity refers to the brightness inside the `innerConeAngle` (and at the location of the light) and is defined in candela, which is lumens per square radian (lm/sr). Engines that don't support two angles for spotlights should use `outerConeAngle` as the spotlight angle (leaving `innerConeAngle` to implicitly be `0`).
Spot lights emit light in a cone in the direction of the local -z axis. The angle and falloff of the cone is defined using two numbers, the `innerConeAngle` and `outerConeAngle`. As with point lights, the brightness also attenuates in a physically correct manner as distance increases from the light's position (i.e. brightness goes like the inverse square of the distance). Spot light intensity refers to the brightness inside the `innerConeAngle` (and at the location of the light) and is defined in watts per square radian (W/sr). Engines that don't support two angles for spotlights should use `outerConeAngle` as the spotlight angle (leaving `innerConeAngle` to implicitly be `0`).

A spot light's position and orientation are inherited from its node transform. Inherited scale does not affect cone shape, and is ignored except for its effect on position and orientation.

Expand Down

0 comments on commit 4de2d01

Please sign in to comment.