@zephyr3d/scene 0.9.25 → 0.9.27

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 (299) hide show
  1. package/dist/animation/animationset.js +92 -30
  2. package/dist/animation/animationset.js.map +1 -1
  3. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  4. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  5. package/dist/animation/joint_dynamics/controller.js +7 -5
  6. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  7. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  8. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  9. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  10. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  11. package/dist/animation/morphtrack.js +3 -4
  12. package/dist/animation/morphtrack.js.map +1 -1
  13. package/dist/animation/skeleton.js +79 -25
  14. package/dist/animation/skeleton.js.map +1 -1
  15. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  16. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  17. package/dist/animation/spring/spring_collider.js +4 -3
  18. package/dist/animation/spring/spring_collider.js.map +1 -1
  19. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  20. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  21. package/dist/animation/spring/spring_particle.js +2 -0
  22. package/dist/animation/spring/spring_particle.js.map +1 -1
  23. package/dist/animation/spring/spring_system.js +11 -3
  24. package/dist/animation/spring/spring_system.js.map +1 -1
  25. package/dist/animation/spring_modifier.js +10 -0
  26. package/dist/animation/spring_modifier.js.map +1 -1
  27. package/dist/app/engine.js +53 -43
  28. package/dist/app/engine.js.map +1 -1
  29. package/dist/app/scriptingsystem.js +119 -6
  30. package/dist/app/scriptingsystem.js.map +1 -1
  31. package/dist/app/scriptregistry.js +3 -2
  32. package/dist/app/scriptregistry.js.map +1 -1
  33. package/dist/asset/assetmanager.js +284 -67
  34. package/dist/asset/assetmanager.js.map +1 -1
  35. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  36. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  37. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  38. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  39. package/dist/asset/model.js +184 -69
  40. package/dist/asset/model.js.map +1 -1
  41. package/dist/camera/camera.js +268 -44
  42. package/dist/camera/camera.js.map +1 -1
  43. package/dist/camera/perspectivecamera.js +3 -1
  44. package/dist/camera/perspectivecamera.js.map +1 -1
  45. package/dist/index.d.ts +9044 -5139
  46. package/dist/index.js +17 -6
  47. package/dist/index.js.map +1 -1
  48. package/dist/material/eye.js +932 -0
  49. package/dist/material/eye.js.map +1 -0
  50. package/dist/material/hair.js +917 -0
  51. package/dist/material/hair.js.map +1 -0
  52. package/dist/material/hairstrand.js +842 -0
  53. package/dist/material/hairstrand.js.map +1 -0
  54. package/dist/material/hairstrand_data.js +162 -0
  55. package/dist/material/hairstrand_data.js.map +1 -0
  56. package/dist/material/lambert.js +5 -2
  57. package/dist/material/lambert.js.map +1 -1
  58. package/dist/material/material.js +48 -10
  59. package/dist/material/material.js.map +1 -1
  60. package/dist/material/meshmaterial.js +120 -19
  61. package/dist/material/meshmaterial.js.map +1 -1
  62. package/dist/material/mixins/albedocolor.js +1 -1
  63. package/dist/material/mixins/albedocolor.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  65. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  67. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  70. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  71. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  72. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  73. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  74. package/dist/material/mixins/lit.js +106 -19
  75. package/dist/material/mixins/lit.js.map +1 -1
  76. package/dist/material/mixins/pbr/common.js +4 -4
  77. package/dist/material/mixins/pbr/common.js.map +1 -1
  78. package/dist/material/mixins/texture.js +48 -11
  79. package/dist/material/mixins/texture.js.map +1 -1
  80. package/dist/material/mtoon.js +6 -5
  81. package/dist/material/mtoon.js.map +1 -1
  82. package/dist/material/pbrblueprint.js +146 -28
  83. package/dist/material/pbrblueprint.js.map +1 -1
  84. package/dist/material/pbrblueprint_instance.js +501 -0
  85. package/dist/material/pbrblueprint_instance.js.map +1 -0
  86. package/dist/material/pbrmr.js +15 -16
  87. package/dist/material/pbrmr.js.map +1 -1
  88. package/dist/material/shader/helper.js +734 -23
  89. package/dist/material/shader/helper.js.map +1 -1
  90. package/dist/material/shader/terrain_blend.js +55 -0
  91. package/dist/material/shader/terrain_blend.js.map +1 -0
  92. package/dist/material/skin.js +192 -32
  93. package/dist/material/skin.js.map +1 -1
  94. package/dist/material/spriteblueprint.js +16 -1
  95. package/dist/material/spriteblueprint.js.map +1 -1
  96. package/dist/material/subsurfaceprofile.js +86 -23
  97. package/dist/material/subsurfaceprofile.js.map +1 -1
  98. package/dist/material/water.js +2059 -72
  99. package/dist/material/water.js.map +1 -1
  100. package/dist/posteffect/bloom.js +167 -7
  101. package/dist/posteffect/bloom.js.map +1 -1
  102. package/dist/posteffect/coloradjust.js +2 -1
  103. package/dist/posteffect/coloradjust.js.map +1 -1
  104. package/dist/posteffect/compositor.js.map +1 -1
  105. package/dist/posteffect/fxaa.js +2 -1
  106. package/dist/posteffect/fxaa.js.map +1 -1
  107. package/dist/posteffect/grayscale.js +3 -1
  108. package/dist/posteffect/grayscale.js.map +1 -1
  109. package/dist/posteffect/motionblur.js +664 -56
  110. package/dist/posteffect/motionblur.js.map +1 -1
  111. package/dist/posteffect/posteffect.js +12 -1
  112. package/dist/posteffect/posteffect.js.map +1 -1
  113. package/dist/posteffect/sao.js +46 -44
  114. package/dist/posteffect/sao.js.map +1 -1
  115. package/dist/posteffect/skinsss.js +368 -69
  116. package/dist/posteffect/skinsss.js.map +1 -1
  117. package/dist/posteffect/ssgi.js +16 -9
  118. package/dist/posteffect/ssgi.js.map +1 -1
  119. package/dist/posteffect/ssr.js +3 -0
  120. package/dist/posteffect/ssr.js.map +1 -1
  121. package/dist/posteffect/sss.js +121 -36
  122. package/dist/posteffect/sss.js.map +1 -1
  123. package/dist/posteffect/taa.js.map +1 -1
  124. package/dist/posteffect/tonemap.js +44 -1
  125. package/dist/posteffect/tonemap.js.map +1 -1
  126. package/dist/render/abuffer_oit.js +8 -2
  127. package/dist/render/abuffer_oit.js.map +1 -1
  128. package/dist/render/clipmap.js +156 -5
  129. package/dist/render/clipmap.js.map +1 -1
  130. package/dist/render/cull_visitor.js +20 -0
  131. package/dist/render/cull_visitor.js.map +1 -1
  132. package/dist/render/depthpass.js +36 -2
  133. package/dist/render/depthpass.js.map +1 -1
  134. package/dist/render/drawable_mixin.js +26 -1
  135. package/dist/render/drawable_mixin.js.map +1 -1
  136. package/dist/render/dualdepthpeeling_oit.js +3 -2
  137. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  138. package/dist/render/envlight.js +1 -1
  139. package/dist/render/envlight.js.map +1 -1
  140. package/dist/render/fbm_wavegenerator.js +6 -3
  141. package/dist/render/fbm_wavegenerator.js.map +1 -1
  142. package/dist/render/fft_wavegenerator.js +57 -15
  143. package/dist/render/fft_wavegenerator.js.map +1 -1
  144. package/dist/render/gerstner_wavegenerator.js +130 -20
  145. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  146. package/dist/render/globalbindgroup_allocator.js +3 -0
  147. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  148. package/dist/render/hzb.js +80 -22
  149. package/dist/render/hzb.js.map +1 -1
  150. package/dist/render/lightpass.js +6 -3
  151. package/dist/render/lightpass.js.map +1 -1
  152. package/dist/render/oit.js +29 -0
  153. package/dist/render/oit.js.map +1 -0
  154. package/dist/render/render_queue.js +39 -0
  155. package/dist/render/render_queue.js.map +1 -1
  156. package/dist/render/renderer.js +4 -0
  157. package/dist/render/renderer.js.map +1 -1
  158. package/dist/render/rendergraph/blackboard.js +1 -0
  159. package/dist/render/rendergraph/blackboard.js.map +1 -1
  160. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  161. package/dist/render/rendergraph/executor.js +2 -0
  162. package/dist/render/rendergraph/executor.js.map +1 -1
  163. package/dist/render/rendergraph/forward_plus_builder.js +379 -10
  164. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  165. package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
  166. package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
  167. package/dist/render/rendergraph/history_resources.js +8 -1
  168. package/dist/render/rendergraph/history_resources.js.map +1 -1
  169. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  170. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  171. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  172. package/dist/render/rendergraph/types.js.map +1 -1
  173. package/dist/render/shadow_mask_pass.js +73 -8
  174. package/dist/render/shadow_mask_pass.js.map +1 -1
  175. package/dist/render/sky.js +166 -126
  176. package/dist/render/sky.js.map +1 -1
  177. package/dist/render/underwater.js +624 -0
  178. package/dist/render/underwater.js.map +1 -0
  179. package/dist/render/water_caustics.js +1380 -0
  180. package/dist/render/water_caustics.js.map +1 -0
  181. package/dist/render/weightedblended_oit.js +3 -2
  182. package/dist/render/weightedblended_oit.js.map +1 -1
  183. package/dist/scene/basesprite.js +8 -0
  184. package/dist/scene/basesprite.js.map +1 -1
  185. package/dist/scene/batchgroup.js +3 -0
  186. package/dist/scene/batchgroup.js.map +1 -1
  187. package/dist/scene/environment.js +4 -1
  188. package/dist/scene/environment.js.map +1 -1
  189. package/dist/scene/hair.js +963 -0
  190. package/dist/scene/hair.js.map +1 -0
  191. package/dist/scene/light.js +5 -1
  192. package/dist/scene/light.js.map +1 -1
  193. package/dist/scene/mesh.js +481 -47
  194. package/dist/scene/mesh.js.map +1 -1
  195. package/dist/scene/meshdrawable.js +6 -0
  196. package/dist/scene/meshdrawable.js.map +1 -1
  197. package/dist/scene/msdftext.js +3 -0
  198. package/dist/scene/msdftext.js.map +1 -1
  199. package/dist/scene/msdftextsprite.js +3 -0
  200. package/dist/scene/msdftextsprite.js.map +1 -1
  201. package/dist/scene/particlesys.js +6 -0
  202. package/dist/scene/particlesys.js.map +1 -1
  203. package/dist/scene/scene.js +3 -0
  204. package/dist/scene/scene.js.map +1 -1
  205. package/dist/scene/scene_node.js +6 -1
  206. package/dist/scene/scene_node.js.map +1 -1
  207. package/dist/scene/terrain-cm/grass.js +3 -0
  208. package/dist/scene/terrain-cm/grass.js.map +1 -1
  209. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  210. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  211. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  212. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  213. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  214. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  215. package/dist/scene/water.js +546 -4
  216. package/dist/scene/water.js.map +1 -1
  217. package/dist/shaders/atmosphere.js.map +1 -1
  218. package/dist/shaders/diffusion.js +54 -0
  219. package/dist/shaders/diffusion.js.map +1 -0
  220. package/dist/shaders/shadow.js +33 -21
  221. package/dist/shaders/shadow.js.map +1 -1
  222. package/dist/shaders/temporal.js +71 -33
  223. package/dist/shaders/temporal.js.map +1 -1
  224. package/dist/shaders/water.js +22 -19
  225. package/dist/shaders/water.js.map +1 -1
  226. package/dist/shaders/water_medium.js +56 -0
  227. package/dist/shaders/water_medium.js.map +1 -0
  228. package/dist/shadow/dom.js +546 -0
  229. package/dist/shadow/dom.js.map +1 -0
  230. package/dist/shadow/pcf_opt.js +3 -5
  231. package/dist/shadow/pcf_opt.js.map +1 -1
  232. package/dist/shadow/pcf_pd.js +1 -1
  233. package/dist/shadow/pcf_pd.js.map +1 -1
  234. package/dist/shadow/receiver_bias.js +41 -0
  235. package/dist/shadow/receiver_bias.js.map +1 -0
  236. package/dist/shadow/shader.js +20 -60
  237. package/dist/shadow/shader.js.map +1 -1
  238. package/dist/shadow/shadow_impl.js +89 -0
  239. package/dist/shadow/shadow_impl.js.map +1 -1
  240. package/dist/shadow/shadow_region.js +1 -1
  241. package/dist/shadow/shadow_region.js.map +1 -1
  242. package/dist/shadow/shadowmapper.js +150 -37
  243. package/dist/shadow/shadowmapper.js.map +1 -1
  244. package/dist/shapes/shape.js +11 -2
  245. package/dist/shapes/shape.js.map +1 -1
  246. package/dist/shapes/sphere.js +50 -9
  247. package/dist/shapes/sphere.js.map +1 -1
  248. package/dist/utility/blueprint/common/constants.js +112 -2
  249. package/dist/utility/blueprint/common/constants.js.map +1 -1
  250. package/dist/utility/blueprint/material/func.js +142 -49
  251. package/dist/utility/blueprint/material/func.js.map +1 -1
  252. package/dist/utility/blueprint/material/ir.js +490 -25
  253. package/dist/utility/blueprint/material/ir.js.map +1 -1
  254. package/dist/utility/blueprint/material/texture.js +898 -4
  255. package/dist/utility/blueprint/material/texture.js.map +1 -1
  256. package/dist/utility/serialization/manager.js +434 -101
  257. package/dist/utility/serialization/manager.js.map +1 -1
  258. package/dist/utility/serialization/scene/animation.js +401 -5
  259. package/dist/utility/serialization/scene/animation.js.map +1 -1
  260. package/dist/utility/serialization/scene/batch.js +4 -0
  261. package/dist/utility/serialization/scene/batch.js.map +1 -1
  262. package/dist/utility/serialization/scene/camera.js +186 -26
  263. package/dist/utility/serialization/scene/camera.js.map +1 -1
  264. package/dist/utility/serialization/scene/common.js +26 -5
  265. package/dist/utility/serialization/scene/common.js.map +1 -1
  266. package/dist/utility/serialization/scene/hair.js +1141 -0
  267. package/dist/utility/serialization/scene/hair.js.map +1 -0
  268. package/dist/utility/serialization/scene/light.js +84 -4
  269. package/dist/utility/serialization/scene/light.js.map +1 -1
  270. package/dist/utility/serialization/scene/material.js +1867 -166
  271. package/dist/utility/serialization/scene/material.js.map +1 -1
  272. package/dist/utility/serialization/scene/mesh.js +231 -14
  273. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  274. package/dist/utility/serialization/scene/node.js +141 -7
  275. package/dist/utility/serialization/scene/node.js.map +1 -1
  276. package/dist/utility/serialization/scene/particle.js +4 -0
  277. package/dist/utility/serialization/scene/particle.js.map +1 -1
  278. package/dist/utility/serialization/scene/primitive.js +18 -0
  279. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  280. package/dist/utility/serialization/scene/sprite.js +4 -0
  281. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  282. package/dist/utility/serialization/scene/terrain.js +4 -0
  283. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  284. package/dist/utility/serialization/scene/text.js +4 -0
  285. package/dist/utility/serialization/scene/text.js.map +1 -1
  286. package/dist/utility/serialization/scene/water.js +1105 -21
  287. package/dist/utility/serialization/scene/water.js.map +1 -1
  288. package/dist/utility/serialization/types.js.map +1 -1
  289. package/dist/utility/shprojector.js +9 -8
  290. package/dist/utility/shprojector.js.map +1 -1
  291. package/dist/values.js +49 -2
  292. package/dist/values.js.map +1 -1
  293. package/package.json +3 -3
  294. package/dist/render/rendergraph/frame_graph_context.js +0 -41
  295. package/dist/render/rendergraph/frame_graph_context.js.map +0 -1
  296. package/dist/shaders/ssgi.js +0 -63
  297. package/dist/shaders/ssgi.js.map +0 -1
  298. package/dist/shaders/ssgi_reprojection.js +0 -118
  299. package/dist/shaders/ssgi_reprojection.js.map +0 -1
