-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
EXT_lights_environment #1850
Changes from 23 commits
d2d2e2f
36c5432
03276f9
8701f10
0aa4f66
dfda721
2f0a7bf
9b52d13
a87419f
f4f6eba
e308ef5
6ebfa3c
d0196ac
90c91ea
36ab973
5b6a698
ed16458
0c9896b
5d7d535
285d945
1ac92d0
821b165
a2f177c
5cd666e
969ec0b
785ce36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
|
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I agree with @donmccurdy |
||
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" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
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" | ||
] | ||
} |
There was a problem hiding this comment.
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.