@woosh/meep-engine 3.64.1 → 3.67.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 (372) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/build/bundle-worker-image-decoder.js +1 -1
  3. package/build/bundle-worker-terrain.js +1 -1
  4. package/package.json +1 -1
  5. package/src/core/binary/BinaryBuffer.d.ts +5 -0
  6. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  7. package/src/core/binary/BinaryBuffer.js +39 -5
  8. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts +65 -6
  9. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts.map +1 -1
  10. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +451 -101
  11. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +4 -2
  12. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -1
  13. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +4 -2
  14. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts +8 -1
  15. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts.map +1 -1
  16. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +45 -10
  17. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
  18. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +237 -119
  19. package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts +143 -0
  20. package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts.map +1 -0
  21. package/src/engine/graphics/ecs/grass/GrassSpecies.js +189 -0
  22. package/src/engine/graphics/ecs/grass/GrassSurface.d.ts +25 -0
  23. package/src/engine/graphics/ecs/grass/GrassSurface.d.ts.map +1 -0
  24. package/src/engine/graphics/ecs/grass/GrassSurface.js +32 -0
  25. package/src/engine/graphics/ecs/grass/GroundCover.d.ts +68 -0
  26. package/src/engine/graphics/ecs/grass/GroundCover.d.ts.map +1 -0
  27. package/src/engine/graphics/ecs/grass/GroundCover.js +85 -0
  28. package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
  29. package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
  30. package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
  31. package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
  32. package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
  33. package/src/engine/graphics3/GroundCoverSystem.js +58 -0
  34. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  35. package/src/engine/network/NetworkSession.js +372 -110
  36. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  37. package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
  38. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  39. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
  40. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  41. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
  42. package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
  43. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  44. package/src/engine/network/sim/SimActionExecutor.js +65 -9
  45. package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
  46. package/src/engine/network/state/PredictionHistory.js +6 -1
  47. package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
  48. package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
  49. package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
  50. package/src/engine/network/time/RenderPlayout.d.ts +23 -3
  51. package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
  52. package/src/engine/network/time/RenderPlayout.js +40 -4
  53. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  54. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
  55. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
  56. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
  57. package/src/format/lut/cube/CubeLut.d.ts +38 -0
  58. package/src/format/lut/cube/CubeLut.d.ts.map +1 -0
  59. package/src/format/lut/cube/CubeLut.js +23 -0
  60. package/src/format/lut/cube/cube_read.d.ts +23 -0
  61. package/src/format/lut/cube/cube_read.d.ts.map +1 -0
  62. package/src/format/lut/cube/cube_read.js +199 -0
  63. package/src/format/lut/cube/cube_write.d.ts +15 -0
  64. package/src/format/lut/cube/cube_write.d.ts.map +1 -0
  65. package/src/format/lut/cube/cube_write.js +90 -0
  66. package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
  67. package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
  68. package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
  69. package/src/shade/playground/grass_surfaces/index.html +75 -0
  70. package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
  71. package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
  72. package/src/shade/playground/grass_surfaces/main.js +593 -0
  73. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
  74. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
  75. package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
  76. package/src/shade/playground/probe_clipmap/README.md +1 -0
  77. package/src/shade/playground/probe_clipmap/index.html +5 -0
  78. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
  79. package/src/shade/playground/probe_clipmap/main.js +7 -0
  80. package/src/shade/playground/probe_clipmap_box/README.md +5 -1
  81. package/src/shade/playground/probe_clipmap_box/index.html +12 -0
  82. package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
  83. package/src/shade/playground/probe_clipmap_box/main.js +15 -0
  84. package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
  85. package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
  86. package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
  87. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  88. package/src/shade/renderer/Renderer.js +59 -55
  89. package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts +73 -4
  90. package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -1
  91. package/src/shade/renderer/deferred/tonemap/ColorGrade.js +113 -7
  92. package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.d.ts +12 -0
  93. package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.d.ts.map +1 -0
  94. package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.js +12 -0
  95. package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts +15 -1
  96. package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts.map +1 -1
  97. package/src/shade/renderer/deferred/tonemap/ToneMapper.js +31 -3
  98. package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.d.ts +25 -0
  99. package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.d.ts.map +1 -0
  100. package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.js +51 -0
  101. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts +2 -2
  102. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts.map +1 -1
  103. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.js +6 -3
  104. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts +3 -2
  105. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts.map +1 -1
  106. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.js +7 -3
  107. package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
  108. package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
  109. package/src/shade/renderer/extension/ViewTextures.js +19 -5
  110. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
  111. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
  112. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
  113. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
  114. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
  115. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
  116. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
  117. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  118. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
  119. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
  120. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
  121. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
  122. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
  123. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
  124. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
  125. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
  126. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  127. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
  128. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
  129. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
  130. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
  131. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
  132. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  133. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
  134. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
  135. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
  136. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
  137. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
  138. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
  139. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
  140. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
  141. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
  142. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
  143. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
  144. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
  145. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
  146. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
  147. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
  148. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
  149. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  150. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
  151. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -1
  152. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  153. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -2
  154. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
  155. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
  156. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
  157. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  158. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +3 -1
  159. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
  160. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
  161. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
  162. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
  163. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
  164. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
  165. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
  166. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
  167. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
  168. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  169. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
  170. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
  171. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
  172. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
  173. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
  174. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
  175. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
  176. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
  177. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
  178. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
  179. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
  180. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
  181. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
  182. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
  183. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
  184. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
  185. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
  186. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
  187. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
  188. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  189. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
  190. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
  191. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
  192. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
  193. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
  194. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
  195. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
  196. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
  197. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
  198. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
  199. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
  200. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
  201. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
  202. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
  203. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
  204. package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
  205. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
  206. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
  207. package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
  208. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
  209. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
  210. package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
  211. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
  212. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
  213. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
  214. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
  215. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
  216. package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
  217. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
  218. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
  219. package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
  220. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
  221. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
  222. package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
  223. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
  224. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
  225. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
  226. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
  227. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
  228. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
  229. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
  230. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
  231. package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
  232. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
  233. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
  234. package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
  235. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
  236. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
  237. package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
  238. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
  239. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
  240. package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
  241. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
  242. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
  243. package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
  244. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
  245. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
  246. package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
  247. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
  248. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
  249. package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
  250. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
  251. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
  252. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
  253. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
  254. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
  255. package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
  256. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
  257. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
  258. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
  259. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
  260. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
  261. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
  262. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
  263. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
  264. package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
  265. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
  266. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
  267. package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
  268. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
  269. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
  270. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
  271. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
  272. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
  273. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
  274. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
  275. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
  276. package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
  277. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
  278. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
  279. package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
  280. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
  281. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
  282. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
  283. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
  284. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
  285. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
  286. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
  287. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
  288. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
  289. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
  290. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
  291. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
  292. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
  293. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
  294. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
  295. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
  296. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
  297. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
  298. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
  299. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
  300. package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
  301. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
  302. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
  303. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
  304. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +35 -9
  305. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  306. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +81 -11
  307. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.d.ts.map +1 -1
  308. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.js +4 -1
  309. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  310. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
  311. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
  312. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
  313. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
  314. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  315. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
  316. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  317. package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
  318. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
  319. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
  320. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
  321. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
  322. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
  323. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
  324. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
  325. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
  326. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts +6 -0
  327. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts.map +1 -1
  328. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.js +7 -0
  329. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts +4 -4
  330. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts.map +1 -1
  331. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.js +86 -5
  332. package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.d.ts +65 -0
  333. package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.d.ts.map +1 -0
  334. package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.js +136 -0
  335. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
  336. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
  337. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
  338. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
  339. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
  340. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
  341. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
  342. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
  343. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
  344. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
  345. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
  346. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
  347. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  348. package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
  349. package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
  350. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
  351. package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
  352. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
  353. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
  354. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
  355. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
  356. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
  357. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
  358. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
  359. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
  360. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
  361. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
  362. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
  363. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
  364. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
  365. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
  366. package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
  367. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
  368. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  369. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
  370. package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.d.ts +0 -11
  371. package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.d.ts.map +0 -1
  372. package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.js +0 -56
