@woosh/meep-engine 3.63.2 → 3.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/package.json +1 -1
- package/src/core/color/xyz/m3_chromatic_adaptation_bradford.d.ts +14 -0
- package/src/core/color/xyz/m3_chromatic_adaptation_bradford.d.ts.map +1 -0
- package/src/core/color/xyz/m3_chromatic_adaptation_bradford.js +51 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts +2 -1
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +51 -70
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.js +8 -64
- package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.d.ts +17 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.d.ts.map +1 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.js +64 -0
- package/src/core/math/linalg/solve_box_constrained_qp.d.ts +30 -0
- package/src/core/math/linalg/solve_box_constrained_qp.d.ts.map +1 -0
- package/src/core/math/linalg/solve_box_constrained_qp.js +205 -0
- package/src/engine/physics/constraint/soft_spring_coefficients.d.ts +24 -0
- package/src/engine/physics/constraint/soft_spring_coefficients.d.ts.map +1 -0
- package/src/engine/physics/constraint/soft_spring_coefficients.js +38 -0
- package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
- package/src/engine/physics/constraint/solve_constraints.js +16 -8
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +54 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +192 -7
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts +3 -5
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
- package/src/engine/physics/inertia/world_inverse_inertia.js +3 -5
- package/src/engine/physics/vehicle/RaycastVehicle.d.ts +183 -12
- package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
- package/src/engine/physics/vehicle/RaycastVehicle.js +1046 -121
- package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts +17 -0
- package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUCommandEncoder.js +46 -0
- package/src/shade/playground/tonemap_sdr/README.md +11 -8
- package/src/shade/playground/tonemap_sdr/ToneMapCompare.js +2 -2
- package/src/shade/renderer/Renderer.d.ts +5 -6
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +15 -88
- package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.d.ts +14 -0
- package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.d.ts.map +1 -0
- package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.js +62 -0
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +12 -0
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.js +85 -0
- package/src/shade/renderer/buffer/table/GPUDatabaseDefinition.d.ts +2 -1
- package/src/shade/renderer/buffer/table/GPUDatabaseDefinition.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabaseDefinition.js +2 -1
- package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts +158 -0
- package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/ColorGrade.js +337 -0
- package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.d.ts +9 -0
- package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.js +15 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.d.ts +6 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.js +84 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.d.ts +10 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.js +25 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.d.ts +9 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.js +20 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.d.ts +14 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.js +30 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapOperator.d.ts +54 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapOperator.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapOperator.js +63 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts +106 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapper.js +474 -0
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts +5 -13
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.js +5 -44
- package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.d.ts +7 -25
- package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.js +11 -51
- package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.d.ts +20 -0
- package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.js +103 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts +9 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/{shader_tonemap_HDR_none.js → shader_tonemap_HDR_lut.js} +22 -18
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts +9 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/{shader_tonemap_LDR_aces.js → shader_tonemap_LDR_lut.js} +24 -24
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.d.ts +23 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.js +92 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.d.ts +15 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.js +73 -0
- package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
- package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +1 -1
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.js +62 -0
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts +13 -0
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.js +140 -0
- package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.d.ts +11 -0
- package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.js +65 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.d.ts +14 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.js +38 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.d.ts +16 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.js +41 -0
- package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -8
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
- package/src/shade/renderer/ShadeToneMappingMode.d.ts +0 -15
- package/src/shade/renderer/ShadeToneMappingMode.d.ts.map +0 -1
- package/src/shade/renderer/ShadeToneMappingMode.js +0 -41
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.d.ts +0 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.js +0 -79
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts +0 -17
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.js +0 -101
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_none.d.ts +0 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_none.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.d.ts +0 -10
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.js +0 -80
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.d.ts +0 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.js +0 -80
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts +0 -10
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.d.ts +0 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.js +0 -71
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.d.ts +0 -10
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.js +0 -76
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_hdr_bt2390.d.ts +0 -3
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_hdr_bt2390.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_hdr_bt2390.js +0 -44
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUDatabaseDefinition.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/buffer/table/GPUDatabaseDefinition.js"],"names":[],"mappings":"AAwCA;;;;;;;;;;GAUG;AACH;IA0DI;;;;;OAKG;IACH,0CAHW,MAAM,GACJ,qBAAqB,CAIjC;IA9BD;;;OAGG;IACH,2CAFW,MAAM,EAkBhB;IAvDD;;OAEG;IACH,aAFU,uBAAuB,EAAE,CAElB;IAOjB;;;OAGG;IACH,iBAFU,MAAM,CAEA;IA8FhB
|
|
1
|
+
{"version":3,"file":"GPUDatabaseDefinition.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/buffer/table/GPUDatabaseDefinition.js"],"names":[],"mappings":"AAwCA;;;;;;;;;;GAUG;AACH;IA0DI;;;;;OAKG;IACH,0CAHW,MAAM,GACJ,qBAAqB,CAIjC;IA9BD;;;OAGG;IACH,2CAFW,MAAM,EAkBhB;IAvDD;;OAEG;IACH,aAFU,uBAAuB,EAAE,CAElB;IAOjB;;;OAGG;IACH,iBAFU,MAAM,CAEA;IA8FhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+CG;IACH,eAVW;QACV,KAAW,EAAE,MAAM,CAAC;QACpB,KAAW,EAAE,MAAM,CAAC;QACpB,eAAqB,EAAE,qBAAqB,CAAC;QAC7C,YAAkB,EAAE,MAAM,CAAC;QAC3B,QAAc,EAAE,OAAO,CAAC;QACxB,MAAY,EAAE,OAAO,CAAC;KACnB,GACS,YAAY,CAgDxB;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gBAVW;QACV,KAAW,EAAE,MAAM,CAAC;QACpB,WAAiB,EAAE,MAAM,CAAC;QAC1B,WAAiB,EAAE,MAAM,CAAC;QAC1B,eAAqB,EAAE,qBAAqB,CAAC;QAC7C,YAAkB,EAAE,MAAM,CAAC;QAC3B,MAAY,EAAE,OAAO,CAAC;KACnB,GACS,aAAa,CAmDzB;IAiCD;;;OAGG;IACH,4BAEC;IAED;;;OAGG;IACH,8BAEC;IAED;;;;;OAKG;IACH,iBAHW,uBAAuB,GACrB,aAAa,EAAE,CAM3B;IAED;;;;;OAKG;IACH,gBAHW,uBAAuB,GACrB,YAAY,EAAE,CAM1B;IAED;;;;OAIG;IACH,sBAEC;IAED;;;;;;;OAOG;IACH,aAiEC;IAED;;;;OAIG;IACH,UAHW,MAAM,GACJ,OAAO,CAMnB;IAED;;;OAGG;IACH,UAHW,MAAM,GACJ,uBAAuB,GAAC,SAAS,CAM7C;IAED;;OAEG;IACH,0BAEC;IAGL;;;OAGG;IACH,kCAFU,OAAO,CAEsC;;CANtD;wCA7fuC,8BAA8B;6BAFzC,mBAAmB;8BAClB,oBAAoB"}
|
|
@@ -175,7 +175,8 @@ export class GPUDatabaseDefinition {
|
|
|
175
175
|
* it into every link word the row has, whatever `nullable` says, because a freed row points
|
|
176
176
|
* nowhere; a new page starts with it in every link word too. So a link no write has touched names
|
|
177
177
|
* no row, on a row never written as on one freed, and a value that leaves a link out leaves it
|
|
178
|
-
* naming nothing.
|
|
178
|
+
* naming nothing. That holds on the GPU for every occupied row and every freed one; a row the GPU
|
|
179
|
+
* has never been sent reads 0 there instead (see {@link GPUDatabase}).
|
|
179
180
|
*
|
|
180
181
|
* `owning` means one thing: removing the row that holds the link removes the row it names, and
|
|
181
182
|
* that row's owned rows in turn ({@link GPUTypedTable#remove}). Nothing else follows it.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The grade as the bake reads it, a uniform. Every field is 16 bytes, in this order, never packed: field i is at byte
|
|
3
|
+
* 16 · i, which is how {@link ColorGrade#pack} writes it.
|
|
4
|
+
*
|
|
5
|
+
* - `white_balance_c0..c2`: the white-balance matrix on linear Rec.709, by column.
|
|
6
|
+
* - per zone, `{zone}_saturation`, `_contrast`, `_gamma`, `_gain`, `_offset`: the zone's values with the global ones
|
|
7
|
+
* folded in and each vector's fourth component applied to the first three, as Unreal's `ColorCorrectAll` combines
|
|
8
|
+
* them.
|
|
9
|
+
* - `zone_bounds`: `shadows_max`, `highlights_min`, `highlights_max`.
|
|
10
|
+
* - `curve_counts`: the keys of the hue, saturation and lightness curves. They follow the uniform in `grade_keys`, in
|
|
11
|
+
* that order.
|
|
12
|
+
*/
|
|
13
|
+
export const COLOR_GRADE_STRUCT: WebGPUStruct;
|
|
14
|
+
/**
|
|
15
|
+
* Floats of {@link COLOR_GRADE_STRUCT} at the head of {@link ColorGrade#pack}'s data.
|
|
16
|
+
* @type {number}
|
|
17
|
+
*/
|
|
18
|
+
export const COLOR_GRADE_HEADER_FLOATS: number;
|
|
19
|
+
/**
|
|
20
|
+
* Floats of one keyframe in `grade_keys`: time, value, in tangent, out tangent.
|
|
21
|
+
* @type {number}
|
|
22
|
+
*/
|
|
23
|
+
export const COLOR_GRADE_KEY_FLOATS: number;
|
|
24
|
+
/**
|
|
25
|
+
* One zone of Unreal's primary grade: shadows, midtones, highlights, or all of them. Each vector is RGB and a master
|
|
26
|
+
* value that scales (or, for the offset, adds to) all three.
|
|
27
|
+
*/
|
|
28
|
+
export class ColorGradeZone {
|
|
29
|
+
/**
|
|
30
|
+
* Blend between the luma and the colour; 0 is grey, 1 leaves it.
|
|
31
|
+
* @readonly
|
|
32
|
+
* @type {Vector4}
|
|
33
|
+
*/
|
|
34
|
+
readonly saturation: Vector4;
|
|
35
|
+
/**
|
|
36
|
+
* Power about 0.18.
|
|
37
|
+
* @readonly
|
|
38
|
+
* @type {Vector4}
|
|
39
|
+
*/
|
|
40
|
+
readonly contrast: Vector4;
|
|
41
|
+
/**
|
|
42
|
+
* The colour is raised to 1 / gamma.
|
|
43
|
+
* @readonly
|
|
44
|
+
* @type {Vector4}
|
|
45
|
+
*/
|
|
46
|
+
readonly gamma: Vector4;
|
|
47
|
+
/**
|
|
48
|
+
* @readonly
|
|
49
|
+
* @type {Vector4}
|
|
50
|
+
*/
|
|
51
|
+
readonly gain: Vector4;
|
|
52
|
+
/**
|
|
53
|
+
* Added last.
|
|
54
|
+
* @readonly
|
|
55
|
+
* @type {Vector4}
|
|
56
|
+
*/
|
|
57
|
+
readonly offset: Vector4;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A colour grade on the exposed scene colour, ahead of the tone-mapping operator, baked into the tone mapper's LUTs.
|
|
61
|
+
* Neutral as constructed. In order:
|
|
62
|
+
*
|
|
63
|
+
* 1. **White balance**, Unreal's temperature white balance on linear Rec.709; see `m3_white_balance_rec709`.
|
|
64
|
+
* 2. **Primaries**, Unreal's `ColorCorrectAll` in AP1: saturation, contrast, gamma, gain and offset for {@link global},
|
|
65
|
+
* {@link shadows}, {@link midtones} and {@link highlights}, the zones blended by AP1 luma between
|
|
66
|
+
* {@link shadows_max}, {@link highlights_min} and {@link highlights_max}. Values from an Unreal project's post-process
|
|
67
|
+
* settings give the same result. The colour is clamped at zero in Rec.709 after it, as the operator takes it.
|
|
68
|
+
* 3. **Hue curves**, in OkLCh. Each curve's time is the colour's OkLCh hue in degrees, 0 to 360, and is evaluated as
|
|
69
|
+
* {@link AnimationCurve#evaluate} would; a curve with no keys does nothing. The curve holds its end keys' values
|
|
70
|
+
* outside them, so for a seamless circle key 0 and 360 with the same value and tangent.
|
|
71
|
+
* - {@link hue_shift}: degrees added to the hue.
|
|
72
|
+
* - {@link hue_saturation}: a multiplier on the chroma.
|
|
73
|
+
* - {@link hue_lightness}: stops of exposure, the light multiplied by 2^stops at the same chromaticity, weighted by
|
|
74
|
+
* the colour's saturation relative to the most saturated Rec.709 colour of its hue. A grey never moves, and a
|
|
75
|
+
* colour on the gamut's edge takes the full value.
|
|
76
|
+
* All three are read at the colour's hue before any of them applies.
|
|
77
|
+
*
|
|
78
|
+
* Read by the tone mapper every frame; any change bakes the LUTs again. A LUT the user supplies is not graded.
|
|
79
|
+
*/
|
|
80
|
+
export class ColorGrade {
|
|
81
|
+
/**
|
|
82
|
+
* Colour temperature of the white the grade makes neutral, K. 6500 does nothing.
|
|
83
|
+
* @type {number}
|
|
84
|
+
*/
|
|
85
|
+
white_temperature: number;
|
|
86
|
+
/**
|
|
87
|
+
* Offset of that white along its isotherm, -1 to 1 as in Unreal. 0 does nothing.
|
|
88
|
+
* @type {number}
|
|
89
|
+
*/
|
|
90
|
+
white_tint: number;
|
|
91
|
+
/**
|
|
92
|
+
* Applies in every zone, under the zone's own values.
|
|
93
|
+
* @readonly
|
|
94
|
+
* @type {ColorGradeZone}
|
|
95
|
+
*/
|
|
96
|
+
readonly global: ColorGradeZone;
|
|
97
|
+
/**
|
|
98
|
+
* @readonly
|
|
99
|
+
* @type {ColorGradeZone}
|
|
100
|
+
*/
|
|
101
|
+
readonly shadows: ColorGradeZone;
|
|
102
|
+
/**
|
|
103
|
+
* @readonly
|
|
104
|
+
* @type {ColorGradeZone}
|
|
105
|
+
*/
|
|
106
|
+
readonly midtones: ColorGradeZone;
|
|
107
|
+
/**
|
|
108
|
+
* @readonly
|
|
109
|
+
* @type {ColorGradeZone}
|
|
110
|
+
*/
|
|
111
|
+
readonly highlights: ColorGradeZone;
|
|
112
|
+
/**
|
|
113
|
+
* AP1 luma at which the shadows' weight reaches 0. Unreal's default.
|
|
114
|
+
* @type {number}
|
|
115
|
+
*/
|
|
116
|
+
shadows_max: number;
|
|
117
|
+
/**
|
|
118
|
+
* AP1 luma at which the highlights' weight starts to rise from 0. Unreal's default.
|
|
119
|
+
* @type {number}
|
|
120
|
+
*/
|
|
121
|
+
highlights_min: number;
|
|
122
|
+
/**
|
|
123
|
+
* AP1 luma at which the highlights' weight reaches 1. Unreal's default.
|
|
124
|
+
* @type {number}
|
|
125
|
+
*/
|
|
126
|
+
highlights_max: number;
|
|
127
|
+
/**
|
|
128
|
+
* Degrees added to the OkLCh hue, against the hue in degrees.
|
|
129
|
+
* @readonly
|
|
130
|
+
* @type {AnimationCurve}
|
|
131
|
+
*/
|
|
132
|
+
readonly hue_shift: AnimationCurve;
|
|
133
|
+
/**
|
|
134
|
+
* Multiplier on the OkLCh chroma, against the hue in degrees.
|
|
135
|
+
* @readonly
|
|
136
|
+
* @type {AnimationCurve}
|
|
137
|
+
*/
|
|
138
|
+
readonly hue_saturation: AnimationCurve;
|
|
139
|
+
/**
|
|
140
|
+
* Stops of exposure, against the hue in degrees.
|
|
141
|
+
* @readonly
|
|
142
|
+
* @type {AnimationCurve}
|
|
143
|
+
*/
|
|
144
|
+
readonly hue_lightness: AnimationCurve;
|
|
145
|
+
/**
|
|
146
|
+
* The grade as the bake reads it: {@link COLOR_GRADE_STRUCT}, then the three curves' keys, each
|
|
147
|
+
* {@link COLOR_GRADE_KEY_FLOATS} floats, with room for one key when there are none. The array is reused while the
|
|
148
|
+
* key count stays the same.
|
|
149
|
+
*
|
|
150
|
+
* @returns {Float32Array}
|
|
151
|
+
*/
|
|
152
|
+
pack(): Float32Array;
|
|
153
|
+
#private;
|
|
154
|
+
}
|
|
155
|
+
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
156
|
+
import { Vector4 } from "../../../../core/geom/Vector4.js";
|
|
157
|
+
import { AnimationCurve } from "../../../../engine/animation/curve/AnimationCurve.js";
|
|
158
|
+
//# sourceMappingURL=ColorGrade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorGrade.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/ColorGrade.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;GAWG;AACH,8CAyBG;AAEH;;;GAGG;AACH,wCAFU,MAAM,CAE4B;AAE5C;;;GAGG;AACH,qCAFU,MAAM,CAEwB;AAExC;;;GAGG;AACH;IACI;;;;OAIG;IACH,qBAFU,OAAO,CAEoB;IAErC;;;;OAIG;IACH,mBAFU,OAAO,CAEkB;IAEnC;;;;OAIG;IACH,gBAFU,OAAO,CAEe;IAEhC;;;OAGG;IACH,eAFU,OAAO,CAEc;IAE/B;;;;OAIG;IACH,iBAFU,OAAO,CAEgB;CACpC;AAwED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IACI;;;OAGG;IACH,mBAFU,MAAM,CAEsC;IAEtD;;;OAGG;IACH,YAFU,MAAM,CAEwB;IAExC;;;;OAIG;IACH,iBAFU,cAAc,CAEM;IAE9B;;;OAGG;IACH,kBAFU,cAAc,CAEO;IAE/B;;;OAGG;IACH,mBAFU,cAAc,CAEQ;IAEhC;;;OAGG;IACH,qBAFU,cAAc,CAEU;IAElC;;;OAGG;IACH,aAFU,MAAM,CAEG;IAEnB;;;OAGG;IACH,gBAFU,MAAM,CAEK;IAErB;;;OAGG;IACH,gBAFU,MAAM,CAEG;IAEnB;;;;OAIG;IACH,oBAFU,cAAc,CAES;IAEjC;;;;OAIG;IACH,yBAFU,cAAc,CAEc;IAEtC;;;;OAIG;IACH,wBAFU,cAAc,CAEa;IAarC;;;;;;OAMG;IACH,QAFa,YAAY,CAqDxB;;CACJ;6BA5U4B,mCAAmC;wBAHxC,kCAAkC;+BAC3B,sDAAsD"}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { Vector4 } from "../../../../core/geom/Vector4.js";
|
|
3
|
+
import { AnimationCurve } from "../../../../engine/animation/curve/AnimationCurve.js";
|
|
4
|
+
import { vec4f, vec4u } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
5
|
+
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
6
|
+
import { m3_white_balance_rec709, WHITE_BALANCE_NEUTRAL_TEMPERATURE, WHITE_BALANCE_NEUTRAL_TINT } from "./m3_white_balance_rec709.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The grade as the bake reads it, a uniform. Every field is 16 bytes, in this order, never packed: field i is at byte
|
|
10
|
+
* 16 · i, which is how {@link ColorGrade#pack} writes it.
|
|
11
|
+
*
|
|
12
|
+
* - `white_balance_c0..c2`: the white-balance matrix on linear Rec.709, by column.
|
|
13
|
+
* - per zone, `{zone}_saturation`, `_contrast`, `_gamma`, `_gain`, `_offset`: the zone's values with the global ones
|
|
14
|
+
* folded in and each vector's fourth component applied to the first three, as Unreal's `ColorCorrectAll` combines
|
|
15
|
+
* them.
|
|
16
|
+
* - `zone_bounds`: `shadows_max`, `highlights_min`, `highlights_max`.
|
|
17
|
+
* - `curve_counts`: the keys of the hue, saturation and lightness curves. They follow the uniform in `grade_keys`, in
|
|
18
|
+
* that order.
|
|
19
|
+
*/
|
|
20
|
+
export const COLOR_GRADE_STRUCT = WebGPUStruct.from({
|
|
21
|
+
white_balance_c0: vec4f,
|
|
22
|
+
white_balance_c1: vec4f,
|
|
23
|
+
white_balance_c2: vec4f,
|
|
24
|
+
|
|
25
|
+
shadows_saturation: vec4f,
|
|
26
|
+
shadows_contrast: vec4f,
|
|
27
|
+
shadows_gamma: vec4f,
|
|
28
|
+
shadows_gain: vec4f,
|
|
29
|
+
shadows_offset: vec4f,
|
|
30
|
+
|
|
31
|
+
midtones_saturation: vec4f,
|
|
32
|
+
midtones_contrast: vec4f,
|
|
33
|
+
midtones_gamma: vec4f,
|
|
34
|
+
midtones_gain: vec4f,
|
|
35
|
+
midtones_offset: vec4f,
|
|
36
|
+
|
|
37
|
+
highlights_saturation: vec4f,
|
|
38
|
+
highlights_contrast: vec4f,
|
|
39
|
+
highlights_gamma: vec4f,
|
|
40
|
+
highlights_gain: vec4f,
|
|
41
|
+
highlights_offset: vec4f,
|
|
42
|
+
|
|
43
|
+
zone_bounds: vec4f,
|
|
44
|
+
curve_counts: vec4u,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Floats of {@link COLOR_GRADE_STRUCT} at the head of {@link ColorGrade#pack}'s data.
|
|
49
|
+
* @type {number}
|
|
50
|
+
*/
|
|
51
|
+
export const COLOR_GRADE_HEADER_FLOATS = 80;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Floats of one keyframe in `grade_keys`: time, value, in tangent, out tangent.
|
|
55
|
+
* @type {number}
|
|
56
|
+
*/
|
|
57
|
+
export const COLOR_GRADE_KEY_FLOATS = 4;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* One zone of Unreal's primary grade: shadows, midtones, highlights, or all of them. Each vector is RGB and a master
|
|
61
|
+
* value that scales (or, for the offset, adds to) all three.
|
|
62
|
+
*/
|
|
63
|
+
export class ColorGradeZone {
|
|
64
|
+
/**
|
|
65
|
+
* Blend between the luma and the colour; 0 is grey, 1 leaves it.
|
|
66
|
+
* @readonly
|
|
67
|
+
* @type {Vector4}
|
|
68
|
+
*/
|
|
69
|
+
saturation = new Vector4(1, 1, 1, 1);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Power about 0.18.
|
|
73
|
+
* @readonly
|
|
74
|
+
* @type {Vector4}
|
|
75
|
+
*/
|
|
76
|
+
contrast = new Vector4(1, 1, 1, 1);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The colour is raised to 1 / gamma.
|
|
80
|
+
* @readonly
|
|
81
|
+
* @type {Vector4}
|
|
82
|
+
*/
|
|
83
|
+
gamma = new Vector4(1, 1, 1, 1);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @readonly
|
|
87
|
+
* @type {Vector4}
|
|
88
|
+
*/
|
|
89
|
+
gain = new Vector4(1, 1, 1, 1);
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Added last.
|
|
93
|
+
* @readonly
|
|
94
|
+
* @type {Vector4}
|
|
95
|
+
*/
|
|
96
|
+
offset = new Vector4(0, 0, 0, 0);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const scratch_m3 = new Float64Array(9);
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @param {Float32Array} out
|
|
103
|
+
* @param {number} at float index
|
|
104
|
+
* @param {Vector4} zone
|
|
105
|
+
* @param {Vector4} global
|
|
106
|
+
*/
|
|
107
|
+
function write_product(out, at, zone, global) {
|
|
108
|
+
const master = zone[3] * global[3];
|
|
109
|
+
|
|
110
|
+
out[at] = zone[0] * global[0] * master;
|
|
111
|
+
out[at + 1] = zone[1] * global[1] * master;
|
|
112
|
+
out[at + 2] = zone[2] * global[2] * master;
|
|
113
|
+
out[at + 3] = 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @param {Float32Array} out
|
|
118
|
+
* @param {number} at float index
|
|
119
|
+
* @param {Vector4} zone
|
|
120
|
+
* @param {Vector4} global
|
|
121
|
+
*/
|
|
122
|
+
function write_sum(out, at, zone, global) {
|
|
123
|
+
const master = zone[3] + global[3];
|
|
124
|
+
|
|
125
|
+
out[at] = zone[0] + global[0] + master;
|
|
126
|
+
out[at + 1] = zone[1] + global[1] + master;
|
|
127
|
+
out[at + 2] = zone[2] + global[2] + master;
|
|
128
|
+
out[at + 3] = 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @param {Float32Array} out
|
|
133
|
+
* @param {number} at float index
|
|
134
|
+
* @param {ColorGradeZone} zone
|
|
135
|
+
* @param {ColorGradeZone} global
|
|
136
|
+
*/
|
|
137
|
+
function write_zone(out, at, zone, global) {
|
|
138
|
+
write_product(out, at, zone.saturation, global.saturation);
|
|
139
|
+
write_product(out, at + 4, zone.contrast, global.contrast);
|
|
140
|
+
write_product(out, at + 8, zone.gamma, global.gamma);
|
|
141
|
+
write_product(out, at + 12, zone.gain, global.gain);
|
|
142
|
+
write_sum(out, at + 16, zone.offset, global.offset);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @param {Float32Array} out
|
|
147
|
+
* @param {number} at float index
|
|
148
|
+
* @param {AnimationCurve} curve
|
|
149
|
+
* @returns {number} the float index after the curve's keys
|
|
150
|
+
*/
|
|
151
|
+
function write_keys(out, at, curve) {
|
|
152
|
+
const keys = curve.keys;
|
|
153
|
+
const count = keys.length;
|
|
154
|
+
|
|
155
|
+
for (let i = 0; i < count; i++) {
|
|
156
|
+
const key = keys[i];
|
|
157
|
+
|
|
158
|
+
out[at] = key.time;
|
|
159
|
+
out[at + 1] = key.value;
|
|
160
|
+
out[at + 2] = key.inTangent;
|
|
161
|
+
out[at + 3] = key.outTangent;
|
|
162
|
+
|
|
163
|
+
at += COLOR_GRADE_KEY_FLOATS;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return at;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* A colour grade on the exposed scene colour, ahead of the tone-mapping operator, baked into the tone mapper's LUTs.
|
|
171
|
+
* Neutral as constructed. In order:
|
|
172
|
+
*
|
|
173
|
+
* 1. **White balance**, Unreal's temperature white balance on linear Rec.709; see `m3_white_balance_rec709`.
|
|
174
|
+
* 2. **Primaries**, Unreal's `ColorCorrectAll` in AP1: saturation, contrast, gamma, gain and offset for {@link global},
|
|
175
|
+
* {@link shadows}, {@link midtones} and {@link highlights}, the zones blended by AP1 luma between
|
|
176
|
+
* {@link shadows_max}, {@link highlights_min} and {@link highlights_max}. Values from an Unreal project's post-process
|
|
177
|
+
* settings give the same result. The colour is clamped at zero in Rec.709 after it, as the operator takes it.
|
|
178
|
+
* 3. **Hue curves**, in OkLCh. Each curve's time is the colour's OkLCh hue in degrees, 0 to 360, and is evaluated as
|
|
179
|
+
* {@link AnimationCurve#evaluate} would; a curve with no keys does nothing. The curve holds its end keys' values
|
|
180
|
+
* outside them, so for a seamless circle key 0 and 360 with the same value and tangent.
|
|
181
|
+
* - {@link hue_shift}: degrees added to the hue.
|
|
182
|
+
* - {@link hue_saturation}: a multiplier on the chroma.
|
|
183
|
+
* - {@link hue_lightness}: stops of exposure, the light multiplied by 2^stops at the same chromaticity, weighted by
|
|
184
|
+
* the colour's saturation relative to the most saturated Rec.709 colour of its hue. A grey never moves, and a
|
|
185
|
+
* colour on the gamut's edge takes the full value.
|
|
186
|
+
* All three are read at the colour's hue before any of them applies.
|
|
187
|
+
*
|
|
188
|
+
* Read by the tone mapper every frame; any change bakes the LUTs again. A LUT the user supplies is not graded.
|
|
189
|
+
*/
|
|
190
|
+
export class ColorGrade {
|
|
191
|
+
/**
|
|
192
|
+
* Colour temperature of the white the grade makes neutral, K. 6500 does nothing.
|
|
193
|
+
* @type {number}
|
|
194
|
+
*/
|
|
195
|
+
white_temperature = WHITE_BALANCE_NEUTRAL_TEMPERATURE;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Offset of that white along its isotherm, -1 to 1 as in Unreal. 0 does nothing.
|
|
199
|
+
* @type {number}
|
|
200
|
+
*/
|
|
201
|
+
white_tint = WHITE_BALANCE_NEUTRAL_TINT;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Applies in every zone, under the zone's own values.
|
|
205
|
+
* @readonly
|
|
206
|
+
* @type {ColorGradeZone}
|
|
207
|
+
*/
|
|
208
|
+
global = new ColorGradeZone();
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @readonly
|
|
212
|
+
* @type {ColorGradeZone}
|
|
213
|
+
*/
|
|
214
|
+
shadows = new ColorGradeZone();
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* @readonly
|
|
218
|
+
* @type {ColorGradeZone}
|
|
219
|
+
*/
|
|
220
|
+
midtones = new ColorGradeZone();
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @readonly
|
|
224
|
+
* @type {ColorGradeZone}
|
|
225
|
+
*/
|
|
226
|
+
highlights = new ColorGradeZone();
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* AP1 luma at which the shadows' weight reaches 0. Unreal's default.
|
|
230
|
+
* @type {number}
|
|
231
|
+
*/
|
|
232
|
+
shadows_max = 0.09;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* AP1 luma at which the highlights' weight starts to rise from 0. Unreal's default.
|
|
236
|
+
* @type {number}
|
|
237
|
+
*/
|
|
238
|
+
highlights_min = 0.5;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* AP1 luma at which the highlights' weight reaches 1. Unreal's default.
|
|
242
|
+
* @type {number}
|
|
243
|
+
*/
|
|
244
|
+
highlights_max = 1;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Degrees added to the OkLCh hue, against the hue in degrees.
|
|
248
|
+
* @readonly
|
|
249
|
+
* @type {AnimationCurve}
|
|
250
|
+
*/
|
|
251
|
+
hue_shift = new AnimationCurve();
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Multiplier on the OkLCh chroma, against the hue in degrees.
|
|
255
|
+
* @readonly
|
|
256
|
+
* @type {AnimationCurve}
|
|
257
|
+
*/
|
|
258
|
+
hue_saturation = new AnimationCurve();
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Stops of exposure, against the hue in degrees.
|
|
262
|
+
* @readonly
|
|
263
|
+
* @type {AnimationCurve}
|
|
264
|
+
*/
|
|
265
|
+
hue_lightness = new AnimationCurve();
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @type {Float32Array}
|
|
269
|
+
*/
|
|
270
|
+
#data = new Float32Array(COLOR_GRADE_HEADER_FLOATS + COLOR_GRADE_KEY_FLOATS);
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* {@link #data}'s words, for the curve counts.
|
|
274
|
+
* @type {Uint32Array}
|
|
275
|
+
*/
|
|
276
|
+
#words = new Uint32Array(this.#data.buffer);
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* The grade as the bake reads it: {@link COLOR_GRADE_STRUCT}, then the three curves' keys, each
|
|
280
|
+
* {@link COLOR_GRADE_KEY_FLOATS} floats, with room for one key when there are none. The array is reused while the
|
|
281
|
+
* key count stays the same.
|
|
282
|
+
*
|
|
283
|
+
* @returns {Float32Array}
|
|
284
|
+
*/
|
|
285
|
+
pack() {
|
|
286
|
+
assert.isNumber(this.white_temperature, 'white_temperature');
|
|
287
|
+
assert.greaterThan(this.white_temperature, 0, 'white_temperature');
|
|
288
|
+
assert.isNumber(this.white_tint, 'white_tint');
|
|
289
|
+
|
|
290
|
+
const hue_count = this.hue_shift.keys.length;
|
|
291
|
+
const saturation_count = this.hue_saturation.keys.length;
|
|
292
|
+
const lightness_count = this.hue_lightness.keys.length;
|
|
293
|
+
|
|
294
|
+
const length = COLOR_GRADE_HEADER_FLOATS
|
|
295
|
+
+ COLOR_GRADE_KEY_FLOATS * Math.max(1, hue_count + saturation_count + lightness_count);
|
|
296
|
+
|
|
297
|
+
if (this.#data.length !== length) {
|
|
298
|
+
this.#data = new Float32Array(length);
|
|
299
|
+
this.#words = new Uint32Array(this.#data.buffer);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const out = this.#data;
|
|
303
|
+
|
|
304
|
+
m3_white_balance_rec709(scratch_m3, this.white_temperature, this.white_tint);
|
|
305
|
+
|
|
306
|
+
for (let column = 0; column < 3; column++) {
|
|
307
|
+
out[column * 4] = scratch_m3[column];
|
|
308
|
+
out[column * 4 + 1] = scratch_m3[3 + column];
|
|
309
|
+
out[column * 4 + 2] = scratch_m3[6 + column];
|
|
310
|
+
out[column * 4 + 3] = 0;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
write_zone(out, 12, this.shadows, this.global);
|
|
314
|
+
write_zone(out, 32, this.midtones, this.global);
|
|
315
|
+
write_zone(out, 52, this.highlights, this.global);
|
|
316
|
+
|
|
317
|
+
out[72] = this.shadows_max;
|
|
318
|
+
out[73] = this.highlights_min;
|
|
319
|
+
out[74] = this.highlights_max;
|
|
320
|
+
out[75] = 0;
|
|
321
|
+
|
|
322
|
+
const words = this.#words;
|
|
323
|
+
words[76] = hue_count;
|
|
324
|
+
words[77] = saturation_count;
|
|
325
|
+
words[78] = lightness_count;
|
|
326
|
+
words[79] = 0;
|
|
327
|
+
|
|
328
|
+
let at = COLOR_GRADE_HEADER_FLOATS;
|
|
329
|
+
at = write_keys(out, at, this.hue_shift);
|
|
330
|
+
at = write_keys(out, at, this.hue_saturation);
|
|
331
|
+
at = write_keys(out, at, this.hue_lightness);
|
|
332
|
+
|
|
333
|
+
out.fill(0, at);
|
|
334
|
+
|
|
335
|
+
return out;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trilinear over a tone-mapping LUT. Clamp-to-edge, so a coordinate on the outer texel centres reads that texel
|
|
3
|
+
* alone; the LUT has no mips.
|
|
4
|
+
*
|
|
5
|
+
* @type {Readonly<SamplerDescriptor>}
|
|
6
|
+
*/
|
|
7
|
+
export const SAMPLER_TONEMAP_LUT: Readonly<SamplerDescriptor>;
|
|
8
|
+
import { SamplerDescriptor } from "../../../descriptor/texture/SamplerDescriptor.js";
|
|
9
|
+
//# sourceMappingURL=SAMPLER_TONEMAP_LUT.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SAMPLER_TONEMAP_LUT.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,kCAFU,SAAS,iBAAiB,CAAC,CAQjC;kCAd8B,kDAAkD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SamplerDescriptor } from "../../../descriptor/texture/SamplerDescriptor.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Trilinear over a tone-mapping LUT. Clamp-to-edge, so a coordinate on the outer texel centres reads that texel
|
|
5
|
+
* alone; the LUT has no mips.
|
|
6
|
+
*
|
|
7
|
+
* @type {Readonly<SamplerDescriptor>}
|
|
8
|
+
*/
|
|
9
|
+
export const SAMPLER_TONEMAP_LUT = Object.freeze(SamplerDescriptor.from({
|
|
10
|
+
magFilter: "linear",
|
|
11
|
+
minFilter: "linear",
|
|
12
|
+
addressModeU: "clamp-to-edge",
|
|
13
|
+
addressModeV: "clamp-to-edge",
|
|
14
|
+
addressModeW: "clamp-to-edge",
|
|
15
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TONE_MAP_OPERATOR_ACES.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.js"],"names":[],"mappings":"AAgFA;;GAEG;AACH,qCAFU,eAAe,CAEuC;gCAzEhC,sBAAsB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { chunk_CRM_FROM_REC709_TO_REC2020 } from "../../shader/chunk/color/conversion/chunk_CRM_FROM_REC709_TO_REC2020.js";
|
|
2
|
+
import { ACES2_BLOCK_FLOATS } from "../../shader/chunk/color/tonemap/aces/aces2_transform_block.js";
|
|
3
|
+
import { chunk_aces2_output_transform } from "../../shader/chunk/color/tonemap/aces/chunk_aces2_output_transform.js";
|
|
4
|
+
import { chunk_tonemap_ue_filmic } from "../../shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.js";
|
|
5
|
+
import { chunk_PAPER_WHITE_NITS, PAPER_WHITE_NITS } from "../../shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js";
|
|
6
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
7
|
+
import { graph_import_raw_buffer } from "../../shader/graph/graph_import_raw_buffer.js";
|
|
8
|
+
import { f32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
9
|
+
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
10
|
+
import { TonemapAces2Tables } from "./TonemapAces2Tables.js";
|
|
11
|
+
import { ToneMapOperator } from "./ToneMapOperator.js";
|
|
12
|
+
|
|
13
|
+
const chunk = CodeChunk.from(
|
|
14
|
+
//language=WGSL
|
|
15
|
+
`
|
|
16
|
+
const ACES2_SDR_BLOCK: u32 = 0u;
|
|
17
|
+
const ACES2_DISPLAY_BLOCK: u32 = ${ACES2_BLOCK_FLOATS}u;
|
|
18
|
+
|
|
19
|
+
fn tone_map_operator(scene: vec3<f32>, peak_nits: f32) -> vec3<f32> {
|
|
20
|
+
// the SDR picture first, which is what Unreal 5.8 does with Filmic on any display
|
|
21
|
+
var picture = tonemap_ue_filmic(scene);
|
|
22
|
+
|
|
23
|
+
if (peak_nits > PAPER_WHITE_NITS) {
|
|
24
|
+
// back to the scene through ACES 2.0 at SDR white, then out again through ACES 2.0 at the display's peak over
|
|
25
|
+
// the paper white. Both transforms take SDR white for 100 cd/m² and both are limited to Rec.709, the SDR
|
|
26
|
+
// picture's own gamut, so as the headroom shrinks to none the picture becomes the SDR one.
|
|
27
|
+
picture = aces2_forward(ACES2_DISPLAY_BLOCK, aces2_inverse(ACES2_SDR_BLOCK, picture));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return CRM_FROM_REC709_TO_REC2020 * picture;
|
|
31
|
+
}
|
|
32
|
+
`, [
|
|
33
|
+
chunk_tonemap_ue_filmic,
|
|
34
|
+
chunk_aces2_output_transform,
|
|
35
|
+
chunk_CRM_FROM_REC709_TO_REC2020,
|
|
36
|
+
chunk_PAPER_WHITE_NITS,
|
|
37
|
+
]
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Unreal Engine's default look, the tone mapper's default too.
|
|
42
|
+
*
|
|
43
|
+
* - **SDR** is UE's "Filmic" tone mapper at its default settings, the ACES-derived curve every Unreal title ships with
|
|
44
|
+
* unless it chose otherwise.
|
|
45
|
+
* - **HDR** is what Unreal 5.8 does with the same method: the SDR picture, taken back to the scene through the inverse
|
|
46
|
+
* ACES 2.0 output transform for an SDR display, and rendered again with the ACES 2.0 output transform for the
|
|
47
|
+
* display's headroom, both limited to Rec.709. A display at or under the paper white shows the SDR picture.
|
|
48
|
+
*
|
|
49
|
+
* An exposed 0.18 shows at 0.18 of SDR white, with a mid-tone contrast of 1.36 against GT7's 1.05. On HDR the picture
|
|
50
|
+
* expands into the headroom and mid-grey rises with it, by ACES 2.0's design: 0.26 of SDR white at 1000 cd/m².
|
|
51
|
+
*
|
|
52
|
+
* Binds `aces2_tables`, the two transforms' parameters and gamut tables, built by {@link TonemapAces2Tables} for the
|
|
53
|
+
* peak of each HDR bake.
|
|
54
|
+
*/
|
|
55
|
+
class ToneMapOperatorAces extends ToneMapOperator {
|
|
56
|
+
#tables = new TonemapAces2Tables();
|
|
57
|
+
|
|
58
|
+
constructor() {
|
|
59
|
+
super("aces", chunk);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare(group) {
|
|
63
|
+
group.addStorageBuffer("aces2_tables", WebGPUArray.from(f32));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
bind(graph, peak_nits, bindings) {
|
|
67
|
+
// an SDR bake never reads the tables, so they are not built for it
|
|
68
|
+
if (peak_nits > PAPER_WHITE_NITS) {
|
|
69
|
+
this.#tables.update(peak_nits);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
bindings.aces2_tables = graph_import_raw_buffer({
|
|
73
|
+
graph,
|
|
74
|
+
value: this.#tables.data.buffer,
|
|
75
|
+
label: "tonemap/aces2 tables",
|
|
76
|
+
usage: GPUBufferUsage.STORAGE,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @type {ToneMapOperator}
|
|
83
|
+
*/
|
|
84
|
+
export const TONE_MAP_OPERATOR_ACES = new ToneMapOperatorAces();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GT7 tone mapping (Polyphony Digital, SIGGRAPH 2025), in its own Rec.2020. An exposed 1.0 shows at the paper white
|
|
3
|
+
* on every display. On SDR the peak is the paper white, the curve's SDR mode, which clips there; HDR rolls off to the
|
|
4
|
+
* display's peak.
|
|
5
|
+
*
|
|
6
|
+
* @type {ToneMapOperator}
|
|
7
|
+
*/
|
|
8
|
+
export const TONE_MAP_OPERATOR_GT7: ToneMapOperator;
|
|
9
|
+
import { ToneMapOperator } from "./ToneMapOperator.js";
|
|
10
|
+
//# sourceMappingURL=TONE_MAP_OPERATOR_GT7.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TONE_MAP_OPERATOR_GT7.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.js"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,oCAFU,eAAe,CAatB;gCApB6B,sBAAsB"}
|