Skip to content
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

EXT_lights_environment #1850

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d2d2e2f
add transmission specs
jim-ec Mar 25, 2020
36c5432
add thickness spec
jim-ec Mar 25, 2020
03276f9
add absorption spec
jim-ec Mar 26, 2020
8701f10
remove optional dependency on thickness
jim-ec Mar 26, 2020
0aa4f66
fix transmission spec
jim-ec Mar 30, 2020
dfda721
Update README.md
Apr 1, 2020
2f0a7bf
Update README.md
Apr 1, 2020
9b52d13
refactor to refraction extension
jim-ec Apr 1, 2020
a87419f
update thickness extension
jim-ec Apr 1, 2020
f4f6eba
move thickness extension to its own branch
jim-ec Apr 1, 2020
e308ef5
initial draft
jim-ec Apr 1, 2020
6ebfa3c
improve thickness extension
jim-ec Apr 1, 2020
d0196ac
Merge pull request #3 from KhronosGroup/master
UX3D-nopper Apr 28, 2020
90c91ea
Merge branch 'master' into extensions/KHR_materials_thickness
jim-ec Apr 28, 2020
36ab973
Merge branch 'master' into extensions/KHR_materials_transmission
jim-ec Apr 28, 2020
5b6a698
remove refraction related files as already present in KHR_materials_r…
jim-ec Apr 28, 2020
ed16458
remove absorption related files as already present in KHR_materials_a…
jim-ec Apr 28, 2020
0c9896b
Merge pull request #4 from ux3d/extensions/KHR_materials_transmission
Apr 28, 2020
5d7d535
Minor fixes.
UX3D-nopper Apr 28, 2020
285d945
Merge pull request #7 from ux3d/extensions/KHR_materials_thickness
UX3D-nopper Apr 28, 2020
1ac92d0
Merge pull request #8 from KhronosGroup/master
UX3D-nopper Aug 13, 2020
821b165
Initial draft for EXT_lights_environment
UX3D-nopper Aug 13, 2020
a2f177c
Removed thickness.
UX3D-nopper Aug 13, 2020
5cd666e
Fixed some typos. Clarified the coordinate system.
UX3D-nopper Aug 14, 2020
969ec0b
Added physical units.
UX3D-nopper Aug 14, 2020
785ce36
Merge pull request #9 from KhronosGroup/master
UX3D-nopper Oct 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions extensions/2.0/Vendor/EXT_lights_environment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# EXT_lights_environment

## Contributors

* `TODO: Add contributors`

## Status

Draft

## Dependencies

Written against the glTF 2.0 spec.

## Overview

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add purpose of extension, along the lines of:

The purpose of this extension is to allow embedding of environment map data (IBL) in a glTF asset.
An environment map will supply diffuse and specular light contribution to the scene, as well as information needed for reflections.

This can be used on it's own - ie a glTF asset with only environment map data - for a usecase where the IBL needs to be distributed.
It can also be used together with model data, for usecases where a model shall be displayed in a defined environment.

