@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.
Files changed (148) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/package.json +1 -1
  3. package/src/core/color/xyz/m3_chromatic_adaptation_bradford.d.ts +14 -0
  4. package/src/core/color/xyz/m3_chromatic_adaptation_bradford.d.ts.map +1 -0
  5. package/src/core/color/xyz/m3_chromatic_adaptation_bradford.js +51 -0
  6. package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts +2 -1
  7. package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts.map +1 -1
  8. package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +51 -70
  9. package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts.map +1 -1
  10. package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.js +8 -64
  11. package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.d.ts +17 -0
  12. package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.d.ts.map +1 -0
  13. package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.js +64 -0
  14. package/src/core/math/linalg/solve_box_constrained_qp.d.ts +30 -0
  15. package/src/core/math/linalg/solve_box_constrained_qp.d.ts.map +1 -0
  16. package/src/core/math/linalg/solve_box_constrained_qp.js +205 -0
  17. package/src/engine/physics/constraint/soft_spring_coefficients.d.ts +24 -0
  18. package/src/engine/physics/constraint/soft_spring_coefficients.d.ts.map +1 -0
  19. package/src/engine/physics/constraint/soft_spring_coefficients.js +38 -0
  20. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  21. package/src/engine/physics/constraint/solve_constraints.js +16 -8
  22. package/src/engine/physics/ecs/PhysicsSystem.d.ts +54 -0
  23. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  24. package/src/engine/physics/ecs/PhysicsSystem.js +192 -7
  25. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  26. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +3 -5
  27. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
  28. package/src/engine/physics/inertia/world_inverse_inertia.js +3 -5
  29. package/src/engine/physics/vehicle/RaycastVehicle.d.ts +183 -12
  30. package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
  31. package/src/engine/physics/vehicle/RaycastVehicle.js +1046 -121
  32. package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts +17 -0
  33. package/src/shade/device/mock/SoftwareGPUCommandEncoder.d.ts.map +1 -1
  34. package/src/shade/device/mock/SoftwareGPUCommandEncoder.js +46 -0
  35. package/src/shade/playground/tonemap_sdr/README.md +11 -8
  36. package/src/shade/playground/tonemap_sdr/ToneMapCompare.js +2 -2
  37. package/src/shade/renderer/Renderer.d.ts +5 -6
  38. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  39. package/src/shade/renderer/Renderer.js +15 -88
  40. package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.d.ts +14 -0
  41. package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.d.ts.map +1 -0
  42. package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.js +62 -0
  43. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +12 -0
  44. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  45. package/src/shade/renderer/buffer/table/GPUDatabase.js +85 -0
  46. package/src/shade/renderer/buffer/table/GPUDatabaseDefinition.d.ts +2 -1
  47. package/src/shade/renderer/buffer/table/GPUDatabaseDefinition.d.ts.map +1 -1
  48. package/src/shade/renderer/buffer/table/GPUDatabaseDefinition.js +2 -1
  49. package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts +158 -0
  50. package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -0
  51. package/src/shade/renderer/deferred/tonemap/ColorGrade.js +337 -0
  52. package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.d.ts +9 -0
  53. package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.d.ts.map +1 -0
  54. package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.js +15 -0
  55. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.d.ts +6 -0
  56. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.d.ts.map +1 -0
  57. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.js +84 -0
  58. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.d.ts +10 -0
  59. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.d.ts.map +1 -0
  60. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.js +25 -0
  61. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.d.ts +9 -0
  62. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.d.ts.map +1 -0
  63. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.js +20 -0
  64. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.d.ts +14 -0
  65. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.d.ts.map +1 -0
  66. package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.js +30 -0
  67. package/src/shade/renderer/deferred/tonemap/ToneMapOperator.d.ts +54 -0
  68. package/src/shade/renderer/deferred/tonemap/ToneMapOperator.d.ts.map +1 -0
  69. package/src/shade/renderer/deferred/tonemap/ToneMapOperator.js +63 -0
  70. package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts +106 -0
  71. package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts.map +1 -0
  72. package/src/shade/renderer/deferred/tonemap/ToneMapper.js +474 -0
  73. package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts +5 -13
  74. package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts.map +1 -1
  75. package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.js +5 -44
  76. package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.d.ts +7 -25
  77. package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.d.ts.map +1 -1
  78. package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.js +11 -51
  79. package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.d.ts +20 -0
  80. package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.d.ts.map +1 -0
  81. package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.js +103 -0
  82. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts +9 -0
  83. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts.map +1 -0
  84. package/src/shade/renderer/deferred/tonemap/{shader_tonemap_HDR_none.js → shader_tonemap_HDR_lut.js} +22 -18
  85. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts +9 -0
  86. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts.map +1 -0
  87. package/src/shade/renderer/deferred/tonemap/{shader_tonemap_LDR_aces.js → shader_tonemap_LDR_lut.js} +24 -24
  88. package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.d.ts +23 -0
  89. package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.d.ts.map +1 -0
  90. package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.js +92 -0
  91. package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.d.ts +15 -0
  92. package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.d.ts.map +1 -0
  93. package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.js +73 -0
  94. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  95. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  96. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  97. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  98. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  99. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +1 -1
  100. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  101. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  102. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts +22 -0
  103. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts.map +1 -0
  104. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.js +62 -0
  105. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts +13 -0
  106. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts.map +1 -0
  107. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.js +140 -0
  108. package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.d.ts +11 -0
  109. package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.d.ts.map +1 -0
  110. package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.js +65 -0
  111. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.d.ts +14 -0
  112. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.d.ts.map +1 -0
  113. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.js +38 -0
  114. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.d.ts +16 -0
  115. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.d.ts.map +1 -0
  116. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.js +41 -0
  117. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  118. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -8
  119. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  120. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
  121. package/src/shade/renderer/ShadeToneMappingMode.d.ts +0 -15
  122. package/src/shade/renderer/ShadeToneMappingMode.d.ts.map +0 -1
  123. package/src/shade/renderer/ShadeToneMappingMode.js +0 -41
  124. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.d.ts +0 -9
  125. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.d.ts.map +0 -1
  126. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.js +0 -79
  127. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts +0 -17
  128. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts.map +0 -1
  129. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.js +0 -101
  130. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_none.d.ts +0 -9
  131. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_none.d.ts.map +0 -1
  132. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.d.ts +0 -10
  133. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.d.ts.map +0 -1
  134. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.js +0 -80
  135. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.d.ts +0 -9
  136. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.d.ts.map +0 -1
  137. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.js +0 -80
  138. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts +0 -10
  139. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts.map +0 -1
  140. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.d.ts +0 -9
  141. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.d.ts.map +0 -1
  142. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.js +0 -71
  143. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.d.ts +0 -10
  144. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.d.ts.map +0 -1
  145. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.js +0 -76
  146. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_hdr_bt2390.d.ts +0 -3
  147. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_hdr_bt2390.d.ts.map +0 -1
  148. 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8CG;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;wCA5fuC,8BAA8B;6BAFzC,mBAAmB;8BAClB,oBAAoB"}
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,6 @@
1
+ /**
2
+ * @type {ToneMapOperator}
3
+ */
4
+ export const TONE_MAP_OPERATOR_ACES: ToneMapOperator;
5
+ import { ToneMapOperator } from "./ToneMapOperator.js";
6
+ //# sourceMappingURL=TONE_MAP_OPERATOR_ACES.d.ts.map
@@ -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"}