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_ior #1718

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
99 changes: 99 additions & 0 deletions extensions/2.0/Khronos/KHR_materials_ior/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# KHR\_materials\_ior

## Khronos 3D Formats Working Group
emackey marked this conversation as resolved.
Show resolved Hide resolved

* TODO

## Acknowledgments

* TODO

## Status

Experimental

## Dependencies

Written against the glTF 2.0 spec.

## Overview

The dielectric BRDF of the metallic-roughness material in glTF uses a fixed value of 1.5 for the index of refraction. This is a good fit for many plastics and glass, but not for other materials like water or asphalt, sapphire or diamond. This extensions allows users to set the index of refraction to a certain value.

## Extending Materials

The index of refraction of a material is configured by adding the `KHR_materials_ior` extension to any glTF material.

```json
{
"materials": [
{
"extensions": {
"KHR_materials_ior": {
"ior": 1.4,
}
}
}
]
}
```

Typical values for the index of refraction range from 1 to 2. In rare cases values greater than 2 are possible. The following table shows some materials and their index of refraction:
emackey marked this conversation as resolved.
Show resolved Hide resolved

| Material | Index of Refraction |
|--------------|---------------------|
| Air | 1.0 |
| Water | 1.33 |
| Eyes | 1.38 |
| Window Glass | 1.52 |
| Sapphire | 1.76 |
| Diamond | 2.42 |

The index of refraction (IOR) can be defined either as a scalar value (`ior`) or as a texture (`f0Texture`). If both are given at the same time, `f0Texture` overrides `ior`.

| |Type|Description|Required|
|-|----|-----------|--------|
| **ior** | `number` | The index of refraction. | No, default: `1.5`|
| **f0Texture** | [`textureInfo`](/specification/2.0/README.md#reference-textureInfo) | A 1-channel luminance texture that defines the index of refraction in terms of the reflectance at normal incidence f0. | No |
| **maxF0** | `number` | When using `f0Texture`, a texture value of 1.0 is interpret as `maxF0`. Values between 0 and 1 are linearly scaled between 0 and `maxF0`. | No, default: `0.08` |

The texture stores the IOR in terms of the reflectance at normal incidence, a value in the range 0..1. The mapping works as follows:

```
f0 = ((ior - 1) / (ior + 1))^2
ior = 2 / (1 - sqrt(f0)) - 1
```

As f0 usually is a small value (IOR in range 1..2 corresponds to f0 in range 0..0.08), an optional scale factor can be applied to the texture via `maxF0`.

In case `KHR_materials_volume` is enabled, the `ior` affects the bending of light rays (refraction) passing through the transparent surface and it determines the refractive index of the volume below the surface. As the volume cannot be parametrized with a 2-dimensional texture in UV space, `f0Texture` and `maxF0` are ignored.

## Implementation

The index of refraction affects the Fresnel term in the dielectric BRDF:

```
dielectric_brdf =
fresnel_mix(
diffuse_brdf(baseColor),
microfacet_brdf(roughness^2),
ior)
```

[Appendix B](/specification/2.0/README.md#appendix-b-brdf-implementation) defines the `fresnel_mix` operation as

```
fresnel_mix(base, layer, ior) = base * (1 - fr(ior)) + layer * fr(ior)
fr(ior) = f0 + (1 - f0) * (1 - cos)^5
f0 = ((ior - 1) / (ior + 1))^2
```

with `ior = 1.5`, corresponding to `f0 = 0.04`. The following pseudo-code shows how to compute `f0` from `ior`, `f0Texture` and `maxF0`:

```
if (f0Texture is enabled) {
f0 = fetch(f0Texture, uv) * maxF0;
} else {
f0 = ((ior - 1) / (ior + 1))^2
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"title": "KHR_materials_ior glTF extension",
"type": "object",
"description": "glTF extension that defines the index of refraction of a material.",
"allOf": [ { "$ref": "glTFProperty.schema.json" } ],
"properties": {
"ior": {
"type": "number",
"description": "The index of refraction.",
"default": 1.5,
"minimum": 1.0,
emackey marked this conversation as resolved.
Show resolved Hide resolved
"gltf_detailedDescription": "The index of refraction (IOR) is a measured physical number usually in the range between 1 and 2 that determines how much the path of light is bent, or refracted, when entering a material. It also influences the ratio between reflected and transmitted light, calculated from the Fresnel equations."
},
"f0Texture": {
"allOf": [ { "$ref": "textureInfo.schema.json" } ],
"description": "A 1-channel luminance texture that defines the index of refraction in terms of the reflectance at normal incidence f0.",
"gltf_detailedDescription": "The texture stores the index of refraction in terms of the reflectance at normal incidence, a value in the range 0..1: f0 = ((ior - 1) / (ior + 1))^2. If the texture is enabeld, the ior property is ignored."
},
"maxF0": {
"type": "number",
"description": "Maximum F0 value, corresponds to a texture value of 1.0.",
"default": 0.08,
"minimum": 0.0,
"maximum": 1.0,
"gltf_detailedDescription": "The maximum F0 value acts as a multiplier for the value fetched from the f0 texture. The default of 0.08 maps the texture value 0.5 (128) to an index of refraction of 1.5."
},
"extensions": { },
"extras": { }
}
}