bevy/assets/models/TonemappingTest/TonemappingTest.gltf
Patrick Walton 961b24deaf
Implement filmic color grading. (#13121)
This commit expands Bevy's existing tonemapping feature to a complete
set of filmic color grading tools, matching those of engines like Unity,
Unreal, and Godot. The following features are supported:

* White point adjustment. This is inspired by Unity's implementation of
the feature, but simplified and optimized. *Temperature* and *tint*
control the adjustments to the *x* and *y* chromaticity values of [CIE
1931]. Following Unity, the adjustments are made relative to the [D65
standard illuminant] in the [LMS color space].

* Hue rotation. This simply converts the RGB value to [HSV], alters the
hue, and converts back.

* Color correction. This allows the *gamma*, *gain*, and *lift* values
to be adjusted according to the standard [ASC CDL combined function].

* Separate color correction for shadows, midtones, and highlights.
Blender's source code was used as a reference for the implementation of
this. The midtone ranges can be adjusted by the user. To avoid abrupt
color changes, a small crossfade is used between the different sections
of the image, again following Blender's formulas.

A new example, `color_grading`, has been added, offering a GUI to change
all the color grading settings. It uses the same test scene as the
existing `tonemapping` example, which has been factored out into a
shared glTF scene.

[CIE 1931]: https://en.wikipedia.org/wiki/CIE_1931_color_space

[D65 standard illuminant]:
https://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D

[LMS color space]: https://en.wikipedia.org/wiki/LMS_color_space

[HSV]: https://en.wikipedia.org/wiki/HSL_and_HSV

[ASC CDL combined function]:
https://en.wikipedia.org/wiki/ASC_CDL#Combined_Function

## Changelog

### Added

* Many new filmic color grading options have been added to the
`ColorGrading` component.

## Migration Guide

* `ColorGrading::gamma` and `ColorGrading::pre_saturation` are now set
separately for the `shadows`, `midtones`, and `highlights` sections. You
can migrate code with the `ColorGrading::all_sections` and
`ColorGrading::all_sections_mut` functions, which access and/or update
all sections at once.
* `ColorGrading::post_saturation` and `ColorGrading::exposure` are now
fields of `ColorGrading::global`.

## Screenshots

![Screenshot 2024-04-27
143144](https://github.com/bevyengine/bevy/assets/157897/c1de5894-917d-4101-b5c9-e644d141a941)

![Screenshot 2024-04-27
143216](https://github.com/bevyengine/bevy/assets/157897/da393c8a-d747-42f5-b47c-6465044c788d)
2024-05-02 12:18:59 +00:00

679 lines
9.4 KiB
JSON

{
"asset":{
"generator":"Khronos glTF Blender I/O v4.0.44",
"version":"2.0"
},
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0,
1,
2
]
}
],
"nodes":[
{
"mesh":0,
"name":"Plane",
"scale":[
50,
1,
50
]
},
{
"mesh":1,
"name":"Cube",
"translation":[
-1,
0.125,
0
]
},
{
"mesh":2,
"name":"Sphere",
"translation":[
0,
0.125,
0
]
}
],
"materials":[
{
"doubleSided":true,
"name":"Material.001",
"pbrMetallicRoughness":{
"baseColorFactor":[
0.10000000149011612,
0.20000000298023224,
0.10000000149011612,
1
],
"metallicFactor":0,
"roughnessFactor":0.5
}
},
{
"doubleSided":true,
"name":"Material.002",
"pbrMetallicRoughness":{
"baseColorTexture":{
"index":0
},
"metallicFactor":0,
"roughnessFactor":0.5
}
},
{
"doubleSided":true,
"name":"Sphere0",
"pbrMetallicRoughness":{
"baseColorFactor":[
0,
0,
1,
1
],
"metallicFactor":0,
"roughnessFactor":0.08900000154972076
}
},
{
"doubleSided":true,
"name":"Sphere1",
"pbrMetallicRoughness":{
"baseColorFactor":[
0,
1,
0,
1
],
"metallicFactor":0,
"roughnessFactor":0.08900000154972076
}
},
{
"doubleSided":true,
"name":"Sphere2",
"pbrMetallicRoughness":{
"baseColorFactor":[
1,
0,
0,
1
],
"metallicFactor":0,
"roughnessFactor":0.08900000154972076
}
},
{
"doubleSided":true,
"name":"Sphere3",
"pbrMetallicRoughness":{
"baseColorFactor":[
0.20000000298023224,
0.20000000298023224,
1,
1
],
"metallicFactor":0,
"roughnessFactor":0.08900000154972076
}
},
{
"doubleSided":true,
"name":"Sphere4",
"pbrMetallicRoughness":{
"baseColorFactor":[
0.20000000298023224,
1,
0.20000000298023224,
1
],
"metallicFactor":0,
"roughnessFactor":0.08900000154972076
}
},
{
"doubleSided":true,
"name":"Sphere5",
"pbrMetallicRoughness":{
"baseColorFactor":[
1,
0.20000000298023224,
0.20000000298023224,
1
],
"metallicFactor":0,
"roughnessFactor":0.08900000154972076
}
}
],
"meshes":[
{
"name":"Plane",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3,
"material":0
}
]
},
{
"name":"Cube.001",
"primitives":[
{
"attributes":{
"POSITION":4,
"NORMAL":5,
"TEXCOORD_0":6
},
"indices":7,
"material":1
}
]
},
{
"name":"Sphere",
"primitives":[
{
"attributes":{
"POSITION":8,
"NORMAL":9,
"TEXCOORD_0":10
},
"indices":11,
"material":2
},
{
"attributes":{
"POSITION":12,
"NORMAL":13,
"TEXCOORD_0":14
},
"indices":11,
"material":3
},
{
"attributes":{
"POSITION":15,
"NORMAL":16,
"TEXCOORD_0":17
},
"indices":11,
"material":4
},
{
"attributes":{
"POSITION":18,
"NORMAL":19,
"TEXCOORD_0":20
},
"indices":11,
"material":5
},
{
"attributes":{
"POSITION":21,
"NORMAL":22,
"TEXCOORD_0":23
},
"indices":11,
"material":6
},
{
"attributes":{
"POSITION":24,
"NORMAL":25,
"TEXCOORD_0":26
},
"indices":11,
"material":7
}
]
}
],
"textures":[
{
"sampler":0,
"source":0
}
],
"images":[
{
"mimeType":"image/png",
"name":"TestPattern",
"uri":"TestPattern.png"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":4,
"max":[
1,
0,
1
],
"min":[
-1,
0,
-1
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":4,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":4,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":6,
"type":"SCALAR"
},
{
"bufferView":4,
"componentType":5126,
"count":120,
"max":[
1.125,
0.125,
0.125
],
"min":[
-0.125,
-0.125,
-2.125
],
"type":"VEC3"
},
{
"bufferView":5,
"componentType":5126,
"count":120,
"type":"VEC3"
},
{
"bufferView":6,
"componentType":5126,
"count":120,
"type":"VEC2"
},
{
"bufferView":7,
"componentType":5123,
"count":180,
"type":"SCALAR"
},
{
"bufferView":8,
"componentType":5126,
"count":625,
"max":[
-0.42500004172325134,
0.125,
0.37499991059303284
],
"min":[
-0.6749998927116394,
-0.125,
0.125
],
"type":"VEC3"
},
{
"bufferView":9,
"componentType":5126,
"count":625,
"type":"VEC3"
},
{
"bufferView":10,
"componentType":5126,
"count":625,
"type":"VEC2"
},
{
"bufferView":11,
"componentType":5123,
"count":3264,
"type":"SCALAR"
},
{
"bufferView":12,
"componentType":5126,
"count":625,
"max":[
-0.17500004172325134,
0.125,
0.12499991804361343
],
"min":[
-0.4249998927116394,
-0.125,
-0.125
],
"type":"VEC3"
},
{
"bufferView":13,
"componentType":5126,
"count":625,
"type":"VEC3"
},
{
"bufferView":14,
"componentType":5126,
"count":625,
"type":"VEC2"
},
{
"bufferView":15,
"componentType":5126,
"count":625,
"max":[
0.07499995082616806,
0.125,
-0.12500005960464478
],
"min":[
-0.1749998927116394,
-0.125,
-0.3749999701976776
],
"type":"VEC3"
},
{
"bufferView":16,
"componentType":5126,
"count":625,
"type":"VEC3"
},
{
"bufferView":17,
"componentType":5126,
"count":625,
"type":"VEC2"
},
{
"bufferView":18,
"componentType":5126,
"count":625,
"max":[
-0.1250000298023224,
0.125,
0.6749999523162842
],
"min":[
-0.37499988079071045,
-0.125,
0.42500001192092896
],
"type":"VEC3"
},
{
"bufferView":19,
"componentType":5126,
"count":625,
"type":"VEC3"
},
{
"bufferView":20,
"componentType":5126,
"count":625,
"type":"VEC2"
},
{
"bufferView":21,
"componentType":5126,
"count":625,
"max":[
0.12499996274709702,
0.125,
0.4249999225139618
],
"min":[
-0.12499988079071045,
-0.125,
0.17500001192092896
],
"type":"VEC3"
},
{
"bufferView":22,
"componentType":5126,
"count":625,
"type":"VEC3"
},
{
"bufferView":23,
"componentType":5126,
"count":625,
"type":"VEC2"
},
{
"bufferView":24,
"componentType":5126,
"count":625,
"max":[
0.3749999403953552,
0.125,
0.1749999225139618
],
"min":[
0.12500008940696716,
-0.125,
-0.07499998807907104
],
"type":"VEC3"
},
{
"bufferView":25,
"componentType":5126,
"count":625,
"type":"VEC3"
},
{
"bufferView":26,
"componentType":5126,
"count":625,
"type":"VEC2"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":48,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":48,
"byteOffset":48,
"target":34962
},
{
"buffer":0,
"byteLength":32,
"byteOffset":96,
"target":34962
},
{
"buffer":0,
"byteLength":12,
"byteOffset":128,
"target":34963
},
{
"buffer":0,
"byteLength":1440,
"byteOffset":140,
"target":34962
},
{
"buffer":0,
"byteLength":1440,
"byteOffset":1580,
"target":34962
},
{
"buffer":0,
"byteLength":960,
"byteOffset":3020,
"target":34962
},
{
"buffer":0,
"byteLength":360,
"byteOffset":3980,
"target":34963
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":4340,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":11840,
"target":34962
},
{
"buffer":0,
"byteLength":5000,
"byteOffset":19340,
"target":34962
},
{
"buffer":0,
"byteLength":6528,
"byteOffset":24340,
"target":34963
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":30868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":38368,
"target":34962
},
{
"buffer":0,
"byteLength":5000,
"byteOffset":45868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":50868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":58368,
"target":34962
},
{
"buffer":0,
"byteLength":5000,
"byteOffset":65868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":70868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":78368,
"target":34962
},
{
"buffer":0,
"byteLength":5000,
"byteOffset":85868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":90868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":98368,
"target":34962
},
{
"buffer":0,
"byteLength":5000,
"byteOffset":105868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":110868,
"target":34962
},
{
"buffer":0,
"byteLength":7500,
"byteOffset":118368,
"target":34962
},
{
"buffer":0,
"byteLength":5000,
"byteOffset":125868,
"target":34962
}
],
"samplers":[
{
"magFilter":9728,
"minFilter":9984
}
],
"buffers":[
{
"byteLength":130868,
"uri":"TonemappingTest.bin"
}
]
}