@@ -28,30 +28,37 @@ const fogTypeMap = {
28
28
  none: Fog.FOG_TYPE_NONE
29
29
  };
30
30
  const defaultSkyWorldMatrix = Matrix4x4.identity();
31
- /**
32
- * The sky renderer
33
- * @public
31
+ /**
32
+ * The sky renderer
33
+ * @public
34
34
  */ class SkyRenderer extends Disposable {
35
- /**
36
- * @internal
37
- *
38
- * The atmospheric scattering model predates photometric lighting and was authored around a
39
- * sun input of 10. This normalization maps the physical daylight reference (100,000 lux at
40
- * Sunny 16, whose camera exposure is 1 / 38,400) onto that model reference: 10 / (100000 / 38400).
35
+ /**
36
+ * @internal
37
+ *
38
+ * The atmospheric scattering model predates photometric lighting and was authored around a
39
+ * sun input of 10. This normalization maps the physical daylight reference (100,000 lux at
40
+ * Sunny 16, whose camera exposure is 1 / 38,400) onto that model reference: 10 / (100000 / 38400).
41
41
  */ static PHYSICAL_ATMOSPHERE_LUMINANCE_SCALE = 3.84;
42
- /**
43
- * @internal
44
- * Fixed exposure the physical sky bake is stored at. See {@link PHYSICAL_BAKE_EXPOSURE}.
42
+ /**
43
+ * @internal
44
+ * Fixed exposure the physical sky bake is stored at. See {@link PHYSICAL_BAKE_EXPOSURE}.
45
45
  */ static PHYSICAL_BAKE_EXPOSURE = PHYSICAL_BAKE_EXPOSURE;
46
- /**
47
- * @internal
48
- *
49
- * Reference-exposure anchor previously used to lift authored fog colors into photometric space.
50
- *
51
- * @deprecated Physical fog now derives its luminance from `EnvLightWrapper.intensity`, mirroring
52
- * Filament, which scales fog color by `iblLuminance`. Retained only because it documents the
53
- * Sunny-16 equivalence: 38,400 = 1 / exposure(f/16, 1/125s, ISO 100).
46
+ /**
47
+ * @internal
48
+ *
49
+ * Reference-exposure anchor previously used to lift authored fog colors into photometric space.
50
+ *
51
+ * @deprecated Physical fog now derives its luminance from `EnvLightWrapper.intensity`, mirroring
52
+ * Filament, which scales fog color by `iblLuminance`. Retained only because it documents the
53
+ * Sunny-16 equivalence: 38,400 = 1 / exposure(f/16, 1/125s, ISO 100).
54
54
  */ static FOG_PHYSICAL_LUMINANCE = 38400;
55
+ /**
56
+ * @internal
57
+ *
58
+ * Direct-sun transmittance floor under full cloud cover. Heavy overcast leaves only a few
59
+ * percent of direct sunlight; keeping a small non-zero floor lets shadows fade out smoothly
60
+ * instead of snapping off.
61
+ */ static CLOUD_SUN_MIN_TRANSMITTANCE = 0.05;
55
62
  static _skyCamera = (()=>{
56
63
  return new PerspectiveCamera(null, Math.PI * 0.5, 1, 20, 1);
57
64
  })();
@@ -110,16 +117,16 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
110
117
  _bindgroupFog = null;
111
118
  _bindgroupFogNoDepth = null;
112
119
  _format;
113
- /**
114
- * @internal Scale lifting the authored 0..1 height-fog colors into the pre-exposed space for the
115
- * current frame (1 in legacy, `EnvLightWrapper.intensity * cameraExposure` in physical).
120
+ /**
121
+ * @internal Scale lifting the authored 0..1 height-fog colors into the pre-exposed space for the
122
+ * current frame (1 in legacy, `EnvLightWrapper.intensity * cameraExposure` in physical).
116
123
  */ _fogLuminanceScale;
117
- /**
118
- * @internal Ratio converting the fog shader's atmosphere-derived LUT samples from the fixed bake
119
- * exposure to the live one (1 in legacy).
124
+ /**
125
+ * @internal Ratio converting the fog shader's atmosphere-derived LUT samples from the fixed bake
126
+ * exposure to the live one (1 in legacy).
120
127
  */ _fogPreExposure;
121
- /**
122
- * Creates an instance of SkyRenderer
128
+ /**
129
+ * Creates an instance of SkyRenderer
123
130
  */ constructor(){
124
131
  super();
125
132
  this._skyType = 'scatter';
@@ -166,8 +173,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
166
173
  /** @internal */ getHash(_ctx) {
167
174
  return `${this.skyType}:${this.fogType}`;
168
175
  }
169
- /**
170
- * Gets the preferred environment texture format.
176
+ /**
177
+ * Gets the preferred environment texture format.
171
178
  */ get envTextureFormat() {
172
179
  if (!this._format) {
173
180
  const texCaps = getDevice().getDeviceCaps().textureCaps;
@@ -212,8 +219,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
212
219
  }
213
220
  return this._bakedSkyboxTexture.get();
214
221
  }
215
- /**
216
- * The color used when sky type is `image`
222
+ /**
223
+ * The color used when sky type is `image`
217
224
  */ get skyColor() {
218
225
  return this._skyColor;
219
226
  }
@@ -223,8 +230,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
223
230
  this.invalidate();
224
231
  }
225
232
  }