@@ -9,6 +9,10 @@
9
9
  * - `zone_bounds`: `shadows_max`, `highlights_min`, `highlights_max`.
10
10
  * - `curve_counts`: the keys of the hue, saturation and lightness curves. They follow the uniform in `grade_keys`, in
11
11
  * that order.
12
+ * - `luma_curve_counts`: the keys of the red, green, blue and all-channel saturation-against-luma curves. They follow
13
+ * the hue curves' keys in `grade_keys`, in that order.
14
+ * - `luma_gain_counts`: the keys of the red, green and blue gain-against-luma curves and the exposure-against-luma
15
+ * curve. They follow the saturation-against-luma curves' keys in `grade_keys`, in that order.
12
16
  */
13
17
  export const COLOR_GRADE_STRUCT: WebGPUStruct;
14
18
  /**
@@ -64,8 +68,20 @@ export class ColorGradeZone {
64
68
  * 2. **Primaries**, Unreal's `ColorCorrectAll` in AP1: saturation, contrast, gamma, gain and offset for {@link global},
65
69
  * {@link shadows}, {@link midtones} and {@link highlights}, the zones blended by AP1 luma between
66
70
  * {@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
71
+ * settings give the same result.
72
+ * 3. **Gain against luma**, in AP1 after the primaries: each channel multiplied by its gain at the colour's AP1 luma's
73
+ * stops from middle grey — {@link luma_gain_red}, {@link luma_gain_green}, {@link luma_gain_blue} — and every channel
74
+ * by 2 to the power of {@link luma_exposure} there. Grading by tonal range at any luma, with any blend between ranges:
75
+ * a range that fades in and out over spans of stops, as a smoothstep does, is a cubic between its edges, so ranges
76
+ * sum exactly into curves keyed at their edges. A curve with no keys is a gain of 1, or an exposure of 0. Clamped at
77
+ * zero.
78
+ * 4. **Saturation against luma**, after the gain against luma: each channel drawn away from the colour's AP1 luma by its
79
+ * factor at that luma's stops from middle grey, `log2(luma / 0.18)`: {@link luma_saturation} times the channel's
80
+ * own curve — {@link luma_saturation_red}, {@link luma_saturation_green}, {@link luma_saturation_blue}. Unreal's
81
+ * saturation and per-channel saturation, varying across the tonal range. Each curve is evaluated as
82
+ * {@link AnimationCurve#evaluate} would and holds its end keys' values beyond them; a curve with no keys is a factor
83
+ * of 1, and a colour with no luma is left as it is. Clamped at zero, as the primaries' saturation is. The colour is clamped at zero in Rec.709 after it, as the operator takes it.
84
+ * 5. **Hue curves**, in OkLCh. Each curve's time is the colour's OkLCh hue in degrees, 0 to 360, and is evaluated as
69
85
  * {@link AnimationCurve#evaluate} would; a curve with no keys does nothing. The curve holds its end keys' values
70
86
  * outside them, so for a seamless circle key 0 and 360 with the same value and tangent.
71
87
  * - {@link hue_shift}: degrees added to the hue.
@@ -143,8 +159,61 @@ export class ColorGrade {
143
159
  */
144
160
  readonly hue_lightness: AnimationCurve;
