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

KHR_materials_pbrSpecularGlossiness extension #842

Merged
merged 4 commits into from
Apr 11, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
214 changes: 214 additions & 0 deletions extensions/Khronos/KHR_materials_pbrSpecularGlossiness/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
# KHR\_materials\_pbrSpecularGlossiness

## Contributors

* Max Limper, Fraunhofer IGD, [@mlimper_cg](https://twitter.com/mlimper_cg)
* Timo Sturm, Fraunhofer IGD, [@\_tsturm\_](https://twitter.com/\_tsturm\_)
* Miguel Sousa, Fraunhofer IGD, [@mfportela](https://twitter.com/mfportela)
* Maik Thöner, Fraunhofer IGD, [@mthoener](https://twitter.com/mthoener)
* Eric Haines, Autodesk, [@pointinpolygon](https://twitter.com/pointinpolygon)
* Cedric Pinson, Sketchfab, [@trigrou](https://twitter.com/trigrou)
* Saurabh Bhatia, Microsoft [@iamsbtron](https://twitter.com/iamsbtron)
* Gary Hsu, Microsoft [@bghgary](https://twitter.com/bghgary)
* Patrick Cozzi, Cesium, [@pjcozzi](https://twitter.com/pjcozzi)

## Status

Draft

## Dependencies

Written against the glTF 2.0 spec.

## Overview

This extension defines the specular-glossiness material model from Physically-Based Rendering (PBR). This extensions allows glTF to support this additional workflow.

The [conformance](#conformance) section specifies what an implementation must to do when encountering this extension, and how the extension interacts with the materials defined in the base specification.

## Extending Materials

The PBR specular-glossiness materials are defined by adding the `KHR_materials_pbrSpecularGlossiness` extension to any glTF material.
For example, the following defines a material like gold using specular-glossiness parameters.:

```
{
"materials": [
{
"name": "gold",
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [ 0.5, 0.5, 0.5, 1 ],
"specularFactor": [ 0.0, 0.0, 0.0 ],
"glossinessFactor": 0.8
}
}

}
]
}
```

### Specular - Glossiness

Todo: Add figure

The specular-glossiness material model is defined by the following properties:
* `diffuse` - Reflected diffuse color of the material
* `specular` - Specular color of the material
* `glossiness` - Glossiness of the material

The diffuse value represents the reflected diffuse color of the material. The specular value defines the specific measured reflectance value at normal incidence (F0). The glossiness property is a factor between `0.0` (rough surface) and `1.0` (smooth surface) and represents the surface irregularities that cause light diffusion.

The specular property from specular-glossiness material model is the same as the base color value from the metallic-roughness material model for metals. The glossiness property from specular-glossiness material model is related with the roughness property from the metallic-roughness material model and is defined as `glossiness = 1 - roughness`. See [appendix](#appendix) for more details on how you can convert between these two material models.

The value for each property (`diffuse`, `specular`, `glossiness`) can be defined using factors or textures. The `specular` and `glossiness` properties are packed together in a single texture called `specularGlossinessTexture`. If a texture is not given, all respective texture components within this material model are assumed to have a value of `1.0`. The factors (`diffuseFactor`, `specularFactor`, `glossinessFactor`) scale, in linear space, the components given in the respective textures (`diffuseTexture`, `specularGlossinessTexture`). Texture content must be converted to linear space before it is used for any lighting computations.
Copy link
Member

Choose a reason for hiding this comment

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

Texture content must be converted to linear space

Does it imply that all textures should be stored in sRGB? If so, we must mention that.
Should it be possible to directly store linear data (e.g., via floats in future) in textures? Also, see #835.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it's required that all textures are stored in sRGB. The two textures in this spec will be interpreted as sRGB (as indicated at the bottom), but other textures in extensions or future additions may or may not be depending on the situation. The point of this statement is to ensure that all the math must be done in linear space regardless of how it is stored.


The following equations show how to calculate bidirectional reflectance distribution function (BRDF) inputs (*c<sub>diff</sub>*, *F<sub>0</sub>*, *&alpha;*) from the metallic-roughness material properties.

*c<sub>diff</sub>* = `diffuse.rgb * (1 - max(specular.r, specular.g, specular.b)`
<br>
*F<sub>0</sub>* = `specular`
<br>
*&alpha;* = `max((1 - glossiness) ^ 2, epsilon)`

All implementations should use the same calculations for the BRDF inputs. Implementations of the BRDF itself can vary based on device performance and resource constraints. See [appendix](/specification/2.0/README.md#appendix-a) for more details on the BRDF calculations.

The following table lists the allowed types and ranges for the specular-glossiness model:

| |Type|Description|Required|
|---|----|-----------|--------|
|**diffuseFactor** | `number[4]` | The reflected diffuse factor of the material.|No, default:`[1.0,1.0,1.0,1.0]`|
|**diffuseTexture** | [`textureInfo`](/specification/2.0/README.md#reference-textureInfo) | The diffuse texture.|No|
|**specularFactor** | `number[3]` | The specular RGB color of the material. |No, default:`[1.0,1.0,1.0]`|
|**glossinessFactor** | `number` | The glossiness or smoothness of the material. |No, default:`1.0`|
|**specularGlossinessTexture** | [`textureInfo`](/specification/2.0/README.md#reference-textureInfo) | The specular-glossiness texture.|No|

Additional properties are not allowed.

* **JSON schema**: [glTF.KHR_materials_pbrSpecularGlossiness.schema.json](schema/glTF.KHR_materials_pbrSpecularGlossiness.schema.json)

### diffuseFactor

The RGBA components of the reflected diffuse color of the material. Metals have a diffuse value of `[0.0, 0.0, 0.0]`. The fourth component (A) is the opacity of the material. The values are linear.

* **Type**: `number[4]`
* **Required**: No, default:`[1.0,1.0,1.0,1.0]`
* **Range**: [0,1] for all components

### diffuseTexture

The diffuse texture. This texture contains RGB(A) components of the reflected diffuse color of the material in sRGB color space. If the fourth component (A) is present, it represents the opacity of the material. Otherwise, an opacity of 1.0 is assumed.

* **Type**: [`textureInfo`](/specification/2.0/README.md#reference-textureInfo)
* **Required**: No

### specularFactor

The specular RGB color of the material. This value is linear.

* **Type**: `number[3]`
* **Required**: No, default:`[1.0,1.0,1.0]`
* **Range**: [0,1] for all components


### glossinessFactor

The glossiness or smoothness of the material. A value of 1.0 means the material has full glossiness or is perfectly smooth. A value of 0.0 means the material has no glossiness or is perfectly rough. This value is linear.

* **Type**: `number`
* **Required**: No, default:`1.0`
* **Range**: [0,1]

### specularGlossinessTexture

The specular-glossiness texture is a RGBA texture, containing the specular color (RGB) in sRGB space and the glossiness value (A) in linear space.

* **Type**: [`textureInfo`](/specification/2.0/README.md#reference-textureInfo)
* **Required**: No


#### Additional maps
Copy link
Member

Choose a reason for hiding this comment

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

Can we be consistent on maps/textures term?

Copy link
Contributor

Choose a reason for hiding this comment

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

My opinion is that texture is a type where map is a concept (i.e. maps are stored as textures). That said, maybe we can call this "common properties" to avoid the problem all together.


The [additional maps](/specification/2.0/README.md#additionalmaps) defined in glTF materials node can also be used with the PBR specular-glossiness material model parameters defined in this extension.

```
{
"materials": [
{
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseTexture": {
"index": 0
},
"glossinessFactor": 0.5,
"specularGlossinessTexture": {
"index": 0,
"texCoord": 0
}
}
},
"normalTexture": {
"scale": 2,
"index": 3,
"texCoord": 1
},
"emissiveFactor": [ 0.2, 0.1, 0.0 ]
}
]
}
```

<a name="conformance"></a>
## Conformance and best practices

The PBR specular-glossiness extension can be used along with PBR metallic-roughness material model in glTF to enable support for both PBR workflows. Specular-glossiness can represent a broader range of materials compared to metallic-roughness. However, supporting specular-glossiness on low-resource devices may not be possible as it is more resource heavy than the metallic-roughness model. To get the best of both worlds a glTF asset can include both metallic-roughness and specular-glossiness in a single glTF. This allows the asset to take advantage of richer specular-glossiness materials where possible and still have a fall back with metallic-roughness to ensure that the asset can be rendered everywhere. Since such an approach requires including both material models it is best suited for a web scenario where a client can choose to download the appropriate material model from a server hosting the glTF file.

The following example shows how the same material can be defined using both metallic-roughness as well as specular-glossiness material models:

```
{
"materials": [
{
"name": "gold",
"pbrMetallicRoughness": {
"baseColorfactor": [ 1.000, 0.766, 0.336, 1.0 ],
"metallicFactor": 1.0,
"roughnessFactor": 0.0
},
"extensions": {
"KHR_materials_pbrSpecularGlossiness": {
"diffuseFactor": [ 0.5, 0.5, 0.5, 1 ],
"specularFactor": [ 0.0, 0.0, 0.0 ],
"glossinessFactor": 0.8
}
}
}
]
}
```
If the pbrSpecularGlossiness extension is included in an asset, then any runtime implementation that supports the extension should always render the asset using the specular-glossiness material properties to ensure quality.

A glTF asset may also choose to use the pbrSpecularGlossiness extension without including any metallic-roughness properties for its material definition. If such an asset chooses to include the extension using the `extensionUsed` property then a runtime that doesn't support the pbrSpecularGlossiness extension may choose to render the asset by converting the specular-glossiness values to metallic-roughness using the conversion mechanism described in the [appendix](#appendix). Such a conversion during load can be slow and potentially lossy so the runtime could also choose to ignore the material parameters and render the asset using 50% gray emissive color as described in the [base specification](/specification/2.0/README.md#appendix-a).

If an asset includes the pbrSpecularGlossiness extension using the `extensionsRequired` property and does not specify any metallic-roughness properties then only a runtime that supports the pbrSpecularGlossines extension can render it. With this approach you trade off portability of the asset to ensure quality.

The following table describes the expected rendering behavior based on the material definitions included in the asset:

Copy link
Member

Choose a reason for hiding this comment

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

The last column implies that MR model isn't supported, right? Doesn't that contradict base 2.0 spec?

Copy link
Contributor

Choose a reason for hiding this comment

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

To me, this is a general issue with extensionRequired. If we say an extension is required, then it basically means the asset isn't following the core spec anymore. This can happen with any extension, right? What happens if someone puts KHR_technique_webgl as required?

Copy link
Member

Choose a reason for hiding this comment

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

the asset isn't following the core spec anymore

Right. But a runtime should support core spec anyway. So in what case does last column apply? Are we basically allowing to implement only SpecGloss and always convert MR?

| | Runtime supports Metallic-Roughness | Runtime supports Metallic-Roughness and Specular-Glossiness | Runtime supports Specular-Glossiness|
|----|:----:|:----:|:----:|
|Asset has Metallic-Roughness | Render Metallic-Roughness | Render Metallic-Roughness | Convert and Render in Specular-Glossiness (not lossy) |
|Asset has Metallic-Roughness and Specular-Glossiness | Render Metallic-Roughness | Render Specular-Glossiness | Render Specular-Glossiness|
|Asset has Specular-Glossiness| Convert and render Metallic-Roughness (lossy) | Render Specular-Glossiness | Render Specular-Glossiness|


## Appendix

Conversion between the two PBR material models:
- [Convert between metallic-roughness and specular-glossiness using BabylonJS](examples/convert-between-workflows-bjs/)
- [Convert between metallic-roughness and specular-glossiness using WebGL and threeJS](examples/convert-between-workflows/)





Binary file not shown.
Binary file not shown.
Loading