This extension provides the ability to define an environment light (also known as [sky light](https://docs.unrealengine.com/en-US/Engine/Rendering/LightingAndShadows/LightTypes/SkyLight/index.html)) in a glTF scene. In general, this environment is used for image based lighting in rasterizers and pathtracers.

To environment light is defined by a panorama image (also know as [equirectangular image](https://docs.blender.org/manual/en/latest/render/lights/world.html)). For encoding the panorama image and for supporting [High-dynamic-range rendering](https://en.wikipedia.org/wiki/High-dynamic-range_rendering), the widely used [RGBE image format](https://en.wikipedia.org/wiki/RGBE_image_format) is used as a `.hdr` file:
The panorama image and `.hdr` file format is supported in paint tools like Gimp or Photoshop, 3D modelling tools like Blender or 3ds Max, Game Engines like Unity or Unreal Engine and Web Engines like Babylon.js or three.js.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would consider panorama / equirectangular IBL easy to create, but inefficient to load, which is the opposite of what we usually aim for with glTF. In Babylon.js and three.js the IBL would have to be converted to a cubemap at load time.

Other than wide support in paint tools, are there other reasons to prefer equirectangular? All of these engines should support cubemaps, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do need a) HDR and b) a common supported format. In general, KTX2 would be a perfect fit, but unfortunatelly it does not support HDR compression at this point of time.
I disagree, that .hdr is inefficient to load. It is easy to load (some lines of code and straight forward), nicely encoded and one can choose the final precission and resolution easily (e.g. half float vs. float) for the final cube map. With this preprocessing argument, we could not allow JPEG and/or Basisu compression, as there is also quite something happening on the CPU before the final image is uploaded to the GPU. It is in most cases just hidden in some library.
It is not just about paint tools. Any DCC (2D or 3D) tool can handle .hdr panorama files for IBL. Is there any out there, which does not support .hdr?
I understand your point of view, but some groups want to have this extension and/or feature set. That's the reason for EXT_ and we should not bring all on the same page, as it will not become a KHR_ extension.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not critiquing the choice of .hdr here, but the choice of panorama instead of cubemap. Couldn't you use 6 .hdr images to form a cubemap, or is that just unusual?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is unusual. E.g. in Blender you just define the panorma .hdr file:
image
So, for Blender, an easy import and export would be possible.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would consider panorama / equirectangular IBL easy to create, but inefficient to load, which is the opposite of what we usually aim for with glTF.

I agree with @donmccurdy
If we choose a cubemap format we will reduce the load time process - I think this is something we should aim for!

In general, this format is already used to define environment lights in todays 3D engines.

How to pre-filter and/or sample the panorma image is implicitly definded by the [materials BRDF](https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#appendix-b-brdf-implementation).

### Why no pre-filtering (also known as pre-sampling)?

* Pathtracers do not require this extra data
* Rasterizers can decide between Spherical Harmonics vs. pre-filtered diffuse lighting
* Rasterizers can decide ...
* Numbers of pre-filtering samples
* Pre-filtering algorithm and optimizations
* Direct panorama image sampling vs. cube map sampling
* Cube map resolution
* Cube map mip-map optimization
* Pre-filtering generates more data to be transfered
* Each BRDF potentially needs a new look up table and a mip-mapped cube map
* Graphics API independent
* DirectX vs. OpenGL

## Defining an environment light

The `EXT_lights_environment` extension requires to extend the following glTF schemas.

### Defining the panorama image

```json
"images": [
{
"uri": "any_other_image.png"
},
{
"uri": "dodge2.hdr"
}
]
```

This means, that the `mimeType` inside [image.schema.json](https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/schema/image.schema.json) has to support `image/vnd.radiance`.

### Defining the environment light

One or more environment lights cane be defined inside [glTF.schema.json](https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/schema/glTF.schema.json)

```json
"extensions": {
"EXT_lights_environment": {
"environments": [
{
"source": 0,
"intensity": 1.0,
"frontside": "+X"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary that we allow this to be configured, rather than normatively stating a front facing direction as we do with cameras?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is, that different DCC tools do have a different front face. Some do have +Z, some do have +X. So, yes this is required to compensate this.

Copy link
Contributor

@donmccurdy donmccurdy Aug 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different engines will have different conventions too — we are placing the burden of conversion on them, rather than the DCC tools? This is much easier with cubemaps, perhaps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E.g. the above screenshot from Blender does have +X as the front face. Because of Blender's coordinate system.
If you set up the same scene in 3ds max - as there +Z is the front face, the scene looks different. To compensate, during export to glTF, the front face is defined.
If an engine is following the glTF specification, the coordinate system is well defined and I do not see any burden. It is the opposite, now the orientation is well defined.
Also, some 3D engines will not use cube maps. E.g. Blender Cycles can be executed on the CPU and there is no need to convert to a cube map. And probably any CPU based path/raytracer will directly sample from the panorma image.

}
]
}
}
```

Both the data inside the `.hdr` file and the intensity are linear values.

At this point of time, there is no convention, where the front side of a panorma image **and** which axis direction the front side is. Because of this, the following is defined:

The directions in UV coordinates (0.0 is left (for u) and bottom (for v) of the image:
`+X direction (0.5 , 0.5)`
`-X direction (1.0 , 0.5) (and (0.0 , 0.5) for sampling)`
`+Y direction (0.5 , 1.0)`
`-Y direction (0.5 , 0.0)`
`+Z direction (0.75, 0.5)`
`-Z direction (0.25, 0.5)`

This implies, that by default, the `+X` direction is the front side. By defining a frontside with e.g. `+Z`, the environment has to be rotated by 90 degrees. This can be solved in the following way:

* Adapt sampling by using offsets into the panorama image
* Swap X and Z cube map sides accordingly plus rotate Y cube map sides
* Rotate the sampling vector during runtime

`TODO: Define units: candela (lm/sr) vs. lux (lm/m2)`

### Using the environment light

The environment light is utilized by a scene.

```json
"scenes": [
{
"nodes": [
0
],
"extensions": {
"EXT_lights_environment": {
"environment": 0
}
}
}
]
```

## glTF Schema Updates

- [glTF.EXT_lights_environment.schema.json](schema/glTF.EXT_lights_environment.schema.json)
- [environment.schema.json](schema/environment.schema.json)
- [scene.EXT_lights_environment.schema.json](schema/scene.EXT_lights_environment.schema.json)

## Known Implementations

* `TODO: Add implementations`

## Reference

* `TODO: Add references`
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "EXT_lights_environment glTF extension",
"type": "object",
"allOf": [ { "$ref": "glTFChildOfRootProperty.schema.json" } ],
"properties": {
"source": {
"allOf": [ { "$ref": "glTFid.schema.json" } ],
"description": "The index of the image used by this environment."
},
"intensity": {
"type": "number",
"description": "Intensity of the light source. TODO: Define units.",
"default": 1.0,
"minimum": 0
},
"frontside": {
"type": "string",
"description": "Specifies the front side. +Y and -Y are excluded by purpose.",
"default": "+X",
"anyOf": [
{
"enum": [ "+X" ]
},
{
"enum": [ "-X" ]
},
{
"enum": [ "+Z" ]
},
{
"enum": [ "-Z" ]
},
{
"type": "string"
}
]
},
"name": { },
"extensions": { },
"extras": { }
},
"required": [
"source"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "EXT_lights_environment glTF extension",
"type": "object",
"allOf": [ { "$ref": "glTFProperty.schema.json" } ],
"properties": {
"environments": {
"type": "array",
"items": {
"type": "object",
"$ref": "environment.schema.json"
},
"minItems": 1
},
"extensions": {},
"extras": {}
},
"required": [
"environments"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "EXT_lights_environment glTF extension",
"type": "object",
"allOf": [ { "$ref": "glTFProperty.schema.json" } ],
"properties": {
"environment": {
"allOf": [
{
"$ref": "glTFid.schema.json"
}
],
"description": "The id of the environment used for lighting referenced by this scene."
},
"extensions": {},
"extras": {}
},
"required":[
"environment"
]
}