145
161
  /**
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
162
+ * Saturation of every channel against the colour's AP1 luma in stops from middle grey: 1 leaves it, 0 draws it to
163
+ * the luma. Each channel's own curve multiplies it.
164
+ * @readonly
165
+ * @type {AnimationCurve}
166
+ */
167
+ readonly luma_saturation: AnimationCurve;
168
+ /**
169
+ * Saturation of the red channel against the colour's AP1 luma in stops from middle grey, times
170
+ * {@link luma_saturation}.
171
+ * @readonly
172
+ * @type {AnimationCurve}
173
+ */
174
+ readonly luma_saturation_red: AnimationCurve;
175
+ /**
176
+ * Saturation of the green channel against the colour's AP1 luma in stops from middle grey, times
177
+ * {@link luma_saturation}.
178
+ * @readonly
179
+ * @type {AnimationCurve}
180
+ */
181
+ readonly luma_saturation_green: AnimationCurve;
182
+ /**
183
+ * Saturation of the blue channel against the colour's AP1 luma in stops from middle grey, times
184
+ * {@link luma_saturation}.
185
+ * @readonly
186
+ * @type {AnimationCurve}
187
+ */
188
+ readonly luma_saturation_blue: AnimationCurve;
189
+ /**
190
+ * Gain of the red channel against the colour's AP1 luma in stops from middle grey: 1 leaves it.
191
+ * @readonly
192
+ * @type {AnimationCurve}
193
+ */
194
+ readonly luma_gain_red: AnimationCurve;
195
+ /**
196
+ * Gain of the green channel against the colour's AP1 luma in stops from middle grey: 1 leaves it.
197
+ * @readonly
198
+ * @type {AnimationCurve}
199
+ */
200
+ readonly luma_gain_green: AnimationCurve;
201
+ /**
202
+ * Gain of the blue channel against the colour's AP1 luma in stops from middle grey: 1 leaves it.
203
+ * @readonly
204
+ * @type {AnimationCurve}
205
+ */
206
+ readonly luma_gain_blue: AnimationCurve;
207
+ /**
208
+ * Exposure of every channel against the colour's AP1 luma in stops from middle grey, in stops: 0 leaves it.
209
+ * @readonly
210
+ * @type {AnimationCurve}
211
+ */
212
+ readonly luma_exposure: AnimationCurve;
213
+ /**
214
+ * The grade as the bake reads it: {@link COLOR_GRADE_STRUCT}, then the three hue curves' keys, the four
215
+ * saturation-against-luma curves' keys (red, green, blue, all) and the four gain-against-luma curves' keys (red,
216
+ * green, blue, exposure), each {@link COLOR_GRADE_KEY_FLOATS} floats, with room for one key when there are none. The array is reused while the
148
217
  * key count stays the same.
149
218
  *
150
219
  * @returns {Float32Array}
@@ -1 +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"}
1
+ {"version":3,"file":"ColorGrade.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/ColorGrade.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;GAeG;AACH,8CA2BG;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;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;IAErC;;;;;OAKG;IACH,0BAFU,cAAc,CAEe;IAEvC;;;;;OAKG;IACH,8BAFU,cAAc,CAEmB;IAE3C;;;;;OAKG;IACH,gCAFU,cAAc,CAEqB;IAE7C;;;;;OAKG;IACH,+BAFU,cAAc,CAEoB;IAE5C;;;;OAIG;IACH,wBAFU,cAAc,CAEa;IAErC;;;;OAIG;IACH,0BAFU,cAAc,CAEe;IAEvC;;;;OAIG;IACH,yBAFU,cAAc,CAEc;IAEtC;;;;OAIG;IACH,wBAFU,cAAc,CAEa;IAarC;;;;;;;OAOG;IACH,QAFa,YAAY,CAgFxB;;CACJ;6BAtb4B,mCAAmC;wBAHxC,kCAAkC;+BAC3B,sDAAsD"}
@@ -16,6 +16,10 @@ import { m3_white_balance_rec709, WHITE_BALANCE_NEUTRAL_TEMPERATURE, WHITE_BALAN
16
16
  * - `zone_bounds`: `shadows_max`, `highlights_min`, `highlights_max`.
17
17
  * - `curve_counts`: the keys of the hue, saturation and lightness curves. They follow the uniform in `grade_keys`, in
18
18
  * that order.
19
+ * - `luma_curve_counts`: the keys of the red, green, blue and all-channel saturation-against-luma curves. They follow
20
+ * the hue curves' keys in `grade_keys`, in that order.
21
+ * - `luma_gain_counts`: the keys of the red, green and blue gain-against-luma curves and the exposure-against-luma
22
+ * curve. They follow the saturation-against-luma curves' keys in `grade_keys`, in that order.
19
23
  */