226
- /**
227
- * The image used when sky type is `image`
233
+ /**
234
+ * The image used when sky type is `image`
228
235
  */ get skyImage() {
229
236
  return this._skyImage.get();
230
237
  }
@@ -234,8 +241,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
234
241
  this.invalidate();
235
242
  }
236
243
  }
237
- /**
238
- * Window weights for SH projection
244
+ /**
245
+ * Window weights for SH projection
239
246
  */ get shWindowWeights() {
240
247
  return this._shWindowWeights;
241
248
  }
@@ -243,8 +250,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
243
250
  this._shWindowWeights.set(weights);
244
251
  this.invalidate();
245
252
  }
246
- /**
247
- * Sample count for radiance convolution
253
+ /**
254
+ * Sample count for radiance convolution
248
255
  */ get radianceConvSamples() {
249
256
  return this._radianceConvSamples;
250
257
  }
@@ -254,8 +261,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
254
261
  this.invalidate();
255
262
  }
256
263
  }
257
- /**
258
- * Sample count for irradiance convolution
264
+ /**
265
+ * Sample count for irradiance convolution
259
266
  */ get irradianceConvSamples() {
260
267
  return this._irradianceConvSamples;
261
268
  }
@@ -382,12 +389,12 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
382
389
  this.invalidate();