20
24
  export const COLOR_GRADE_STRUCT = WebGPUStruct.from({
21
25
  white_balance_c0: vec4f,
@@ -42,13 +46,15 @@ export const COLOR_GRADE_STRUCT = WebGPUStruct.from({
42
46
 
43
47
  zone_bounds: vec4f,
44
48
  curve_counts: vec4u,
49
+ luma_curve_counts: vec4u,
50
+ luma_gain_counts: vec4u,
45
51
  });
46
52
 
47
53
  /**
48
54
  * Floats of {@link COLOR_GRADE_STRUCT} at the head of {@link ColorGrade#pack}'s data.
49
55
  * @type {number}
50
56
  */
51
- export const COLOR_GRADE_HEADER_FLOATS = 80;
57
+ export const COLOR_GRADE_HEADER_FLOATS = 88;
52
58
 
53
59
  /**
54
60
  * Floats of one keyframe in `grade_keys`: time, value, in tangent, out tangent.
@@ -174,8 +180,20 @@ function write_keys(out, at, curve) {
174
180
  * 2. **Primaries**, Unreal's `ColorCorrectAll` in AP1: saturation, contrast, gamma, gain and offset for {@link global},
175
181
  * {@link shadows}, {@link midtones} and {@link highlights}, the zones blended by AP1 luma between
176
182
  * {@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
183
+ * settings give the same result.
184
+ * 3. **Gain against luma**, in AP1 after the primaries: each channel multiplied by its gain at the colour's AP1 luma's
185
+ * stops from middle grey — {@link luma_gain_red}, {@link luma_gain_green}, {@link luma_gain_blue} — and every channel
186
+ * by 2 to the power of {@link luma_exposure} there. Grading by tonal range at any luma, with any blend between ranges:
187
+ * a range that fades in and out over spans of stops, as a smoothstep does, is a cubic between its edges, so ranges
188
+ * sum exactly into curves keyed at their edges. A curve with no keys is a gain of 1, or an exposure of 0. Clamped at
189
+ * zero.
190
+ * 4. **Saturation against luma**, after the gain against luma: each channel drawn away from the colour's AP1 luma by its
191
+ * factor at that luma's stops from middle grey, `log2(luma / 0.18)`: {@link luma_saturation} times the channel's
192
+ * own curve — {@link luma_saturation_red}, {@link luma_saturation_green}, {@link luma_saturation_blue}. Unreal's
193
+ * saturation and per-channel saturation, varying across the tonal range. Each curve is evaluated as
194
+ * {@link AnimationCurve#evaluate} would and holds its end keys' values beyond them; a curve with no keys is a factor
195
+ * of 1, and a colour with no luma is left as it is. Clamped at zero, as the primaries' saturation is. The colour is clamped at zero in Rec.709 after it, as the operator takes it.
196
+ * 5. **Hue curves**, in OkLCh. Each curve's time is the colour's OkLCh hue in degrees, 0 to 360, and is evaluated as
179
197
  * {@link AnimationCurve#evaluate} would; a curve with no keys does nothing. The curve holds its end keys' values
180
198
  * outside them, so for a seamless circle key 0 and 360 with the same value and tangent.
181
199
  * - {@link hue_shift}: degrees added to the hue.
@@ -264,6 +282,66 @@ export class ColorGrade {
264
282
  */
265
283
  hue_lightness = new AnimationCurve();
266
284
 
285
+ /**
286
+ * Saturation of every channel against the colour's AP1 luma in stops from middle grey: 1 leaves it, 0 draws it to
287
+ * the luma. Each channel's own curve multiplies it.
288
+ * @readonly
289
+ * @type {AnimationCurve}
290
+ */
291
+ luma_saturation = new AnimationCurve();
292
+
293
+ /**
294
+ * Saturation of the red channel against the colour's AP1 luma in stops from middle grey, times
295
+ * {@link luma_saturation}.
296
+ * @readonly
297
+ * @type {AnimationCurve}
298
+ */
299
+ luma_saturation_red = new AnimationCurve();
300
+
301
+ /**
302
+ * Saturation of the green channel against the colour's AP1 luma in stops from middle grey, times
303
+ * {@link luma_saturation}.
304
+ * @readonly
305
+ * @type {AnimationCurve}
306
+ */
307
+ luma_saturation_green = new AnimationCurve();
308
+
309
+ /**
310
+ * Saturation of the blue channel against the colour's AP1 luma in stops from middle grey, times
311
+ * {@link luma_saturation}.
312
+ * @readonly
313
+ * @type {AnimationCurve}
314
+ */
315
+ luma_saturation_blue = new AnimationCurve();
316
+
317
+ /**
318
+ * Gain of the red channel against the colour's AP1 luma in stops from middle grey: 1 leaves it.
319
+ * @readonly
320
+ * @type {AnimationCurve}
321
+ */
322
+ luma_gain_red = new AnimationCurve();
323
+
324
+ /**
325
+ * Gain of the green channel against the colour's AP1 luma in stops from middle grey: 1 leaves it.
326
+ * @readonly
327
+ * @type {AnimationCurve}
328
+ */
329
+ luma_gain_green = new AnimationCurve();
330
+
331
+ /**
332
+ * Gain of the blue channel against the colour's AP1 luma in stops from middle grey: 1 leaves it.
333
+ * @readonly
334
+ * @type {AnimationCurve}
335
+ */
336
+ luma_gain_blue = new AnimationCurve();
337
+
338
+ /**
339
+ * Exposure of every channel against the colour's AP1 luma in stops from middle grey, in stops: 0 leaves it.
340
+ * @readonly
341
+ * @type {AnimationCurve}
342
+ */
343
+ luma_exposure = new AnimationCurve();
344
+
267
345
  /**
268
346
  * @type {Float32Array}
269
347
  */
@@ -276,8 +354,9 @@ export class ColorGrade {
276
354
  #words = new Uint32Array(this.#data.buffer);
277
355
 
278
356
  /**
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
357
+ * The grade as the bake reads it: {@link COLOR_GRADE_STRUCT}, then the three hue curves' keys, the four
358
+ * saturation-against-luma curves' keys (red, green, blue, all) and the four gain-against-luma curves' keys (red,
359
+ * green, blue, exposure), each {@link COLOR_GRADE_KEY_FLOATS} floats, with room for one key when there are none. The array is reused while the
281
360
  * key count stays the same.
282
361
  *
283
362
  * @returns {Float32Array}
@@ -290,9 +369,20 @@ export class ColorGrade {
290
369
  const hue_count = this.hue_shift.keys.length;
291
370
  const saturation_count = this.hue_saturation.keys.length;
292
371
  const lightness_count = this.hue_lightness.keys.length;
372
+ const red_count = this.luma_saturation_red.keys.length;
373
+ const green_count = this.luma_saturation_green.keys.length;
374
+ const blue_count = this.luma_saturation_blue.keys.length;
375
+ const all_count = this.luma_saturation.keys.length;
376
+ const gain_red_count = this.luma_gain_red.keys.length;
377
+ const gain_green_count = this.luma_gain_green.keys.length;
378
+ const gain_blue_count = this.luma_gain_blue.keys.length;
379
+ const exposure_count = this.luma_exposure.keys.length;
380
+
381
+ const key_count = hue_count + saturation_count + lightness_count
382
+ + red_count + green_count + blue_count + all_count
383
+ + gain_red_count + gain_green_count + gain_blue_count + exposure_count;
293
384
 
294
- const length = COLOR_GRADE_HEADER_FLOATS
295
- + COLOR_GRADE_KEY_FLOATS * Math.max(1, hue_count + saturation_count + lightness_count);
385
+ const length = COLOR_GRADE_HEADER_FLOATS + COLOR_GRADE_KEY_FLOATS * Math.max(1, key_count);
296
386
 
297
387
  if (this.#data.length !== length) {
298
388
  this.#data = new Float32Array(length);
@@ -324,11 +414,27 @@ export class ColorGrade {
324
414
  words[77] = saturation_count;
325
415
  words[78] = lightness_count;
326
416
  words[79] = 0;
417
+ words[80] = red_count;
418
+ words[81] = green_count;
419
+ words[82] = blue_count;
420
+ words[83] = all_count;
421
+ words[84] = gain_red_count;
422
+ words[85] = gain_green_count;
423
+ words[86] = gain_blue_count;
424
+ words[87] = exposure_count;
327
425
 
328
426
  let at = COLOR_GRADE_HEADER_FLOATS;
329
427
  at = write_keys(out, at, this.hue_shift);
330
428
  at = write_keys(out, at, this.hue_saturation);
331
429
  at = write_keys(out, at, this.hue_lightness);
430
+ at = write_keys(out, at, this.luma_saturation_red);
431
+ at = write_keys(out, at, this.luma_saturation_green);
432
+ at = write_keys(out, at, this.luma_saturation_blue);
433
+ at = write_keys(out, at, this.luma_saturation);
434
+ at = write_keys(out, at, this.luma_gain_red);
435
+ at = write_keys(out, at, this.luma_gain_green);
436
+ at = write_keys(out, at, this.luma_gain_blue);
437
+ at = write_keys(out, at, this.luma_exposure);
332
438
 
333
439
  out.fill(0, at);
334
440
 
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Whether the tone mapper applies the Purkinje shift to the scene colour ahead of its LUT. Decided by
3
+ * `chunk_tonemap_purkinje`, whose `false` alternative, the default, is the colour as it is and binds nothing more, so
4
+ * a pass that never sets it draws exactly as it would without the shift.
5
+ *
6
+ * `ToneMapper` sets it from `ToneMapper#purkinje_shift` the frame it records the pass.
7
+ *
8
+ * @type {ShaderSwitch}
9
+ */
10
+ export const TONEMAP_PURKINJE_SHIFT: ShaderSwitch;
11
+ import { ShaderSwitch } from "../../shader/compiler/ShaderSwitch.js";
12
+ //# sourceMappingURL=TONEMAP_PURKINJE_SHIFT.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TONEMAP_PURKINJE_SHIFT.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,qCAFU,YAAY,CAE4D;6BAXrD,uCAAuC"}
@@ -0,0 +1,12 @@
1
+ import { ShaderSwitch } from "../../shader/compiler/ShaderSwitch.js";
2
+
3
+ /**
4
+ * Whether the tone mapper applies the Purkinje shift to the scene colour ahead of its LUT. Decided by
5
+ * `chunk_tonemap_purkinje`, whose `false` alternative, the default, is the colour as it is and binds nothing more, so
6
+ * a pass that never sets it draws exactly as it would without the shift.
7
+ *
8
+ * `ToneMapper` sets it from `ToneMapper#purkinje_shift` the frame it records the pass.
9
+ *
10
+ * @type {ShaderSwitch}
11
+ */
12
+ export const TONEMAP_PURKINJE_SHIFT = ShaderSwitch.bool('tonemap purkinje shift');
@@ -9,6 +9,9 @@
9
9
  * A LUT comes from {@link grade} and {@link operator}, baked at {@link lut_resolution} and baked again when any of them
10
10
  * changes or, for the HDR LUT, when the display's peak does; or from the user, by {@link set_lut_sdr} and
11
11
  * {@link set_lut_hdr}, which takes the place of the bake for that output until cleared. A user's LUT is not graded.
12
+ *
13
+ * Ahead of the LUT, the scene colour goes through the Purkinje shift where {@link purkinje_shift} is on, at the
14
+ * luminance the view is adapted to. The shift is not baked into the LUT, so it applies to a user's LUT as well.
12
15
  */
13
16
  export class ToneMapper {
14
17
  /**
@@ -32,6 +35,13 @@ export class ToneMapper {
32
35
  * @type {ColorGrade}
33
36
  */
34
37
  readonly grade: ColorGrade;
38
+ /**
39
+ * Whether the scene colour goes through the Purkinje shift ahead of the LUT: below 5 cd/m² of adaptation the colour
40
+ * moves towards the rods' response, carried by a blue tint, and below 0.005 cd/m² it is that alone; see
41
+ * `chunk_apply_purkinje_shift`. Off unless set. Read every frame.
42
+ * @type {boolean}
43
+ */
44
+ purkinje_shift: boolean;
35
45
  /**
36
46
  * The canvas's primaries and the display's peak, which the Renderer writes.
37
47
  * @readonly
@@ -84,14 +94,17 @@ export class ToneMapper {
84
94
  * @param {FrameGraph} options.graph
85
95
  * @param {number} options.input_color the scene colour, linear Rec.709
86
96
  * @param {number} options.exposure the exposure multiplier, a uniform
97
+ * @param {number} options.adaptation the luminance the view is adapted to, cd/m², a uniform; read where
98
+ * {@link purkinje_shift} is on
87
99
  * @param {boolean} options.hdr whether the output is HDR
88
100
  * @param {number} options.target the texture to write
89
101
  * @returns {number} `target`, written
90
102
  */
91
- render({ graph, input_color, exposure, hdr, target }: {
103
+ render({ graph, input_color, exposure, adaptation, hdr, target }: {
92
104
  graph: FrameGraph;
93
105
  input_color: number;
94
106
  exposure: number;
107
+ adaptation: number;
95
108
  hdr: boolean;
96
109
  target: number;
97
110
  }): number;
@@ -99,6 +112,7 @@ export class ToneMapper {
99
112
  #private;
100
113
  }
101
114
  export type ToneMapOperator = import("./ToneMapOperator.js").ToneMapOperator;
115
+ export type ImageShader = import("../../shader/ImageShader.js").ImageShader;
102
116
  export type PipelineEnquiry = import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry;
103
117
  export type FrameGraph = import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
104
118
  import { ColorGrade } from "./ColorGrade.js";
@@ -1 +1 @@
1
- {"version":3,"file":"ToneMapper.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/ToneMapper.js"],"names":[],"mappings":"AA6FA;;;;;;;;;;;GAWG;AACH;IAmEI;;OAEG;IACH,+BAMC;IA3ED;;;OAGG;IACH,UAFU,eAAe,CAES;IAElC;;;;OAIG;IACH,gBAFU,MAAM,CAEI;IAEpB;;;;OAIG;IACH,gBAFU,UAAU,CAEK;IAEzB;;;;OAIG;IACH,kBAFU,sBAAsB,CAEO;IAoDvC;;;;;OAKG;IACH,wBAHW,MAAM,QACN,YAAY,QAKtB;IAED;;;;;;;OAOG;IACH,wBAJW,MAAM,QACN,YAAY,aACZ,MAAM,QAQhB;IAED;;OAEG;IACH,sBAIC;IAED;;OAEG;IACH,sBAGC;IAED;;;;;OAKG;IACH,+BASC;IAED;;;;;;OAMG;IACH,2BAJW,eAAe,OACf,OAAO,kCAMjB;IAED;;;;;;;;;;OAUG;IACH;QAP+B,KAAK,EAAzB,UAAU;QACM,WAAW,EAA3B,MAAM;QACU,QAAQ,EAAxB,MAAM;QACW,GAAG,EAApB,OAAO;QACS,MAAM,EAAtB,MAAM;QACJ,MAAM,CAyElB;IAED,gBAGC;;CAkIJ;8BAzcY,OAAO,sBAAsB,EAAE,eAAe;8BAC9C,OAAO,6CAA6C,EAAE,eAAe;yBACrE,OAAO,8DAA8D,EAAE,UAAU;2BAXxC,iBAAiB;uCAMhC,6BAA6B"}
1
+ {"version":3,"file":"ToneMapper.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/ToneMapper.js"],"names":[],"mappings":"AAgGA;;;;;;;;;;;;;;GAcG;AACH;IA2EI;;OAEG;IACH,+BAMC;IAnFD;;;OAGG;IACH,UAFU,eAAe,CAES;IAElC;;;;OAIG;IACH,gBAFU,MAAM,CAEI;IAEpB;;;;OAIG;IACH,gBAFU,UAAU,CAEK;IAEzB;;;;;OAKG;IACH,gBAFU,OAAO,CAEM;IAEvB;;;;OAIG;IACH,kBAFU,sBAAsB,CAEO;IAoDvC;;;;;OAKG;IACH,wBAHW,MAAM,QACN,YAAY,QAKtB;IAED;;;;;;;OAOG;IACH,wBAJW,MAAM,QACN,YAAY,aACZ,MAAM,QAQhB;IAED;;OAEG;IACH,sBAIC;IAED;;OAEG;IACH,sBAGC;IAED;;;;;OAKG;IACH,+BASC;IAED;;;;;;OAMG;IACH,2BAJW,eAAe,OACf,OAAO,kCAMjB;IAED;;;;;;;;;;;;OAYG;IACH;QAT+B,KAAK,EAAzB,UAAU;QACM,WAAW,EAA3B,MAAM;QACU,QAAQ,EAAxB,MAAM;QACU,UAAU,EAA1B,MAAM;QAEW,GAAG,EAApB,OAAO;QACS,MAAM,EAAtB,MAAM;QACJ,MAAM,CA2ElB;IAYD,gBAGC;;CAkIJ;8BAneY,OAAO,sBAAsB,EAAE,eAAe;0BAC9C,OAAO,6BAA6B,EAAE,WAAW;8BACjD,OAAO,6CAA6C,EAAE,eAAe;yBACrE,OAAO,8DAA8D,EAAE,UAAU;2BAbxC,iBAAiB;uCAOhC,6BAA6B"}
@@ -1,5 +1,6 @@
1
1
  import { assert } from "../../../../core/assert.js";
2
2
  import { PAPER_WHITE_NITS } from "../../shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js";
3
+ import { ShaderSwitchSet } from "../../shader/compiler/ShaderSwitchSet.js";
3
4
  import { graph_compute_pass } from "../../shader/graph/compute/graph_compute_pass.js";
4
5
  import { graph_image_pass } from "../../shader/graph/graph_image_pass.js";
5
6
  import { graph_import_raw_buffer } from "../../shader/graph/graph_import_raw_buffer.js";
@@ -11,10 +12,12 @@ import { shader_tonemap_LDR_lut } from "./shader_tonemap_LDR_lut.js";
11
12
  import { shader_tonemap_lut_bake, TONEMAP_LUT_BAKE_GROUP } from "./shader_tonemap_lut_bake.js";
12
13
  import { shader_tonemap_lut_sdr_from_hdr } from "./shader_tonemap_lut_sdr_from_hdr.js";
13
14
  import { TONE_MAP_OPERATOR_ACES } from "./TONE_MAP_OPERATOR_ACES.js";
15
+ import { TONEMAP_PURKINJE_SHIFT } from "./TONEMAP_PURKINJE_SHIFT.js";
14
16
  import { TonemapDisplaySettings } from "./TonemapDisplaySettings.js";
15
17
 
16
18
  /**
17
19
  * @typedef {import("./ToneMapOperator.js").ToneMapOperator} ToneMapOperator
20
+ * @typedef {import("../../shader/ImageShader.js").ImageShader} ImageShader
18
21
  * @typedef {import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
19
22
  * @typedef {import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} FrameGraph
20
23
  */
@@ -102,6 +105,9 @@ function same_words(a, b) {
102
105
  * A LUT comes from {@link grade} and {@link operator}, baked at {@link lut_resolution} and baked again when any of them
103
106
  * changes or, for the HDR LUT, when the display's peak does; or from the user, by {@link set_lut_sdr} and
104
107
  * {@link set_lut_hdr}, which takes the place of the bake for that output until cleared. A user's LUT is not graded.
108
+ *
109
+ * Ahead of the LUT, the scene colour goes through the Purkinje shift where {@link purkinje_shift} is on, at the
110
+ * luminance the view is adapted to. The shift is not baked into the LUT, so it applies to a user's LUT as well.
105
111
  */
106
112
  export class ToneMapper {
107
113
  /**
@@ -124,6 +130,14 @@ export class ToneMapper {
124
130
  */
125
131
  grade = new ColorGrade();
126
132
 
133
+ /**
134
+ * Whether the scene colour goes through the Purkinje shift ahead of the LUT: below 5 cd/m² of adaptation the colour
135
+ * moves towards the rods' response, carried by a blue tint, and below 0.005 cd/m² it is that alone; see
136
+ * `chunk_apply_purkinje_shift`. Off unless set. Read every frame.
137
+ * @type {boolean}
138
+ */
139
+ purkinje_shift = false;
140
+
127
141
  /**
128
142
  * The canvas's primaries and the display's peak, which the Renderer writes.
129
143
  * @readonly
@@ -250,7 +264,7 @@ export class ToneMapper {
250
264
  * @param {GPUTextureFormat} format the canvas's
251
265
  */
252
266
  enquire_pipelines(enquiry, hdr, format) {
253
- enquiry.render.push(apply_shader(hdr).pipeline_for([format]));
267
+ enquiry.render.push(this.#apply_shader(hdr).pipeline_for([format]));
254
268
  enquiry.compute.push(shader_tonemap_lut_bake(this.operator).pipeline);
255
269
  }
256
270
 
@@ -261,12 +275,15 @@ export class ToneMapper {
261
275
  * @param {FrameGraph} options.graph
262
276
  * @param {number} options.input_color the scene colour, linear Rec.709
263
277
  * @param {number} options.exposure the exposure multiplier, a uniform
278
+ * @param {number} options.adaptation the luminance the view is adapted to, cd/m², a uniform; read where
279
+ * {@link purkinje_shift} is on
264
280
  * @param {boolean} options.hdr whether the output is HDR
265
281
  * @param {number} options.target the texture to write
266
282
  * @returns {number} `target`, written
267
283
  */
268
- render({ graph, input_color, exposure, hdr, target }) {
284
+ render({ graph, input_color, exposure, adaptation, hdr, target }) {
269
285
  assert.isBoolean(hdr, 'hdr');
286
+ assert.isNonNegativeInteger(adaptation, 'adaptation');
270
287
 
271
288
  const lut = hdr ? this.#hdr : this.#sdr;
272
289
  const peak_nits = hdr ? this.display.peak_nits : PAPER_WHITE_NITS;
@@ -325,10 +342,11 @@ export class ToneMapper {
325
342
 
326
343
  const [written] = graph_image_pass({
327
344
  graph,
328
- shader: apply_shader(hdr),
345
+ shader: this.#apply_shader(hdr),
329
346
  inputs: {
330
347
  input_color,
331
348
  exposure,
349
+ adaptation,
332
350
  settings: this.display,
333
351
  lut: gr_lut,
334
352
  },
@@ -338,6 +356,16 @@ export class ToneMapper {
338
356
  return written;
339
357
  }
340
358
 
359
+ /**
360
+ * The pass that writes the canvas for this output, as {@link purkinje_shift} makes it.
361
+ *
362
+ * @param {boolean} hdr
363
+ * @returns {ImageShader}
364
+ */
365
+ #apply_shader(hdr) {
366
+ return apply_shader(hdr).variant(ShaderSwitchSet.EMPTY.with(TONEMAP_PURKINJE_SHIFT, this.purkinje_shift));
367
+ }
368
+
341
369
  destroy() {
342
370
  this.#sdr.texture.destroy();
343
371
  this.#hdr.texture.destroy();
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `adaptation`, {@link F32_CONTAINER_STRUCT}: the luminance the view is adapted to, cd/m² —
3
+ * `GPUCameraExposureManager#adaptation`.
4
+ *
5
+ * @type {ShaderResourceDescriptor}
6
+ */
7
+ export const TONEMAP_ADAPTATION_RESOURCE: ShaderResourceDescriptor;
8
+ /**
9
+ * The scene colour as the tone mapper's LUT takes it, by {@link TONEMAP_PURKINJE_SHIFT}:
10
+ *
11
+ * ```wgsl
12
+ * fn tonemap_purkinje(color: vec3<f32>) -> vec3<f32> // color: scene-linear Rec.709
13
+ * ```
14
+ *
15
+ * - `false`, the default: the colour as it is.
16
+ * - `true`: the colour through `apply_purkinje_shift` at the view's adaptation, {@link TONEMAP_ADAPTATION_RESOURCE}.
17
+ *
18
+ * The shift is linear in the colour, so the function may be applied ahead of the exposure or after it.
19
+ *
20
+ * @type {CodeChunkChoice}
21
+ */
22
+ export const chunk_tonemap_purkinje: CodeChunkChoice;
23
+ import { ShaderResourceDescriptor } from "../../shader/resource/ShaderResourceDescriptor.js";
24
+ import { CodeChunkChoice } from "../../shader/compiler/CodeChunkChoice.js";
25
+ //# sourceMappingURL=chunk_tonemap_purkinje.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_tonemap_purkinje.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.js"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,0CAFU,wBAAwB,CAE8E;AAEhH;;;;;;;;;;;;;GAaG;AACH,qCAFU,eAAe,CAE0D;yCA1B1C,mDAAmD;gCAD5D,0CAA0C"}
@@ -0,0 +1,51 @@
1
+ import { chunk_apply_purkinje_shift } from "../../shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.js";
2
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
3
+ import { CodeChunkChoice } from "../../shader/compiler/CodeChunkChoice.js";
4
+ import { ShaderResourceDescriptor } from "../../shader/resource/ShaderResourceDescriptor.js";
5
+ import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
6
+ import { TONEMAP_PURKINJE_SHIFT } from "./TONEMAP_PURKINJE_SHIFT.js";
7
+
8
+ /**
9
+ * `adaptation`, {@link F32_CONTAINER_STRUCT}: the luminance the view is adapted to, cd/m² —
10
+ * `GPUCameraExposureManager#adaptation`.
11
+ *
12
+ * @type {ShaderResourceDescriptor}
13
+ */
14
+ export const TONEMAP_ADAPTATION_RESOURCE = ShaderResourceDescriptor.uniform("adaptation", F32_CONTAINER_STRUCT);
15
+
16
+ /**
17
+ * The scene colour as the tone mapper's LUT takes it, by {@link TONEMAP_PURKINJE_SHIFT}:
18
+ *
19
+ * ```wgsl
20
+ * fn tonemap_purkinje(color: vec3<f32>) -> vec3<f32> // color: scene-linear Rec.709
21
+ * ```
22
+ *
23
+ * - `false`, the default: the colour as it is.
24
+ * - `true`: the colour through `apply_purkinje_shift` at the view's adaptation, {@link TONEMAP_ADAPTATION_RESOURCE}.
25
+ *
26
+ * The shift is linear in the colour, so the function may be applied ahead of the exposure or after it.
27
+ *
28
+ * @type {CodeChunkChoice}
29
+ */
30
+ export const chunk_tonemap_purkinje = CodeChunkChoice.from(TONEMAP_PURKINJE_SHIFT);
31
+
32
+ const unshifted = CodeChunk.from(
33
+ //language=WGSL
34
+ `
35
+ fn tonemap_purkinje(color: vec3<f32>) -> vec3<f32> {
36
+ return color;
37
+ }
38
+ `);
39
+
40
+ const shifted = CodeChunk.from(
41
+ //language=WGSL
42
+ `
43
+ fn tonemap_purkinje(color: vec3<f32>) -> vec3<f32> {
44
+ return apply_purkinje_shift(color, adaptation.value);
45
+ }
46
+ `, [chunk_apply_purkinje_shift]);
47
+
48
+ shifted.requireResource(TONEMAP_ADAPTATION_RESOURCE);
49
+
50
+ chunk_tonemap_purkinje.add(false, unshifted);
51
+ chunk_tonemap_purkinje.add(true, shifted);
@@ -1,6 +1,6 @@
1
1
  /**
2
- * The HDR output of {@link ToneMapper}: exposure, then the HDR LUT, written in the canvas's primaries, extended, where
3
- * 1.0 is SDR white.
2
+ * The HDR output of {@link ToneMapper}: the Purkinje shift where `TONEMAP_PURKINJE_SHIFT` is on, exposure, then the
3
+ * HDR LUT, written in the canvas's primaries, extended, where 1.0 is SDR white.
4
4
  *
5
5
  * @type {ImageShader}
6
6
  */
@@ -1 +1 @@
1
- {"version":3,"file":"shader_tonemap_HDR_lut.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.js"],"names":[],"mappings":"AAmDA;;;;;GAKG;AACH,qCAFU,WAAW,CAclB;4BAlEyB,6BAA6B"}
1
+ {"version":3,"file":"shader_tonemap_HDR_lut.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.js"],"names":[],"mappings":"AAsDA;;;;;GAKG;AACH,qCAFU,WAAW,CAclB;4BArEyB,6BAA6B"}
@@ -6,6 +6,7 @@ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourc
6
6
  import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
7
7
  import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
8
8
  import { SAMPLER_TONEMAP_LUT } from "./SAMPLER_TONEMAP_LUT.js";
9
+ import { chunk_tonemap_purkinje, TONEMAP_ADAPTATION_RESOURCE } from "./chunk_tonemap_purkinje.js";
9
10
  import { TONEMAP_SETTINGS } from "./TonemapDisplaySettings.js";
10
11
 
11
12
  const resources = new ShaderResourceSetDescriptor();
@@ -14,6 +15,7 @@ resources.setImmediate("settings", TONEMAP_SETTINGS);
14
15
  resources.createGroup()
15
16
  .addTexture("input_color", "float")
16
17
  .addUniform("exposure", F32_CONTAINER_STRUCT)
18
+ .add(TONEMAP_ADAPTATION_RESOURCE)
17
19
  .addTexture("lut", "float", "3d")
18
20
  .addSampler("lut_sampler", "filtering", SAMPLER_TONEMAP_LUT)
19
21
 
@@ -26,7 +28,7 @@ fn main(
26
28
  ) -> @location(0) vec4<f32> {
27
29
 
28
30
  // scene color in linear Rec. 709
29
- let color = textureLoad(input_color, vec2i(coord.xy), 0).rgb * exposure.value;
31
+ let color = tonemap_purkinje(textureLoad(input_color, vec2i(coord.xy), 0).rgb) * exposure.value;
30
32
 
31
33
  let uvw = tonemap_lut_coordinate(color, f32(textureDimensions(lut).x));
32
34
  let color_2020 = tonemap_lut_pq_decode(textureSampleLevel(lut, lut_sampler, uvw, 0.0).rgb);
@@ -44,14 +46,15 @@ fn main(
44
46
  return vec4(sRGBTransferOETF(color_display), 1.0);
45
47
  }
46
48
  `, [
49
+ chunk_tonemap_purkinje,
47
50
  chunk_tonemap_lut,
48
51
  chunk_sRGBTransferOETF,
49
52
  ]
50
53
  );
51
54
 
52
55
  /**
53
- * The HDR output of {@link ToneMapper}: exposure, then the HDR LUT, written in the canvas's primaries, extended, where
54
- * 1.0 is SDR white.
56
+ * The HDR output of {@link ToneMapper}: the Purkinje shift where `TONEMAP_PURKINJE_SHIFT` is on, exposure, then the
57
+ * HDR LUT, written in the canvas's primaries, extended, where 1.0 is SDR white.
55
58
  *
56
59
  * @type {ImageShader}
57
60
  */
@@ -1,6 +1,7 @@
1
1
  /**
2
- * The SDR output of {@link ToneMapper}: exposure, then the SDR LUT, the canvas's primaries, the sRGB transfer curve
3
- * and an 8-bit dither. The 8-bit target clips anything the LUT puts past SDR white.
2
+ * The SDR output of {@link ToneMapper}: the Purkinje shift where `TONEMAP_PURKINJE_SHIFT` is on, exposure, then the
3
+ * SDR LUT, the canvas's primaries, the sRGB transfer curve and an 8-bit dither. The 8-bit target clips anything the
4
+ * LUT puts past SDR white.
4
5
  *
5
6
  * @type {ImageShader}
6
7
  */
@@ -1 +1 @@
1
- {"version":3,"file":"shader_tonemap_LDR_lut.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.js"],"names":[],"mappings":"AA0DA;;;;;GAKG;AACH,qCAFU,WAAW,CAclB;4BAtEyB,6BAA6B"}
1
+ {"version":3,"file":"shader_tonemap_LDR_lut.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.js"],"names":[],"mappings":"AA6DA;;;;;;GAMG;AACH,qCAFU,WAAW,CAclB;4BA1EyB,6BAA6B"}