383
390
  }
384
391
  }
385
- /**
386
- * Light density of the sky.
387
- *
388
- * @remarks
389
- * This value controls how much cloud should be rendered when the sky type is scatter.
390
- * Typically, the value should be in the range of 0 to 1.
392
+ /**
393
+ * Light density of the sky.
394
+ *
395
+ * @remarks
396
+ * This value controls how much cloud should be rendered when the sky type is scatter.
397
+ * Typically, the value should be in the range of 0 to 1.
391
398
  */ get cloudy() {
392
399
  return this._cloudy;
393
400
  }
@@ -397,8 +404,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
397
404
  this.invalidate();
398
405
  }
399
406
  }
400
- /**
401
- * Intensity of the sky color
407
+ /**
408
+ * Intensity of the sky color
402
409
  */ get cloudIntensity() {
403
410
  return this._cloudIntensity;
404
411
  }
@@ -408,19 +415,19 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
408
415
  this.invalidate();
409
416
  }
410
417
  }
411
- /**
412
- * Wind velocity
413
- *
414
- * @remarks
415
- * This value affects the movement of the cloud
418
+ /**
419
+ * Wind velocity
420
+ *
421
+ * @remarks
422
+ * This value affects the movement of the cloud
416
423
  */ get wind() {
417
424
  return this._wind;
418
425
  }
419
426
  set wind(val) {
420
427
  this._wind.set(val);
421
428
  }
422
- /**
423
- * Radiance map of the sky.
429
+ /**
430
+ * Radiance map of the sky.
424
431
  */ get radianceMap() {
425
432
  if (!this._radianceMap.get()) {
426
433
  this._radianceMap.set(getDevice().createCubeTexture(this.envTextureFormat, this._radianceMapWidth));
@@ -428,11 +435,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
428
435
  }
429
436
  return this._radianceMap.get();
430
437
  }
431
- /**
432
- * Radiance map of the sky reused for sheen.
433
- *
434
- * @remarks
435
- * Dynamic sky is smooth enough that the GGX-prefiltered radiance map is a practical approximation for sheen.
438
+ /**
439
+ * Radiance map of the sky reused for sheen.
440
+ *
441
+ * @remarks
442
+ * Dynamic sky is smooth enough that the GGX-prefiltered radiance map is a practical approximation for sheen.
436
443
  */ get sheenRadianceMap() {
437
444
  return this.radianceMap;
438
445
  }
@@ -450,8 +457,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
450
457
  }
451
458
  return this._radianceFrameBuffer.get();
452
459
  }
453
- /**
454
- * Irradiance SH coeffecients buffer
460
+ /**
461
+ * Irradiance SH coeffecients buffer
455
462
  */ get irradianceSH() {
456
463
  if (!this._irradianceSH.get()) {
457
464
  const buffer = getDevice().createBuffer(4 * 4 * 9, {
@@ -461,8 +468,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
461
468
  }
462
469
  return this._irradianceSH.get();
463
470
  }
464
- /**
465
- * Irradiance SH coeffecients texture
471
+ /**
472
+ * Irradiance SH coeffecients texture
466
473
  */ get irradianceSHFB() {
467
474
  if (!this._irradianceSHFB.get()) {
468
475
  const device = getDevice();
@@ -477,8 +484,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
477
484
  }
478
485
  return this._irradianceSHFB.get();
479
486
  }
480
- /**
481
- * Cube texture for skybox.
487
+ /**
488
+ * Cube texture for skybox.
482
489
  */ get skyboxTexture() {
483
490
  return this._skyboxTexture.get();
484
491
  }
@@ -490,8 +497,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
490
497
  }
491
498
  }
492
499
  }
493
- /**
494
- * Additional euler rotation (in degrees) applied to skybox.
500
+ /**
501
+ * Additional euler rotation (in degrees) applied to skybox.
495
502
  */ get skyboxRotation() {
496
503
  return this._skyboxRotation;
497
504
  }
@@ -534,8 +541,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
534
541
  /** @internal */ get fogPresents() {
535
542
  return this._skyType === 'scatter' || this._fogType !== 'none';
536
543
  }
537
- /**
538
- * Force the radiance map and irradiance map to be regenerated.
544
+ /**
545
+ * Force the radiance map and irradiance map to be regenerated.
539
546
  */ invalidate() {
540
547
  this._bakedSkyboxDirty = true;
541
548
  }
@@ -594,7 +601,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
594
601
  this.updateBakedSkyMap(ctx);
595
602
  this.renderSkyDistantLut(ctx, this._bakedSkyboxTexture.get());
596
603
  }
597
- const newSunLight = oldSunLight ? Vector3.mul(ctx.sunLight.color.xyz(), this.sunTransmittance(ctx.sunLight)) : Vector3.zero();
604
+ // Atmosphere extinction times cloud occlusion. The cloud term intentionally applies only to
605
+ // the scene's directional light, not to the sky bake: the clouds in the cubemap are lit by
606
+ // the unoccluded sun above the layer, and the bake is where their scattered share of the
607
+ // energy re-enters as ambient.
608
+ const newSunLight = oldSunLight ? Vector3.mul(Vector3.mul(ctx.sunLight.color.xyz(), this.sunTransmittance(ctx.sunLight)), this.cloudSunTransmittance(sunDir)) : Vector3.zero();
598
609
  if (oldSunLight) {
599
610
  ctx.sunLight.setColor(newSunLight);
600
611
  }
@@ -701,11 +712,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
701
712
  device.popDeviceStates();
702
713
  device.setRenderStates(saveRenderStates);
703
714
  }
704
- /**
705
- * @internal
706
- * Updates the scene's IBL (GGX-prefiltered specular radiance map + irradiance SH) from the given
707
- * cubemap, provided the scene environment light is still driven by this dynamic sky. Must be called
708
- * with the fog-free cubemap so height fog does not leak into the environment lighting.
715
+ /**
716
+ * @internal
717
+ * Updates the scene's IBL (GGX-prefiltered specular radiance map + irradiance SH) from the given
718
+ * cubemap, provided the scene environment light is still driven by this dynamic sky. Must be called
719
+ * with the fog-free cubemap so height fog does not leak into the environment lighting.
709
720
  */ _updateIBLFromBakedSky(ctx, skybox) {
710
721
  if (ctx.scene.env.light.radianceMap && (ctx.scene.env.light.radianceMap === this.radianceMap || this._irradianceSH.get() && ctx.scene.env.light.irradianceSH === this.irradianceSH || this._irradianceSHFB.get() && ctx.scene.env.light.irradianceSHFB === this.irradianceSHFB)) {
711
722
  prefilterCubemap(skybox, 'ggx', this.radianceFramebuffer, this._radianceConvSamples);
@@ -741,12 +752,12 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
741
752
  device.setRenderStates(renderStates);
742
753
  device.draw('triangle-strip', 0, 4);
743
754
  }
744
- /**
745
- * @internal
746
- * Height-fog upload params with the authored base/directional colors lifted into the pre-exposed
747
- * physical space when physical lighting is active, plus the pre-exposure the shader applies to its
748
- * atmosphere-derived LUT samples. Legacy returns the stored params untouched so its upload stays
749
- * byte-identical. Stored authored values are never mutated.
755
+ /**
756
+ * @internal
757
+ * Height-fog upload params with the authored base/directional colors lifted into the pre-exposed
758
+ * physical space when physical lighting is active, plus the pre-exposure the shader applies to its
759
+ * atmosphere-derived LUT samples. Legacy returns the stored params untouched so its upload stays
760
+ * byte-identical. Stored authored values are never mutated.
750
761
  */ _getUploadHeightFogParams() {
751
762
  const scale = this._fogLuminanceScale;
752
763
  const p = this._heightFogParams;
@@ -779,14 +790,14 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
779
790
  const savedRenderStates = device.getRenderStates();
780
791
  this._prepareSkyBox(device);
781
792
  this.renderUberFog(camera, depthBuffer);
782
- /*
783
- if (this._skyType === 'scatter') {
784
- this.renderAtmosphericFog(ctx, depthBuffer);
785
- }
786
- */ /*
787
- if (this._fogType === 'height_fog') {
788
- this.renderHeightFog(ctx, depthBuffer);
789
- }
793
+ /*
794
+ if (this._skyType === 'scatter') {
795
+ this.renderAtmosphericFog(ctx, depthBuffer);
796
+ }
797
+ */ /*
798
+ if (this._fogType === 'height_fog') {
799
+ this.renderHeightFog(ctx, depthBuffer);
800
+ }
790
801
  */ device.setRenderStates(savedRenderStates);
791
802
  if (fogFramebuffer) {
792
803
  device.popDeviceStates();
@@ -888,33 +899,33 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
888
899
  }
889
900
  device.setRenderStates(savedRenderStates);
890
901
  }
891
- /**
892
- * @internal
893
- *
894
- * Converts a value stored at {@link PHYSICAL_BAKE_EXPOSURE} into the live pre-exposed space.
895
- *
896
- * @remarks
897
- * Everything derived from the cached sky bake (the IBL, the distant-light LUT, the visible baked
898
- * skybox) is stored at the fixed reference exposure. Multiplying by this ratio yields the same
899
- * result as if the live camera exposure had been baked in, without invalidating the cache when
900
- * the camera stops down. Returns 1 in legacy.
902
+ /**
903
+ * @internal
904
+ *
905
+ * Converts a value stored at {@link PHYSICAL_BAKE_EXPOSURE} into the live pre-exposed space.
906
+ *
907
+ * @remarks
908
+ * Everything derived from the cached sky bake (the IBL, the distant-light LUT, the visible baked
909
+ * skybox) is stored at the fixed reference exposure. Multiplying by this ratio yields the same
910
+ * result as if the live camera exposure had been baked in, without invalidating the cache when
911
+ * the camera stops down. Returns 1 in legacy.
901
912
  */ static getBakeToPreExposedScale(ctx) {
902
913
  return ctx.scene.lightingMode === 'physical' ? ShaderHelper.getPreExposure(ctx) / SkyRenderer.PHYSICAL_BAKE_EXPOSURE : 1;
903
914
  }
904
- /**
905
- * @internal
906
- *
907
- * Scale that normalizes a sky into the IBL bake's storage space.
908
- *
909
- * @remarks
910
- * An authored 0..1 `skybox` / `image` is treated as an emitter of `EnvLightWrapper.intensity` lux.
911
- * The scattering atmosphere needs no lift: its LUTs already carry photometric sun illuminance.
912
- *
913
- * Both are then scaled to {@link PHYSICAL_BAKE_EXPOSURE}. The bake is cached and only invalidated
914
- * by sun changes, so it must be exposure-independent; storing it at raw photometric magnitude
915
- * would overflow the environment cubemap's float range (see {@link PHYSICAL_BAKE_EXPOSURE}).
916
- *
917
- * Returns 1 in legacy so its bake stays byte-identical.
915
+ /**
916
+ * @internal
917
+ *
918
+ * Scale that normalizes a sky into the IBL bake's storage space.
919
+ *
920
+ * @remarks
921
+ * An authored 0..1 `skybox` / `image` is treated as an emitter of `EnvLightWrapper.intensity` lux.
922
+ * The scattering atmosphere needs no lift: its LUTs already carry photometric sun illuminance.
923
+ *
924
+ * Both are then scaled to {@link PHYSICAL_BAKE_EXPOSURE}. The bake is cached and only invalidated
925
+ * by sun changes, so it must be exposure-independent; storing it at raw photometric magnitude
926
+ * would overflow the environment cubemap's float range (see {@link PHYSICAL_BAKE_EXPOSURE}).
927
+ *
928
+ * Returns 1 in legacy so its bake stays byte-identical.
918
929
  */ _getSkyBakeLuminanceScale(ctx) {
919
930
  if (ctx.scene.lightingMode !== 'physical') {
920
931
  return 1;
@@ -922,11 +933,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
922
933
  // scatter already includes the bake exposure via renderAtmosphereLUTs().
923
934
  return this._skyType === 'scatter' ? 1 : ctx.scene.env.light.intensity * SkyRenderer.PHYSICAL_BAKE_EXPOSURE;
924
935
  }
925
- /**
926
- * @internal
927
- *
928
- * On-screen sky scale: the bake-time normalization converted from the stored reference exposure
929
- * to the live one, so the visible sky lands in the same pre-exposed space as every lit surface.
936
+ /**
937
+ * @internal
938
+ *
939
+ * On-screen sky scale: the bake-time normalization converted from the stored reference exposure
940
+ * to the live one, so the visible sky lands in the same pre-exposed space as every lit surface.
930
941
  */ _getSkyScreenLuminanceScale(ctx) {
931
942
  return this._getSkyBakeLuminanceScale(ctx) * SkyRenderer.getBakeToPreExposedScale(ctx);
932
943
  }
@@ -969,6 +980,31 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
969
980
  const t2 = SH + PH;
970
981
  return t1 < 0 ? t2 : t1;
971
982
  }
983
+ /**
984
+ * Transmittance of the cloud layer along the sun direction.
985
+ *
986
+ * @remarks
987
+ * Energy-conservation counterpart of the clouds baked into the environment map: the light the
988
+ * cloud layer scatters into the sky dome has to be removed from the direct sun, otherwise
989
+ * raising cloud density only ever adds energy. This method is the seam where a future cloud
990
+ * renderer plugs in; a volumetric implementation should replace it with the transmittance
991
+ * ray-marched toward the sun (spectral, hence a Vector3).
992
+ *
993
+ * The procedural 2D cloud has no real optical depth, so the sun direction is unused and the
994
+ * result is a gray-scale estimate from coverage alone. In the scatter shader, cloud opacity is
995
+ * `smoothStep(1, 1 + cloudy, noise + cloudy)`: by `cloudy = 1` the whole 0..1-ish fbm noise
996
+ * range falls inside the ramp, i.e. the sky is visually fully covered. `cloudy` (clamped to
997
+ * 0..1) is therefore used directly as the sky coverage. Squaring it accounts for thin/partial
998
+ * clouds at low coverage barely attenuating the sun, while full cover drops to the
999
+ * heavy-overcast floor {@link SkyRenderer.CLOUD_SUN_MIN_TRANSMITTANCE}.
1000
+ */ cloudSunTransmittance(_sunDir) {
1001
+ if (this._skyType !== 'scatter') {
1002
+ return Vector3.one();
1003
+ }
1004
+ const coverage = Math.min(1, Math.max(0, this._cloudy));
1005
+ const t = 1 - coverage * coverage * (1 - SkyRenderer.CLOUD_SUN_MIN_TRANSMITTANCE);
1006
+ return new Vector3(t, t, t);
1007
+ }
972
1008
  /** @internal */ sunTransmittance(sunLight) {
973
1009
  const TRANSMITTANCE_SAMPLES = 32;
974
1010
  const RAYLEIGH_SIGMA = [
@@ -1204,13 +1240,17 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
1204
1240
  if (!SkyRenderer._renderStatesFog) {
1205
1241
  SkyRenderer._renderStatesFog = device.createRenderStateSet();
1206
1242
  SkyRenderer._renderStatesFog.useRasterizerState().setCullMode('none');
1207
- SkyRenderer._renderStatesFog.useBlendingState().enable(true).setBlendFunc('one', 'src-alpha');
1243
+ // RGB composites premultiplied inscattering over the scene weighted by transmittance. Alpha is
1244
+ // left untouched: `src-alpha` applied to the alpha channel too would fold transmittance into
1245
+ // the framebuffer coverage (dstA = T + dstA * T), so dense fog drove the backbuffer alpha
1246
+ // toward 0 and the page showed through wherever the canvas alpha is composited.
1247
+ SkyRenderer._renderStatesFog.useBlendingState().enable(true).setBlendFuncRGB('one', 'src-alpha').setBlendFuncAlpha('zero', 'one');
1208
1248
  SkyRenderer._renderStatesFog.useDepthState().enableTest(false).enableWrite(false);
1209
1249
  }
1210
1250
  if (!SkyRenderer._renderStatesFogScatter) {
1211
1251
  SkyRenderer._renderStatesFogScatter = device.createRenderStateSet();
1212
1252
  SkyRenderer._renderStatesFogScatter.useRasterizerState().setCullMode('none');
1213
- SkyRenderer._renderStatesFogScatter.useBlendingState().enable(true).setBlendFunc('one', 'src-alpha');
1253
+ SkyRenderer._renderStatesFogScatter.useBlendingState().enable(true).setBlendFuncRGB('one', 'src-alpha').setBlendFuncAlpha('zero', 'one');
1214
1254
  SkyRenderer._renderStatesFogScatter.useDepthState().enableTest(true).enableWrite(false).setCompareFunc(DEPTH_COMPARE_FARTHER);
1215
1255
  }
1216
1256
  if (!SkyRenderer._renderStatesDistantLight) {
@@ -1402,11 +1442,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
1402
1442
  this.noiseValue = pb.smoothStep(1, pb.add(1, this.cloudy), this.noiseValue);
1403
1443
  });
1404
1444
  // use sun color as cloud color
1405
- /*
1406
- this.$l.sunColor = pb.mul(
1407
- pb.textureSampleLevel(this.skyLut, viewDirToUV(this, this.sunDir), 0),
1408
- this.sunIntensity
1409
- );
1445
+ /*
1446
+ this.$l.sunColor = pb.mul(
1447
+ pb.textureSampleLevel(this.skyLut, viewDirToUV(this, this.sunDir), 0),
1448
+ this.sunIntensity
1449
+ );
1410
1450
  */ this.$l.cloudColor = pb.mul(this.sunColor.rgb, this.sunIntensity, pb.mul(this.noiseValue, this.cloudIntensity));
1411
1451
  }
1412
1452
  // Compute sky color