@zephyr3d/scene 0.6.1 → 0.7.1

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 (754) hide show
  1. package/dist/animation/animation.js +142 -31
  2. package/dist/animation/animation.js.map +1 -1
  3. package/dist/animation/animationset.js +186 -73
  4. package/dist/animation/animationset.js.map +1 -1
  5. package/dist/animation/animationtrack.js +66 -10
  6. package/dist/animation/animationtrack.js.map +1 -1
  7. package/dist/animation/eulerrotationtrack.js +40 -20
  8. package/dist/animation/eulerrotationtrack.js.map +1 -1
  9. package/dist/animation/morphtarget.js +20 -38
  10. package/dist/animation/morphtarget.js.map +1 -1
  11. package/dist/animation/morphtrack.js +59 -22
  12. package/dist/animation/morphtrack.js.map +1 -1
  13. package/dist/animation/proptrack.js +186 -0
  14. package/dist/animation/proptrack.js.map +1 -0
  15. package/dist/animation/rotationtrack.js +28 -11
  16. package/dist/animation/rotationtrack.js.map +1 -1
  17. package/dist/animation/scaletrack.js +28 -11
  18. package/dist/animation/scaletrack.js.map +1 -1
  19. package/dist/animation/skeleton.js +238 -82
  20. package/dist/animation/skeleton.js.map +1 -1
  21. package/dist/animation/translationtrack.js +29 -11
  22. package/dist/animation/translationtrack.js.map +1 -1
  23. package/dist/app/api.js +52 -0
  24. package/dist/app/api.js.map +1 -0
  25. package/dist/app/app.js +165 -0
  26. package/dist/app/app.js.map +1 -0
  27. package/dist/app/engine.js +300 -0
  28. package/dist/app/engine.js.map +1 -0
  29. package/dist/app/inputmgr.js +351 -0
  30. package/dist/app/inputmgr.js.map +1 -0
  31. package/dist/app/runtimescript.js +62 -0
  32. package/dist/app/runtimescript.js.map +1 -0
  33. package/dist/app/screen.js +318 -0
  34. package/dist/app/screen.js.map +1 -0
  35. package/dist/app/scriptingsystem.js +224 -0
  36. package/dist/app/scriptingsystem.js.map +1 -0
  37. package/dist/app/scriptregistry.js +421 -0
  38. package/dist/app/scriptregistry.js.map +1 -0
  39. package/dist/asset/assetmanager.js +823 -321
  40. package/dist/asset/assetmanager.js.map +1 -1
  41. package/dist/asset/builtin.js +12 -48
  42. package/dist/asset/builtin.js.map +1 -1
  43. package/dist/asset/loaders/dds/dds.js +23 -95
  44. package/dist/asset/loaders/dds/dds.js.map +1 -1
  45. package/dist/asset/loaders/dds/dds_loader.js +9 -19
  46. package/dist/asset/loaders/dds/dds_loader.js.map +1 -1
  47. package/dist/asset/loaders/gltf/gltf_loader.js +50 -48
  48. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  49. package/dist/asset/loaders/gltf/helpers.js +33 -16
  50. package/dist/asset/loaders/gltf/helpers.js.map +1 -1
  51. package/dist/asset/loaders/hdr/hdr.js +39 -27
  52. package/dist/asset/loaders/hdr/hdr.js.map +1 -1
  53. package/dist/asset/loaders/image/tga_Loader.js +15 -17
  54. package/dist/asset/loaders/image/tga_Loader.js.map +1 -1
  55. package/dist/asset/loaders/image/webimage_loader.js +51 -50
  56. package/dist/asset/loaders/image/webimage_loader.js.map +1 -1
  57. package/dist/asset/loaders/loader.js +2 -2
  58. package/dist/asset/loaders/loader.js.map +1 -1
  59. package/dist/asset/model.js +160 -6
  60. package/dist/asset/model.js.map +1 -1
  61. package/dist/blitter/bilateralblur.js +0 -1
  62. package/dist/blitter/bilateralblur.js.map +1 -1
  63. package/dist/blitter/blitter.js +28 -31
  64. package/dist/blitter/blitter.js.map +1 -1
  65. package/dist/blitter/box.js +0 -1
  66. package/dist/blitter/box.js.map +1 -1
  67. package/dist/blitter/copy.js.map +1 -1
  68. package/dist/blitter/gaussianblur.js +23 -23
  69. package/dist/blitter/gaussianblur.js.map +1 -1
  70. package/dist/camera/base.js +139 -34
  71. package/dist/camera/base.js.map +1 -1
  72. package/dist/camera/camera.js +760 -172
  73. package/dist/camera/camera.js.map +1 -1
  74. package/dist/camera/fps.js +21 -27
  75. package/dist/camera/fps.js.map +1 -1
  76. package/dist/camera/orbit.js +134 -59
  77. package/dist/camera/orbit.js.map +1 -1
  78. package/dist/camera/orthocamera.js +52 -21
  79. package/dist/camera/orthocamera.js.map +1 -1
  80. package/dist/camera/perspectivecamera.js +60 -34
  81. package/dist/camera/perspectivecamera.js.map +1 -1
  82. package/dist/index.d.ts +17031 -6901
  83. package/dist/index.js +60 -21
  84. package/dist/index.js.map +1 -1
  85. package/dist/material/blinn.js +5 -0
  86. package/dist/material/blinn.js.map +1 -1
  87. package/dist/material/grassmaterial.js +6 -1
  88. package/dist/material/grassmaterial.js.map +1 -1
  89. package/dist/material/lambert.js +6 -1
  90. package/dist/material/lambert.js.map +1 -1
  91. package/dist/material/material.js +356 -77
  92. package/dist/material/material.js.map +1 -1
  93. package/dist/material/meshmaterial.js +505 -162
  94. package/dist/material/meshmaterial.js.map +1 -1
  95. package/dist/material/mixins/albedocolor.js +5 -1
  96. package/dist/material/mixins/albedocolor.js.map +1 -1
  97. package/dist/material/mixins/foliage.js +3 -3
  98. package/dist/material/mixins/foliage.js.map +1 -1
  99. package/dist/material/mixins/lightmodel/blinnphong.js +18 -5
  100. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  101. package/dist/material/mixins/lightmodel/lambert.js +6 -6
  102. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  103. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +242 -0
  104. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -0
  105. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +52 -15
  106. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  107. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +27 -9
  108. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  109. package/dist/material/mixins/lit.js +19 -7
  110. package/dist/material/mixins/lit.js.map +1 -1
  111. package/dist/material/mixins/pbr/brdf.js +134 -0
  112. package/dist/material/mixins/pbr/brdf.js.map +1 -0
  113. package/dist/material/mixins/pbr/common.js +68 -85
  114. package/dist/material/mixins/pbr/common.js.map +1 -1
  115. package/dist/material/mixins/texture.js +101 -83
  116. package/dist/material/mixins/texture.js.map +1 -1
  117. package/dist/material/mixins/vertexcolor.js +6 -2
  118. package/dist/material/mixins/vertexcolor.js.map +1 -1
  119. package/dist/material/particle.js +272 -0
  120. package/dist/material/particle.js.map +1 -0
  121. package/dist/material/pbrblueprint.js +344 -0
  122. package/dist/material/pbrblueprint.js.map +1 -0
  123. package/dist/material/pbrmr.js +10 -0
  124. package/dist/material/pbrmr.js.map +1 -1
  125. package/dist/material/pbrsg.js +10 -0
  126. package/dist/material/pbrsg.js.map +1 -1
  127. package/dist/material/shader/helper.js +533 -316
  128. package/dist/material/shader/helper.js.map +1 -1
  129. package/dist/material/sprite.js +301 -0
  130. package/dist/material/sprite.js.map +1 -0
  131. package/dist/material/sprite3d.js +301 -0
  132. package/dist/material/sprite3d.js.map +1 -0
  133. package/dist/material/sprite3d_std.js +116 -0
  134. package/dist/material/sprite3d_std.js.map +1 -0
  135. package/dist/material/sprite3dblueprint.js +235 -0
  136. package/dist/material/sprite3dblueprint.js.map +1 -0
  137. package/dist/material/sprite_std.js +116 -0
  138. package/dist/material/sprite_std.js.map +1 -0
  139. package/dist/material/spriteblueprint.js +235 -0
  140. package/dist/material/spriteblueprint.js.map +1 -0
  141. package/dist/material/terrain-cm.js +606 -0
  142. package/dist/material/terrain-cm.js.map +1 -0
  143. package/dist/material/terrainmaterial.js +59 -54
  144. package/dist/material/terrainmaterial.js.map +1 -1
  145. package/dist/material/unlit.js +5 -0
  146. package/dist/material/unlit.js.map +1 -1
  147. package/dist/material/water.js +415 -0
  148. package/dist/material/water.js.map +1 -0
  149. package/dist/node_modules/@zephyr3d/runtime/dist/runtime/runtimemgr.js +38 -0
  150. package/dist/node_modules/@zephyr3d/runtime/dist/runtime/runtimemgr.js.map +1 -0
  151. package/dist/node_modules/@zephyr3d/runtime/dist/runtime/runtimescript.js +10 -0
  152. package/dist/node_modules/@zephyr3d/runtime/dist/runtime/runtimescript.js.map +1 -0
  153. package/dist/node_modules/@zephyr3d/runtime/dist/runtime/scriptingsystem.js +127 -0
  154. package/dist/node_modules/@zephyr3d/runtime/dist/runtime/scriptingsystem.js.map +1 -0
  155. package/dist/node_modules/@zephyr3d/runtime/dist/runtime/scriptregistry.js +263 -0
  156. package/dist/node_modules/@zephyr3d/runtime/dist/runtime/scriptregistry.js.map +1 -0
  157. package/dist/node_modules/es-module-lexer/dist/lexer.js +5 -0
  158. package/dist/node_modules/es-module-lexer/dist/lexer.js.map +1 -0
  159. package/dist/posteffect/bloom.js +39 -54
  160. package/dist/posteffect/bloom.js.map +1 -1
  161. package/dist/posteffect/compositor.js +95 -128
  162. package/dist/posteffect/compositor.js.map +1 -1
  163. package/dist/posteffect/fxaa.js +10 -18
  164. package/dist/posteffect/fxaa.js.map +1 -1
  165. package/dist/posteffect/grayscale.js +9 -17
  166. package/dist/posteffect/grayscale.js.map +1 -1
  167. package/dist/posteffect/motionblur.js +105 -0
  168. package/dist/posteffect/motionblur.js.map +1 -0
  169. package/dist/posteffect/posteffect.js +66 -35
  170. package/dist/posteffect/posteffect.js.map +1 -1
  171. package/dist/posteffect/sao.js +13 -21
  172. package/dist/posteffect/sao.js.map +1 -1
  173. package/dist/posteffect/ssr.js +65 -103
  174. package/dist/posteffect/ssr.js.map +1 -1
  175. package/dist/posteffect/taa.js +175 -0
  176. package/dist/posteffect/taa.js.map +1 -0
  177. package/dist/posteffect/tonemap.js +12 -20
  178. package/dist/posteffect/tonemap.js.map +1 -1
  179. package/dist/render/abuffer_oit.js +38 -25
  180. package/dist/render/abuffer_oit.js.map +1 -1
  181. package/dist/render/clipmap.js +424 -106
  182. package/dist/render/clipmap.js.map +1 -1
  183. package/dist/render/cluster_light.js +11 -9
  184. package/dist/render/cluster_light.js.map +1 -1
  185. package/dist/render/cull_visitor.js +51 -13
  186. package/dist/render/cull_visitor.js.map +1 -1
  187. package/dist/render/depthpass.js +15 -7
  188. package/dist/render/depthpass.js.map +1 -1
  189. package/dist/render/drawable.js +15 -0
  190. package/dist/render/drawable.js.map +1 -0
  191. package/dist/render/drawable_mixin.js +121 -44
  192. package/dist/render/drawable_mixin.js.map +1 -1
  193. package/dist/render/envlight.js +86 -141
  194. package/dist/render/envlight.js.map +1 -1
  195. package/dist/render/fbm_wavegenerator.js +236 -0
  196. package/dist/render/fbm_wavegenerator.js.map +1 -0
  197. package/dist/render/fft_wavegenerator.js +131 -114
  198. package/dist/render/fft_wavegenerator.js.map +1 -1
  199. package/dist/render/fullscreenquad.js +2 -2
  200. package/dist/render/fullscreenquad.js.map +1 -1
  201. package/dist/render/gerstner_wavegenerator.js +100 -48
  202. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  203. package/dist/render/globalbindgroup_allocator.js +7 -3
  204. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  205. package/dist/render/hzb.js +7 -5
  206. package/dist/render/hzb.js.map +1 -1
  207. package/dist/render/lightpass.js +28 -27
  208. package/dist/render/lightpass.js.map +1 -1
  209. package/dist/render/objectcolorpass.js +6 -9
  210. package/dist/render/objectcolorpass.js.map +1 -1
  211. package/dist/render/primitive.js +213 -105
  212. package/dist/render/primitive.js.map +1 -1
  213. package/dist/render/render_queue.js +49 -24
  214. package/dist/render/render_queue.js.map +1 -1
  215. package/dist/render/renderbundle_wrapper.js +65 -15
  216. package/dist/render/renderbundle_wrapper.js.map +1 -1
  217. package/dist/render/renderer.js +324 -189
  218. package/dist/render/renderer.js.map +1 -1
  219. package/dist/render/renderpass.js +43 -84
  220. package/dist/render/renderpass.js.map +1 -1
  221. package/dist/render/rendertarget.js +5 -0
  222. package/dist/render/rendertarget.js.map +1 -0
  223. package/dist/render/screenrendertarget.js +56 -0
  224. package/dist/render/screenrendertarget.js.map +1 -0
  225. package/dist/render/shadowmap_pass.js +5 -6
  226. package/dist/render/shadowmap_pass.js.map +1 -1
  227. package/dist/render/sky.js +867 -542
  228. package/dist/render/sky.js.map +1 -1
  229. package/dist/render/weightedblended_oit.js +13 -15
  230. package/dist/render/weightedblended_oit.js.map +1 -1
  231. package/dist/scene/basesprite.js +296 -0
  232. package/dist/scene/basesprite.js.map +1 -0
  233. package/dist/scene/batchgroup.js +22 -7
  234. package/dist/scene/batchgroup.js.map +1 -1
  235. package/dist/scene/environment.js +78 -49
  236. package/dist/scene/environment.js.map +1 -1
  237. package/dist/scene/graph_node.js +2 -3
  238. package/dist/scene/graph_node.js.map +1 -1
  239. package/dist/scene/light.js +49 -92
  240. package/dist/scene/light.js.map +1 -1
  241. package/dist/scene/mesh.js +298 -89
  242. package/dist/scene/mesh.js.map +1 -1
  243. package/dist/scene/octree.js +371 -162
  244. package/dist/scene/octree.js.map +1 -1
  245. package/dist/scene/particlesys.js +687 -0
  246. package/dist/scene/particlesys.js.map +1 -0
  247. package/dist/scene/raycast_visitor.js +26 -13
  248. package/dist/scene/raycast_visitor.js.map +1 -1
  249. package/dist/scene/scene.js +312 -85
  250. package/dist/scene/scene.js.map +1 -1
  251. package/dist/scene/scene_node.js +663 -105
  252. package/dist/scene/scene_node.js.map +1 -1
  253. package/dist/scene/sprite.js +18 -0
  254. package/dist/scene/sprite.js.map +1 -0
  255. package/dist/scene/sprite3d.js +18 -0
  256. package/dist/scene/sprite3d.js.map +1 -0
  257. package/dist/scene/terrain/grass.js +48 -49
  258. package/dist/scene/terrain/grass.js.map +1 -1
  259. package/dist/scene/terrain/heightfield.js +46 -44
  260. package/dist/scene/terrain/heightfield.js.map +1 -1
  261. package/dist/scene/terrain/patch.js +20 -29
  262. package/dist/scene/terrain/patch.js.map +1 -1
  263. package/dist/scene/terrain/quadtree.js +58 -27
  264. package/dist/scene/terrain/quadtree.js.map +1 -1
  265. package/dist/scene/terrain/terrain.js +31 -45
  266. package/dist/scene/terrain/terrain.js.map +1 -1
  267. package/dist/scene/terrain-cm/grass.js +604 -0
  268. package/dist/scene/terrain-cm/grass.js.map +1 -0
  269. package/dist/scene/terrain-cm/grassmaterial.js +162 -0
  270. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -0
  271. package/dist/scene/terrain-cm/terrain-cm.js +550 -0
  272. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -0
  273. package/dist/scene/water.js +383 -0
  274. package/dist/scene/water.js.map +1 -0
  275. package/dist/shaders/atmosphere.js +945 -0
  276. package/dist/shaders/atmosphere.js.map +1 -0
  277. package/dist/shaders/fog.js +116 -0
  278. package/dist/shaders/fog.js.map +1 -0
  279. package/dist/shaders/misc.js.map +1 -1
  280. package/dist/shaders/noise.js +217 -8
  281. package/dist/shaders/noise.js.map +1 -1
  282. package/dist/shaders/pbr.js.map +1 -1
  283. package/dist/shaders/shadow.js +8 -8
  284. package/dist/shaders/shadow.js.map +1 -1
  285. package/dist/shaders/ssr.js +87 -39
  286. package/dist/shaders/ssr.js.map +1 -1
  287. package/dist/shaders/temporal.js +216 -0
  288. package/dist/shaders/temporal.js.map +1 -0
  289. package/dist/shaders/water.js +42 -20
  290. package/dist/shaders/water.js.map +1 -1
  291. package/dist/shadow/esm.js +32 -14
  292. package/dist/shadow/esm.js.map +1 -1
  293. package/dist/shadow/pcf_opt.js +12 -13
  294. package/dist/shadow/pcf_opt.js.map +1 -1
  295. package/dist/shadow/pcf_pd.js +12 -13
  296. package/dist/shadow/pcf_pd.js.map +1 -1
  297. package/dist/shadow/shader.js +40 -0
  298. package/dist/shadow/shader.js.map +1 -0
  299. package/dist/shadow/shadow_impl.js.map +1 -1
  300. package/dist/shadow/shadowmapper.js +73 -44
  301. package/dist/shadow/shadowmapper.js.map +1 -1
  302. package/dist/shadow/ssm.js +15 -16
  303. package/dist/shadow/ssm.js.map +1 -1
  304. package/dist/shadow/vsm.js +33 -16
  305. package/dist/shadow/vsm.js.map +1 -1
  306. package/dist/shapes/box.js +187 -83
  307. package/dist/shapes/box.js.map +1 -1
  308. package/dist/shapes/cylinder.js +101 -43
  309. package/dist/shapes/cylinder.js.map +1 -1
  310. package/dist/shapes/plane.js +70 -29
  311. package/dist/shapes/plane.js.map +1 -1
  312. package/dist/shapes/shape.js +121 -17
  313. package/dist/shapes/shape.js.map +1 -1
  314. package/dist/shapes/sphere.js +78 -44
  315. package/dist/shapes/sphere.js.map +1 -1
  316. package/dist/shapes/tetrahedron.js +255 -0
  317. package/dist/shapes/tetrahedron.js.map +1 -0
  318. package/dist/shapes/torus.js +76 -55
  319. package/dist/shapes/torus.js.map +1 -1
  320. package/dist/src/animation/animation.js +127 -0
  321. package/dist/src/animation/animation.js.map +1 -0
  322. package/dist/src/animation/animationset.js +255 -0
  323. package/dist/src/animation/animationset.js.map +1 -0
  324. package/dist/src/animation/animationtrack.js +34 -0
  325. package/dist/src/animation/animationtrack.js.map +1 -0
  326. package/dist/src/animation/eulerrotationtrack.js +52 -0
  327. package/dist/src/animation/eulerrotationtrack.js.map +1 -0
  328. package/dist/src/animation/morphtarget.js +93 -0
  329. package/dist/src/animation/morphtarget.js.map +1 -0
  330. package/dist/src/animation/morphtrack.js +70 -0
  331. package/dist/src/animation/morphtrack.js.map +1 -0
  332. package/dist/src/animation/proptrack.js +161 -0
  333. package/dist/src/animation/proptrack.js.map +1 -0
  334. package/dist/src/animation/rotationtrack.js +51 -0
  335. package/dist/src/animation/rotationtrack.js.map +1 -0
  336. package/dist/src/animation/scaletrack.js +50 -0
  337. package/dist/src/animation/scaletrack.js.map +1 -0
  338. package/dist/src/animation/skeleton.js +204 -0
  339. package/dist/src/animation/skeleton.js.map +1 -0
  340. package/dist/src/animation/translationtrack.js +50 -0
  341. package/dist/src/animation/translationtrack.js.map +1 -0
  342. package/dist/{app.js → src/app/app.js} +18 -40
  343. package/dist/src/app/app.js.map +1 -0
  344. package/dist/{input → src/app}/inputmgr.js +41 -16
  345. package/dist/src/app/inputmgr.js.map +1 -0
  346. package/dist/src/asset/assetmanager.js +404 -0
  347. package/dist/src/asset/assetmanager.js.map +1 -0
  348. package/dist/src/asset/builtin.js +337 -0
  349. package/dist/src/asset/builtin.js.map +1 -0
  350. package/dist/src/asset/loaders/dds/dds.js +470 -0
  351. package/dist/src/asset/loaders/dds/dds.js.map +1 -0
  352. package/dist/src/asset/loaders/dds/dds_loader.js +28 -0
  353. package/dist/src/asset/loaders/dds/dds_loader.js.map +1 -0
  354. package/dist/src/asset/loaders/gltf/gltf_loader.js +1265 -0
  355. package/dist/src/asset/loaders/gltf/gltf_loader.js.map +1 -0
  356. package/dist/src/asset/loaders/gltf/helpers.js +327 -0
  357. package/dist/src/asset/loaders/gltf/helpers.js.map +1 -0
  358. package/dist/src/asset/loaders/hdr/hdr.js +180 -0
  359. package/dist/src/asset/loaders/hdr/hdr.js.map +1 -0
  360. package/dist/src/asset/loaders/image/tga_Loader.js +116 -0
  361. package/dist/src/asset/loaders/image/tga_Loader.js.map +1 -0
  362. package/dist/src/asset/loaders/image/webimage_loader.js +63 -0
  363. package/dist/src/asset/loaders/image/webimage_loader.js.map +1 -0
  364. package/dist/src/asset/loaders/loader.js +45 -0
  365. package/dist/src/asset/loaders/loader.js.map +1 -0
  366. package/dist/src/asset/model.js +414 -0
  367. package/dist/src/asset/model.js.map +1 -0
  368. package/dist/{blitter/depthlimitedgaussion.js → src/blitter/bilateralblur.js} +1 -2
  369. package/dist/src/blitter/bilateralblur.js.map +1 -0
  370. package/dist/src/blitter/blitter.js +390 -0
  371. package/dist/src/blitter/blitter.js.map +1 -0
  372. package/dist/src/blitter/box.js +118 -0
  373. package/dist/src/blitter/box.js.map +1 -0
  374. package/dist/src/blitter/copy.js +22 -0
  375. package/dist/src/blitter/copy.js.map +1 -0
  376. package/dist/src/blitter/gaussianblur.js +228 -0
  377. package/dist/src/blitter/gaussianblur.js.map +1 -0
  378. package/dist/src/camera/base.js +92 -0
  379. package/dist/src/camera/base.js.map +1 -0
  380. package/dist/src/camera/camera.js +1005 -0
  381. package/dist/src/camera/camera.js.map +1 -0
  382. package/dist/src/camera/fps.js +238 -0
  383. package/dist/src/camera/fps.js.map +1 -0
  384. package/dist/src/camera/orbit.js +245 -0
  385. package/dist/src/camera/orbit.js.map +1 -0
  386. package/dist/src/camera/orthocamera.js +167 -0
  387. package/dist/src/camera/orthocamera.js.map +1 -0
  388. package/dist/src/camera/perspectivecamera.js +141 -0
  389. package/dist/src/camera/perspectivecamera.js.map +1 -0
  390. package/dist/src/index.js +120 -0
  391. package/dist/src/index.js.map +1 -0
  392. package/dist/src/material/blinn.js +81 -0
  393. package/dist/src/material/blinn.js.map +1 -0
  394. package/dist/src/material/grassmaterial.js +113 -0
  395. package/dist/src/material/grassmaterial.js.map +1 -0
  396. package/dist/src/material/lambert.js +92 -0
  397. package/dist/src/material/lambert.js.map +1 -0
  398. package/dist/src/material/material.js +301 -0
  399. package/dist/src/material/material.js.map +1 -0
  400. package/dist/src/material/meshmaterial.js +704 -0
  401. package/dist/src/material/meshmaterial.js.map +1 -0
  402. package/dist/src/material/mixins/albedocolor.js +76 -0
  403. package/dist/src/material/mixins/albedocolor.js.map +1 -0
  404. package/dist/src/material/mixins/foliage.js +47 -0
  405. package/dist/src/material/mixins/foliage.js.map +1 -0
  406. package/dist/src/material/mixins/lightmodel/blinnphong.js +112 -0
  407. package/dist/src/material/mixins/lightmodel/blinnphong.js.map +1 -0
  408. package/dist/src/material/mixins/lightmodel/lambert.js +58 -0
  409. package/dist/src/material/mixins/lightmodel/lambert.js.map +1 -0
  410. package/dist/src/material/mixins/lightmodel/pbrmetallicroughness.js +178 -0
  411. package/dist/src/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -0
  412. package/dist/src/material/mixins/lightmodel/pbrspecularglossness.js +139 -0
  413. package/dist/src/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -0
  414. package/dist/src/material/mixins/lit.js +476 -0
  415. package/dist/src/material/mixins/lit.js.map +1 -0
  416. package/dist/src/material/mixins/pbr/common.js +918 -0
  417. package/dist/src/material/mixins/pbr/common.js.map +1 -0
  418. package/dist/src/material/mixins/texture.js +172 -0
  419. package/dist/src/material/mixins/texture.js.map +1 -0
  420. package/dist/src/material/mixins/vertexcolor.js +56 -0
  421. package/dist/src/material/mixins/vertexcolor.js.map +1 -0
  422. package/dist/src/material/particle.js +178 -0
  423. package/dist/src/material/particle.js.map +1 -0
  424. package/dist/src/material/pbrmr.js +97 -0
  425. package/dist/src/material/pbrmr.js.map +1 -0
  426. package/dist/src/material/pbrsg.js +97 -0
  427. package/dist/src/material/pbrsg.js.map +1 -0
  428. package/dist/src/material/shader/helper.js +1209 -0
  429. package/dist/src/material/shader/helper.js.map +1 -0
  430. package/dist/src/material/terrain-cm.js +606 -0
  431. package/dist/src/material/terrain-cm.js.map +1 -0
  432. package/dist/src/material/terrainmaterial.js +375 -0
  433. package/dist/src/material/terrainmaterial.js.map +1 -0
  434. package/dist/src/material/unlit.js +41 -0
  435. package/dist/src/material/unlit.js.map +1 -0
  436. package/dist/src/material/water.js +417 -0
  437. package/dist/src/material/water.js.map +1 -0
  438. package/dist/src/posteffect/bloom.js +361 -0
  439. package/dist/src/posteffect/bloom.js.map +1 -0
  440. package/dist/src/posteffect/compositor.js +226 -0
  441. package/dist/src/posteffect/compositor.js.map +1 -0
  442. package/dist/src/posteffect/fxaa.js +273 -0
  443. package/dist/src/posteffect/fxaa.js.map +1 -0
  444. package/dist/src/posteffect/grayscale.js +69 -0
  445. package/dist/src/posteffect/grayscale.js.map +1 -0
  446. package/dist/src/posteffect/motionblur.js +96 -0
  447. package/dist/src/posteffect/motionblur.js.map +1 -0
  448. package/dist/src/posteffect/posteffect.js +126 -0
  449. package/dist/src/posteffect/posteffect.js.map +1 -0
  450. package/dist/src/posteffect/sao.js +324 -0
  451. package/dist/src/posteffect/sao.js.map +1 -0
  452. package/dist/src/posteffect/ssr.js +489 -0
  453. package/dist/src/posteffect/ssr.js.map +1 -0
  454. package/dist/src/posteffect/taa.js +172 -0
  455. package/dist/src/posteffect/taa.js.map +1 -0
  456. package/dist/src/posteffect/tonemap.js +94 -0
  457. package/dist/src/posteffect/tonemap.js.map +1 -0
  458. package/dist/src/render/abuffer_oit.js +361 -0
  459. package/dist/src/render/abuffer_oit.js.map +1 -0
  460. package/dist/src/render/clipmap.js +851 -0
  461. package/dist/src/render/clipmap.js.map +1 -0
  462. package/dist/src/render/cluster_light.js +333 -0
  463. package/dist/src/render/cluster_light.js.map +1 -0
  464. package/dist/src/render/cull_visitor.js +187 -0
  465. package/dist/src/render/cull_visitor.js.map +1 -0
  466. package/dist/src/render/depthpass.js +68 -0
  467. package/dist/src/render/depthpass.js.map +1 -0
  468. package/dist/src/render/drawable_mixin.js +227 -0
  469. package/dist/src/render/drawable_mixin.js.map +1 -0
  470. package/dist/src/render/envlight.js +463 -0
  471. package/dist/src/render/envlight.js.map +1 -0
  472. package/dist/src/render/fbm_wavegenerator.js +251 -0
  473. package/dist/src/render/fbm_wavegenerator.js.map +1 -0
  474. package/dist/src/render/fft_wavegenerator.js +1006 -0
  475. package/dist/src/render/fft_wavegenerator.js.map +1 -0
  476. package/dist/src/render/fullscreenquad.js +38 -0
  477. package/dist/src/render/fullscreenquad.js.map +1 -0
  478. package/dist/src/render/gerstner_wavegenerator.js +314 -0
  479. package/dist/src/render/gerstner_wavegenerator.js.map +1 -0
  480. package/dist/src/render/globalbindgroup_allocator.js +60 -0
  481. package/dist/src/render/globalbindgroup_allocator.js.map +1 -0
  482. package/dist/src/render/hzb.js +273 -0
  483. package/dist/src/render/hzb.js.map +1 -0
  484. package/dist/src/render/lightpass.js +172 -0
  485. package/dist/src/render/lightpass.js.map +1 -0
  486. package/dist/src/render/objectcolorpass.js +51 -0
  487. package/dist/src/render/objectcolorpass.js.map +1 -0
  488. package/dist/src/render/primitive.js +364 -0
  489. package/dist/src/render/primitive.js.map +1 -0
  490. package/dist/src/render/render_queue.js +467 -0
  491. package/dist/src/render/render_queue.js.map +1 -0
  492. package/dist/src/render/renderbundle_wrapper.js +152 -0
  493. package/dist/src/render/renderbundle_wrapper.js.map +1 -0
  494. package/dist/src/render/renderer.js +455 -0
  495. package/dist/src/render/renderer.js.map +1 -0
  496. package/dist/src/render/renderpass.js +200 -0
  497. package/dist/src/render/renderpass.js.map +1 -0
  498. package/dist/src/render/shadowmap_pass.js +56 -0
  499. package/dist/src/render/shadowmap_pass.js.map +1 -0
  500. package/dist/src/render/sky.js +1103 -0
  501. package/dist/src/render/sky.js.map +1 -0
  502. package/dist/src/render/weightedblended_oit.js +168 -0
  503. package/dist/src/render/weightedblended_oit.js.map +1 -0
  504. package/dist/src/scene/batchgroup.js +162 -0
  505. package/dist/src/scene/batchgroup.js.map +1 -0
  506. package/dist/src/scene/environment.js +209 -0
  507. package/dist/src/scene/environment.js.map +1 -0
  508. package/dist/src/scene/graph_node.js +72 -0
  509. package/dist/src/scene/graph_node.js.map +1 -0
  510. package/dist/src/scene/light.js +416 -0
  511. package/dist/src/scene/light.js.map +1 -0
  512. package/dist/src/scene/mesh.js +341 -0
  513. package/dist/src/scene/mesh.js.map +1 -0
  514. package/dist/src/scene/octree.js +649 -0
  515. package/dist/src/scene/octree.js.map +1 -0
  516. package/dist/src/scene/particlesys.js +738 -0
  517. package/dist/src/scene/particlesys.js.map +1 -0
  518. package/dist/src/scene/raycast_visitor.js +103 -0
  519. package/dist/src/scene/raycast_visitor.js.map +1 -0
  520. package/dist/src/scene/scene.js +284 -0
  521. package/dist/src/scene/scene.js.map +1 -0
  522. package/dist/src/scene/scene_node.js +732 -0
  523. package/dist/src/scene/scene_node.js.map +1 -0
  524. package/dist/src/scene/terrain/grass.js +278 -0
  525. package/dist/src/scene/terrain/grass.js.map +1 -0
  526. package/dist/src/scene/terrain/heightfield.js +475 -0
  527. package/dist/src/scene/terrain/heightfield.js.map +1 -0
  528. package/dist/src/scene/terrain/patch.js +530 -0
  529. package/dist/src/scene/terrain/patch.js.map +1 -0
  530. package/dist/src/scene/terrain/quadtree.js +461 -0
  531. package/dist/src/scene/terrain/quadtree.js.map +1 -0
  532. package/dist/src/scene/terrain/terrain.js +246 -0
  533. package/dist/src/scene/terrain/terrain.js.map +1 -0
  534. package/dist/src/scene/terrain-cm/grass.js +594 -0
  535. package/dist/src/scene/terrain-cm/grass.js.map +1 -0
  536. package/dist/src/scene/terrain-cm/grassmaterial.js +159 -0
  537. package/dist/src/scene/terrain-cm/grassmaterial.js.map +1 -0
  538. package/dist/src/scene/terrain-cm/terrain-cm.js +538 -0
  539. package/dist/src/scene/terrain-cm/terrain-cm.js.map +1 -0
  540. package/dist/src/scene/water.js +374 -0
  541. package/dist/src/scene/water.js.map +1 -0
  542. package/dist/src/shaders/atmosphere.js +957 -0
  543. package/dist/src/shaders/atmosphere.js.map +1 -0
  544. package/dist/src/shaders/fog.js +112 -0
  545. package/dist/src/shaders/fog.js.map +1 -0
  546. package/dist/src/shaders/misc.js +266 -0
  547. package/dist/src/shaders/misc.js.map +1 -0
  548. package/dist/src/shaders/noise.js +222 -0
  549. package/dist/src/shaders/noise.js.map +1 -0
  550. package/dist/src/shaders/pbr.js +51 -0
  551. package/dist/src/shaders/pbr.js.map +1 -0
  552. package/dist/src/shaders/shadow.js +636 -0
  553. package/dist/src/shaders/shadow.js.map +1 -0
  554. package/dist/src/shaders/ssr.js +490 -0
  555. package/dist/src/shaders/ssr.js.map +1 -0
  556. package/dist/src/shaders/temporal.js +215 -0
  557. package/dist/src/shaders/temporal.js.map +1 -0
  558. package/dist/src/shaders/water.js +756 -0
  559. package/dist/src/shaders/water.js.map +1 -0
  560. package/dist/src/shadow/esm.js +237 -0
  561. package/dist/src/shadow/esm.js.map +1 -0
  562. package/dist/src/shadow/pcf_opt.js +181 -0
  563. package/dist/src/shadow/pcf_opt.js.map +1 -0
  564. package/dist/src/shadow/pcf_pd.js +189 -0
  565. package/dist/src/shadow/pcf_pd.js.map +1 -0
  566. package/dist/src/shadow/shader.js +37 -0
  567. package/dist/src/shadow/shader.js.map +1 -0
  568. package/dist/src/shadow/shadow_impl.js +15 -0
  569. package/dist/src/shadow/shadow_impl.js.map +1 -0
  570. package/dist/src/shadow/shadowmapper.js +790 -0
  571. package/dist/src/shadow/shadowmapper.js.map +1 -0
  572. package/dist/src/shadow/ssm.js +159 -0
  573. package/dist/src/shadow/ssm.js.map +1 -0
  574. package/dist/src/shadow/vsm.js +297 -0
  575. package/dist/src/shadow/vsm.js.map +1 -0
  576. package/dist/src/shapes/box.js +386 -0
  577. package/dist/src/shapes/box.js.map +1 -0
  578. package/dist/src/shapes/cylinder.js +125 -0
  579. package/dist/src/shapes/cylinder.js.map +1 -0
  580. package/dist/src/shapes/plane.js +88 -0
  581. package/dist/src/shapes/plane.js.map +1 -0
  582. package/dist/src/shapes/shape.js +87 -0
  583. package/dist/src/shapes/shape.js.map +1 -0
  584. package/dist/src/shapes/sphere.js +114 -0
  585. package/dist/src/shapes/sphere.js.map +1 -0
  586. package/dist/src/shapes/tetrahedron.js +188 -0
  587. package/dist/src/shapes/tetrahedron.js.map +1 -0
  588. package/dist/src/shapes/torus.js +111 -0
  589. package/dist/src/shapes/torus.js.map +1 -0
  590. package/dist/src/utility/aabbtree.js +400 -0
  591. package/dist/src/utility/aabbtree.js.map +1 -0
  592. package/dist/src/utility/bounding_volume.js +29 -0
  593. package/dist/src/utility/bounding_volume.js.map +1 -0
  594. package/dist/src/utility/debug.js +28 -0
  595. package/dist/src/utility/debug.js.map +1 -0
  596. package/dist/src/utility/draco/decoder.js +116 -0
  597. package/dist/src/utility/draco/decoder.js.map +1 -0
  598. package/dist/src/utility/misc.js +105 -0
  599. package/dist/src/utility/misc.js.map +1 -0
  600. package/dist/src/utility/panorama.js +163 -0
  601. package/dist/src/utility/panorama.js.map +1 -0
  602. package/dist/src/utility/pmrem.js +354 -0
  603. package/dist/src/utility/pmrem.js.map +1 -0
  604. package/dist/src/utility/rendermipmap.js +115 -0
  605. package/dist/src/utility/rendermipmap.js.map +1 -0
  606. package/dist/src/utility/serialization/json.js +402 -0
  607. package/dist/src/utility/serialization/json.js.map +1 -0
  608. package/dist/src/utility/serialization/manager.js +623 -0
  609. package/dist/src/utility/serialization/manager.js.map +1 -0
  610. package/dist/src/utility/serialization/scene/animation.js +248 -0
  611. package/dist/src/utility/serialization/scene/animation.js.map +1 -0
  612. package/dist/src/utility/serialization/scene/batch.js +59 -0
  613. package/dist/src/utility/serialization/scene/batch.js.map +1 -0
  614. package/dist/src/utility/serialization/scene/camera.js +790 -0
  615. package/dist/src/utility/serialization/scene/camera.js.map +1 -0
  616. package/dist/src/utility/serialization/scene/common.js +222 -0
  617. package/dist/src/utility/serialization/scene/common.js.map +1 -0
  618. package/dist/src/utility/serialization/scene/light.js +575 -0
  619. package/dist/src/utility/serialization/scene/light.js.map +1 -0
  620. package/dist/src/utility/serialization/scene/material.js +1111 -0
  621. package/dist/src/utility/serialization/scene/material.js.map +1 -0
  622. package/dist/src/utility/serialization/scene/mesh.js +148 -0
  623. package/dist/src/utility/serialization/scene/mesh.js.map +1 -0
  624. package/dist/src/utility/serialization/scene/misc.js +39 -0
  625. package/dist/src/utility/serialization/scene/misc.js.map +1 -0
  626. package/dist/src/utility/serialization/scene/node.js +451 -0
  627. package/dist/src/utility/serialization/scene/node.js.map +1 -0
  628. package/dist/src/utility/serialization/scene/particle.js +425 -0
  629. package/dist/src/utility/serialization/scene/particle.js.map +1 -0
  630. package/dist/src/utility/serialization/scene/primitive.js +692 -0
  631. package/dist/src/utility/serialization/scene/primitive.js.map +1 -0
  632. package/dist/src/utility/serialization/scene/scene.js +704 -0
  633. package/dist/src/utility/serialization/scene/scene.js.map +1 -0
  634. package/dist/src/utility/serialization/scene/terrain.js +488 -0
  635. package/dist/src/utility/serialization/scene/terrain.js.map +1 -0
  636. package/dist/src/utility/serialization/scene/water.js +465 -0
  637. package/dist/src/utility/serialization/scene/water.js.map +1 -0
  638. package/dist/src/utility/shprojector.js +297 -0
  639. package/dist/src/utility/shprojector.js.map +1 -0
  640. package/dist/{material/mixins → src/utility/textures}/ggxlut.js +1 -1
  641. package/dist/src/utility/textures/ggxlut.js.map +1 -0
  642. package/dist/src/utility/textures/gradientnoise.js +62 -0
  643. package/dist/src/utility/textures/gradientnoise.js.map +1 -0
  644. package/dist/src/utility/textures/randomnoise.js +41 -0
  645. package/dist/src/utility/textures/randomnoise.js.map +1 -0
  646. package/dist/src/values.js +162 -0
  647. package/dist/src/values.js.map +1 -0
  648. package/dist/utility/aabbtree.js +16 -6
  649. package/dist/utility/aabbtree.js.map +1 -1
  650. package/dist/utility/blueprint/common/constants.js +1325 -0
  651. package/dist/utility/blueprint/common/constants.js.map +1 -0
  652. package/dist/utility/blueprint/common/math.js +2507 -0
  653. package/dist/utility/blueprint/common/math.js.map +1 -0
  654. package/dist/utility/blueprint/common.js +7 -0
  655. package/dist/utility/blueprint/common.js.map +1 -0
  656. package/dist/utility/blueprint/material/common.js +7 -0
  657. package/dist/utility/blueprint/material/common.js.map +1 -0
  658. package/dist/utility/blueprint/material/func.js +525 -0
  659. package/dist/utility/blueprint/material/func.js.map +1 -0
  660. package/dist/utility/blueprint/material/inputs.js +1659 -0
  661. package/dist/utility/blueprint/material/inputs.js.map +1 -0
  662. package/dist/utility/blueprint/material/ir.js +1519 -0
  663. package/dist/utility/blueprint/material/ir.js.map +1 -0
  664. package/dist/utility/blueprint/material/pbr.js +450 -0
  665. package/dist/utility/blueprint/material/pbr.js.map +1 -0
  666. package/dist/utility/blueprint/material/texture.js +1116 -0
  667. package/dist/utility/blueprint/material/texture.js.map +1 -0
  668. package/dist/utility/blueprint/node.js +214 -0
  669. package/dist/utility/blueprint/node.js.map +1 -0
  670. package/dist/utility/bounding_volume.js +0 -1
  671. package/dist/utility/bounding_volume.js.map +1 -1
  672. package/dist/utility/debug.js +26 -0
  673. package/dist/utility/debug.js.map +1 -0
  674. package/dist/utility/draco/decoder.js +1 -1
  675. package/dist/utility/draco/decoder.js.map +1 -1
  676. package/dist/utility/misc.js +19 -7
  677. package/dist/utility/misc.js.map +1 -1
  678. package/dist/utility/panorama.js +8 -6
  679. package/dist/utility/panorama.js.map +1 -1
  680. package/dist/utility/pmrem.js +30 -18
  681. package/dist/utility/pmrem.js.map +1 -1
  682. package/dist/utility/rendermipmap.js +116 -0
  683. package/dist/utility/rendermipmap.js.map +1 -0
  684. package/dist/utility/serialization/blueprint/constants.js +255 -0
  685. package/dist/utility/serialization/blueprint/constants.js.map +1 -0
  686. package/dist/utility/serialization/blueprint/material/constants.js +203 -0
  687. package/dist/utility/serialization/blueprint/material/constants.js.map +1 -0
  688. package/dist/utility/serialization/blueprint/material/texture.js +165 -0
  689. package/dist/utility/serialization/blueprint/material/texture.js.map +1 -0
  690. package/dist/utility/serialization/json.js +406 -0
  691. package/dist/utility/serialization/json.js.map +1 -0
  692. package/dist/utility/serialization/manager.js +1243 -0
  693. package/dist/utility/serialization/manager.js.map +1 -0
  694. package/dist/utility/serialization/scene/animation.js +701 -0
  695. package/dist/utility/serialization/scene/animation.js.map +1 -0
  696. package/dist/utility/serialization/scene/batch.js +54 -0
  697. package/dist/utility/serialization/scene/batch.js.map +1 -0
  698. package/dist/utility/serialization/scene/camera.js +896 -0
  699. package/dist/utility/serialization/scene/camera.js.map +1 -0
  700. package/dist/utility/serialization/scene/common.js +298 -0
  701. package/dist/utility/serialization/scene/common.js.map +1 -0
  702. package/dist/utility/serialization/scene/light.js +591 -0
  703. package/dist/utility/serialization/scene/light.js.map +1 -0
  704. package/dist/utility/serialization/scene/material.js +1070 -0
  705. package/dist/utility/serialization/scene/material.js.map +1 -0
  706. package/dist/utility/serialization/scene/mesh.js +345 -0
  707. package/dist/utility/serialization/scene/mesh.js.map +1 -0
  708. package/dist/utility/serialization/scene/misc.js +40 -0
  709. package/dist/utility/serialization/scene/misc.js.map +1 -0
  710. package/dist/utility/serialization/scene/node.js +424 -0
  711. package/dist/utility/serialization/scene/node.js.map +1 -0
  712. package/dist/utility/serialization/scene/particle.js +427 -0
  713. package/dist/utility/serialization/scene/particle.js.map +1 -0
  714. package/dist/utility/serialization/scene/primitive.js +585 -0
  715. package/dist/utility/serialization/scene/primitive.js.map +1 -0
  716. package/dist/utility/serialization/scene/scene.js +764 -0
  717. package/dist/utility/serialization/scene/scene.js.map +1 -0
  718. package/dist/utility/serialization/scene/sprite.js +164 -0
  719. package/dist/utility/serialization/scene/sprite.js.map +1 -0
  720. package/dist/utility/serialization/scene/terrain.js +497 -0
  721. package/dist/utility/serialization/scene/terrain.js.map +1 -0
  722. package/dist/utility/serialization/scene/water.js +467 -0
  723. package/dist/utility/serialization/scene/water.js.map +1 -0
  724. package/dist/utility/serialization/types.js +6 -0
  725. package/dist/utility/serialization/types.js.map +1 -0
  726. package/dist/utility/shprojector.js +313 -0
  727. package/dist/utility/shprojector.js.map +1 -0
  728. package/dist/utility/textures/ggxlut.js +4 -5
  729. package/dist/utility/textures/ggxlut.js.map +1 -1
  730. package/dist/utility/textures/gradientnoise.js +2 -1
  731. package/dist/utility/textures/gradientnoise.js.map +1 -1
  732. package/dist/utility/textures/randomnoise.js +1 -0
  733. package/dist/utility/textures/randomnoise.js.map +1 -1
  734. package/dist/values.js +103 -16
  735. package/dist/values.js.map +1 -1
  736. package/package.json +80 -66
  737. package/dist/app.js.map +0 -1
  738. package/dist/blitter/depthlimitedgaussion.js.map +0 -1
  739. package/dist/input/inputmgr.js.map +0 -1
  740. package/dist/material/mixins/ggxlut.js.map +0 -1
  741. package/dist/posteffect/water.js +0 -508
  742. package/dist/posteffect/water.js.map +0 -1
  743. package/dist/render/oit.js +0 -16
  744. package/dist/render/oit.js.map +0 -1
  745. package/dist/render/scatteringlut.js +0 -634
  746. package/dist/render/scatteringlut.js.map +0 -1
  747. package/dist/render/watermesh.js +0 -193
  748. package/dist/render/watermesh.js.map +0 -1
  749. package/dist/render/wavegenerator.js +0 -8
  750. package/dist/render/wavegenerator.js.map +0 -1
  751. package/dist/scene/xform.js +0 -247
  752. package/dist/scene/xform.js.map +0 -1
  753. package/dist/utility/shprojection.js +0 -442
  754. package/dist/utility/shprojection.js.map +0 -1
@@ -1,101 +1,145 @@
1
- import { Application } from '../app.js';
2
- import { decodeNormalizedFloatFromRGBA, linearToGamma } from '../shaders/misc.js';
1
+ import { linearToGamma } from '../shaders/misc.js';
3
2
  import { smoothNoise3D } from '../shaders/noise.js';
4
- import { Matrix4x4, Vector4, Vector2, Vector3, CubeFace } from '@zephyr3d/base';
5
- import '@zephyr3d/device';
3
+ import { getDevice, getEngine } from '../app/api.js';
4
+ import { getDefaultAtmosphereParams, getAerialPerspectiveLut, renderAtmosphereLUTs, getAtmosphereParamsStruct, createTransmittanceLutProgram, createMultiScatteringLutProgram, createSkyViewLutProgram, createAPLutProgram, skyBox, atmosphereLUTRendered, getTransmittanceLut, getSkyViewLut } from '../shaders/atmosphere.js';
5
+ import { Matrix4x4, Disposable, DRef, Vector4, Vector2, Vector3, CubeFace, objectKeys } from '@zephyr3d/base';
6
+ import { Primitive } from './primitive.js';
6
7
  import { BoxShape } from '../shapes/box.js';
7
- import { ScatteringLut } from './scatteringlut.js';
8
- import { Camera } from '../camera/camera.js';
8
+ import '../shapes/cylinder.js';
9
+ import '../shapes/torus.js';
10
+ import '../shapes/plane.js';
11
+ import '../shapes/sphere.js';
12
+ import '../shapes/tetrahedron.js';
9
13
  import { prefilterCubemap } from '../utility/pmrem.js';
10
- import '../utility/panorama.js';
11
- import '../utility/shprojection.js';
12
14
  import { ShaderHelper } from '../material/shader/helper.js';
13
15
  import { fetchSampler } from '../utility/misc.js';
16
+ import { CubemapSHProjector } from '../utility/shprojector.js';
17
+ import { uniformSphereSamples, Fog } from '../values.js';
18
+ import { getDefaultHeightFogParams, MAX_FOG_HEIGHT, getHeightFogParamsStruct, calculateFog } from '../shaders/fog.js';
19
+ import { drawFullscreenQuad } from './fullscreenquad.js';
20
+ import { panoramaToCubemap } from '../utility/panorama.js';
21
+ import '../camera/camera.js';
22
+ import { PerspectiveCamera } from '../camera/perspectivecamera.js';
14
23
 
15
24
  const fogTypeMap = {
16
- linear: ShaderHelper.FOG_TYPE_LINEAR,
17
- exp: ShaderHelper.FOG_TYPE_EXP,
18
- exp2: ShaderHelper.FOG_TYPE_EXP2,
19
- scatter: ShaderHelper.FOG_TYPE_SCATTER,
20
- none: ShaderHelper.FOG_TYPE_NONE
25
+ height_fog: Fog.FOG_TYPE_HEIGHT,
26
+ none: Fog.FOG_TYPE_NONE
21
27
  };
22
28
  const defaultSkyWorldMatrix = Matrix4x4.identity();
23
29
  /**
24
30
  * The sky renderer
25
31
  * @public
26
- */ class SkyRenderer {
32
+ */ class SkyRenderer extends Disposable {
33
+ static _skyCamera = (()=>{
34
+ return new PerspectiveCamera(null, Math.PI * 0.5, 1, 20, 1);
35
+ })();
36
+ static transmittanceLutProgram = null;
37
+ static multiScatteringLutProgram = null;
38
+ static skyViewLutProgram = null;
39
+ static APLutProgram = null;
40
+ static _programSky = {};
41
+ static _programDistantLight = null;
42
+ static _programFog = null;
43
+ static _programFogNoDepth = null;
44
+ static _vertexLayout = null;
45
+ static _primitiveSky = null;
46
+ static _primitiveDistantLight = null;
47
+ static _renderStatesSky = null;
48
+ static _renderStatesSkyNoDepthTest = null;
49
+ static _renderStatesFog = null;
50
+ static _renderStatesFogScatter = null;
51
+ static _renderStatesDistantLight = null;
52
+ static _defaultSkyImage = new DRef();
27
53
  _skyType;
28
54
  _skyColor;
55
+ _skyImage;
56
+ _bakedSkyboxDirty;
57
+ _bakedSkyboxTextureSize;
58
+ _skyboxTextureSize;
29
59
  _skyboxTexture;
30
- _updateRadianceMaps;
31
- _radianceMapDirty;
32
- _scatterSkyboxFramebuffer;
33
- _scatterSkyboxTextureWidth;
34
- _aerialPerspectiveDensity;
60
+ _bakedSkyboxTexture;
61
+ _bakedSkyboxFrameBuffer;
35
62
  _radianceMap;
63
+ _radianceFrameBuffer;
64
+ _irradianceSH;
65
+ _irradianceSHFB;
66
+ _skyDistantLightLut;
67
+ _irradianceFrameBuffer;
36
68
  _radianceMapWidth;
37
- _irradianceMap;
38
- _irradianceMapWidth;
69
+ _atmosphereParams;
70
+ _atmosphereExposure;
39
71
  _fogType;
40
- _fogColor;
41
- _fogParams;
72
+ _heightFogParams;
42
73
  _cloudy;
43
74
  _cloudIntensity;
75
+ _debugAerialPerspective;
44
76
  _wind;
45
- _programSky;
46
- _bindgroupSky;
47
- _programFog;
48
- _bindgroupFog;
49
- _programFogScatter;
50
- _bindgroupFogScatter;
51
- _vertexLayout;
52
- _primitiveSky;
53
77
  _skyWorldMatrix;
54
- _renderStatesSky;
55
- _renderStatesSkyNoDepthTest;
56
- _renderStatesFog;
57
- _renderStatesFogScatter;
58
- _drawGround;
59
78
  _lastSunDir;
79
+ _lastSunColor;
80
+ _panoramaAsset;
81
+ _shProjector;
82
+ _shWindowWeights;
83
+ _radianceConvSamples;
84
+ _irradianceConvSamples;
85
+ _bindgroupDistantLight = null;
86
+ _bindgroupSky = {};
87
+ _bindgroupFog = null;
88
+ _bindgroupFogNoDepth = null;
89
+ _format;
60
90
  /**
61
91
  * Creates an instance of SkyRenderer
62
92
  */ constructor(){
93
+ super();
63
94
  this._skyType = 'scatter';
64
- this._updateRadianceMaps = true;
65
- this._radianceMapDirty = true;
66
- this._skyColor = Vector4.zero();
67
- this._skyboxTexture = null;
68
- this._scatterSkyboxFramebuffer = null;
69
- this._scatterSkyboxTextureWidth = 256;
70
- this._aerialPerspectiveDensity = 1;
71
- this._radianceMap = null;
95
+ this._skyColor = new Vector4(0, 0, 0, 1);
96
+ this._skyImage = new DRef();
97
+ this._skyboxTexture = new DRef();
98
+ this._skyboxTextureSize = 1024;
99
+ this._bakedSkyboxTexture = new DRef();
100
+ this._bakedSkyboxFrameBuffer = new DRef();
101
+ this._bakedSkyboxDirty = true;
102
+ this._bakedSkyboxTextureSize = 256;
103
+ this._radianceMap = new DRef();
104
+ this._radianceFrameBuffer = new DRef();
72
105
  this._radianceMapWidth = 128;
73
- this._irradianceMap = null;
74
- this._irradianceMapWidth = 64;
75
- this._fogType = 'none';
76
- this._fogColor = Vector4.one();
77
- this._fogParams = new Vector4(1, 100, 50, 0.002);
78
- this._cloudy = 0.6;
79
- this._cloudIntensity = 40;
80
- this._wind = Vector2.zero();
81
- this._drawGround = false;
82
- this._programSky = {};
83
- this._bindgroupSky = {};
84
- this._programFog = null;
85
- this._bindgroupFog = null;
86
- this._programFogScatter = null;
87
- this._bindgroupFogScatter = null;
88
- this._vertexLayout = null;
89
- this._primitiveSky = null;
90
- this._renderStatesSky = null;
91
- this._renderStatesSkyNoDepthTest = null;
92
- this._renderStatesFog = null;
93
- this._renderStatesFogScatter = null;
106
+ this._irradianceSH = new DRef();
107
+ this._irradianceSHFB = new DRef();
108
+ this._skyDistantLightLut = new DRef();
109
+ this._irradianceFrameBuffer = new DRef();
110
+ this._atmosphereParams = getDefaultAtmosphereParams();
111
+ this._atmosphereExposure = 1;
112
+ this._debugAerialPerspective = 0;
113
+ this._fogType = 'height_fog';
114
+ this._heightFogParams = getDefaultHeightFogParams();
115
+ this._cloudy = 0.45;
116
+ this._cloudIntensity = 15;
117
+ this._wind = new Vector2(0, 0);
94
118
  this._skyWorldMatrix = defaultSkyWorldMatrix;
95
- this._lastSunDir = Vector3.zero();
119
+ this._lastSunDir = SkyRenderer._getSunDir(null);
120
+ this._lastSunColor = SkyRenderer._getSunColor(null);
121
+ this._panoramaAsset = '';
122
+ this._shProjector = new CubemapSHProjector(10000);
123
+ this._shWindowWeights = new Vector3(1, 0.8, 0.6);
124
+ this._radianceConvSamples = 64;
125
+ this._irradianceConvSamples = 256;
126
+ this._bindgroupDistantLight = new DRef();
127
+ this._bindgroupSky = {};
128
+ this._bindgroupFog = new DRef();
129
+ this._bindgroupFogNoDepth = new DRef();
130
+ this._format = null;
96
131
  }
97
- /** @internal */ getHash(ctx) {
98
- return ctx.applyFog === 'scatter' ? '1' : ctx.applyFog ? '2' : '0';
132
+ /** @internal */ getHash(_ctx) {
133
+ return `${this.skyType}:${this.fogType}`;
134
+ }
135
+ /**
136
+ * Gets the preferred environment texture format.
137
+ */ get envTextureFormat() {
138
+ if (!this._format) {
139
+ const texCaps = getDevice().getDeviceCaps().textureCaps;
140
+ this._format = texCaps.getTextureFormatInfo('rg11b10uf')?.renderable ? 'rg11b10uf' : texCaps.supportHalfFloatColorBuffer && texCaps.supportLinearHalfFloatTexture ? 'rgba16f' : 'rgba32f';
141
+ }
142
+ return this._format;
99
143
  }
100
144
  /** Which type of the sky should be rendered */ get skyType() {
101
145
  return this._skyType;
@@ -103,57 +147,206 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
103
147
  set skyType(val) {
104
148
  if (val !== this._skyType) {
105
149
  this._skyType = val;
106
- this.invalidateIBLMaps();
150
+ this.invalidate();
107
151
  }
108
152
  }
109
- /** Whether ground should be rendered */ get drawGround() {
110
- return this._drawGround;
111
- }
112
- set drawGround(val) {
113
- this._drawGround = !!val;
153
+ /** @internal */ get panoramaTextureAsset() {
154
+ return this._panoramaAsset;
114
155
  }
115
- /** Baked sky texture */ get bakedSkyTexture() {
116
- if (this._skyType === 'skybox' && this._skyboxTexture) {
117
- return this._skyboxTexture;
156
+ set panoramaTextureAsset(id) {
157
+ if (id !== this._panoramaAsset) {
158
+ this._panoramaAsset = id ?? '';
159
+ if (!this._panoramaAsset) {
160
+ this.skyboxTexture = null;
161
+ return;
162
+ }
163
+ this._updateSkyboxTexture();
118
164
  }
119
- if (!this._scatterSkyboxFramebuffer) {
120
- this.updateIBLMaps(this._lastSunDir);
165
+ }
166
+ /** @internal */ get skyboxTextureSize() {
167
+ return this._skyboxTextureSize;
168
+ }
169
+ set skyboxTextureSize(size) {
170
+ if (size !== this._skyboxTextureSize) {
171
+ this._skyboxTextureSize = size;
172
+ this._updateSkyboxTexture();
121
173
  }
122
- return this._scatterSkyboxFramebuffer.getColorAttachments()[0];
123
174
  }
124
- /**
125
- * Wether the IBL maps should be updated automatically.
126
- *
127
- * @remarks
128
- * If use use the sky for image-based lighting, the value shoud be set to true. default is false
129
- *
130
- */ get autoUpdateIBLMaps() {
131
- return this._updateRadianceMaps;
132
- }
133
- set autoUpdateIBLMaps(val) {
134
- if (this._updateRadianceMaps !== !!val) {
135
- this._updateRadianceMaps = !!val;
136
- if (this._updateRadianceMaps) {
137
- this.invalidateIBLMaps();
138
- }
175
+ /** Baked sky texture */ getBakedSkyTexture(ctx) {
176
+ if (this._bakedSkyboxDirty) {
177
+ this.update(ctx);
139
178
  }
179
+ return this._bakedSkyboxTexture.get();
140
180
  }
141
181
  /**
142
- * The solid sky color
182
+ * The color used when sky type is `image`
143
183
  */ get skyColor() {
144
184
  return this._skyColor;
145
185
  }
146
186
  set skyColor(val) {
147
187
  if (!val.equalsTo(this._skyColor)) {
148
188
  this._skyColor.set(val);
149
- this.invalidateIBLMaps();
189
+ this.invalidate();
190
+ }
191
+ }
192
+ /**
193
+ * The image used when sky type is `image`
194
+ */ get skyImage() {
195
+ return this._skyImage.get();
196
+ }
197
+ set skyImage(texture) {
198
+ if (texture !== this._skyImage.get()) {
199
+ this._skyImage.set(texture);
200
+ this.invalidate();
201
+ }
202
+ }
203
+ /**
204
+ * Window weights for SH projection
205
+ */ get shWindowWeights() {
206
+ return this._shWindowWeights;
207
+ }
208
+ set shWindowWeights(weights) {
209
+ this._shWindowWeights.set(weights);
210
+ this.invalidate();
211
+ }
212
+ /**
213
+ * Sample count for radiance convolution
214
+ */ get radianceConvSamples() {
215
+ return this._radianceConvSamples;
216
+ }
217
+ set radianceConvSamples(val) {
218
+ if (val !== this._radianceConvSamples) {
219
+ this._radianceConvSamples = val;
220
+ this.invalidate();
221
+ }
222
+ }
223
+ /**
224
+ * Sample count for irradiance convolution
225
+ */ get irradianceConvSamples() {
226
+ return this._irradianceConvSamples;
227
+ }
228
+ set irradianceConvSamples(val) {
229
+ if (val !== this._irradianceConvSamples) {
230
+ this._irradianceConvSamples = val;
231
+ this.invalidate();
232
+ }
233
+ }
234
+ /** Aerial perspective density */ get aerialPerspectiveDistance() {
235
+ return this._atmosphereParams.apDistance;
236
+ }
237
+ set aerialPerspectiveDistance(val) {
238
+ if (val !== this._atmosphereParams.apDistance) {
239
+ this._atmosphereParams.apDistance = val;
240
+ this.invalidate();
241
+ }
242
+ }
243
+ /** Atmosphere exposure */ get atmosphereExposure() {
244
+ return this._atmosphereExposure;
245
+ }
246
+ set atmosphereExposure(val) {
247
+ if (val !== this._atmosphereExposure) {
248
+ this._atmosphereExposure = val;
249
+ this.invalidate();
250
+ }
251
+ }
252
+ /** Aerial perspective density */ get cameraHeightScale() {
253
+ return this._atmosphereParams.cameraHeightScale;
254
+ }
255
+ set cameraHeightScale(val) {
256
+ if (val !== this._atmosphereParams.cameraHeightScale) {
257
+ this._atmosphereParams.cameraHeightScale = val;
258
+ this.invalidate();
259
+ }
260
+ }
261
+ /** Height fog color */ get heightFogColor() {
262
+ return this._heightFogParams.parameter1.xyz();
263
+ }
264
+ set heightFogColor(val) {
265
+ if (!val.equalsTo(this._heightFogParams.parameter1.xyz())) {
266
+ this._heightFogParams.parameter1.set(val);
267
+ this.invalidate();
268
+ }
269
+ }
270
+ /** Height fog density */ get heightFogDensity() {
271
+ return this._heightFogParams.parameter2.x;
272
+ }
273
+ set heightFogDensity(val) {
274
+ if (val !== this._heightFogParams.parameter2.x) {
275
+ this._heightFogParams.parameter2.x = val;
276
+ this.invalidate();
277
+ }
278
+ }
279
+ /** Height fog falloff */ get heightFogFalloff() {
280
+ return this._heightFogParams.parameter1.w;
281
+ }
282
+ set heightFogFalloff(val) {
283
+ if (val !== this._heightFogParams.parameter1.w) {
284
+ this._heightFogParams.parameter1.w = val;
285
+ this.invalidate();
286
+ }
287
+ }
288
+ /** Height fog start height */ get heightFogStartHeight() {
289
+ return this._heightFogParams.parameter2.y;
290
+ }
291
+ set heightFogStartHeight(val) {
292
+ if (val !== this._heightFogParams.parameter2.y) {
293
+ this._heightFogParams.parameter2.y = val;
294
+ this.invalidate();
295
+ }
296
+ }
297
+ /** Height fog start distance */ get heightFogStartDistance() {
298
+ return this._heightFogParams.parameter2.z;
299
+ }
300
+ set heightFogStartDistance(val) {
301
+ if (val !== this._heightFogParams.parameter2.z) {
302
+ this._heightFogParams.parameter2.z = val;
303
+ this.invalidate();
304
+ }
305
+ }
306
+ /** Height fog end distance */ get heightFogEndDistance() {
307
+ return this._heightFogParams.parameter2.w;
308
+ }
309
+ set heightFogEndDistance(val) {
310
+ if (val !== this._heightFogParams.parameter2.w) {
311
+ this._heightFogParams.parameter2.w = val;
312
+ this.invalidate();
313
+ }
314
+ }
315
+ /** Height fog maximum opacity */ get heightFogMaxOpacity() {
316
+ return this._heightFogParams.parameter3.x;
317
+ }
318
+ set heightFogMaxOpacity(val) {
319
+ if (val !== this._heightFogParams.parameter3.x) {
320
+ this._heightFogParams.parameter3.x = val;
321
+ this.invalidate();
322
+ }
323
+ }
324
+ /** Height fog atmosphere contribution strength */ get heightFogAtmosphereContribution() {
325
+ return this._heightFogParams.parameter3.y;
326
+ }
327
+ set heightFogAtmosphereContribution(val) {
328
+ if (val !== this._heightFogParams.parameter3.y) {
329
+ this._heightFogParams.parameter3.y = val;
330
+ this.invalidate();
150
331
  }
151
332
  }
152
- /** Aerial perspective density */ get aerialPerspectiveDensity() {
153
- return this._aerialPerspectiveDensity;
333
+ /** Height fog directional exponent */ get heightFogDirExponent() {
334
+ return this._heightFogParams.parameter3.w;
335
+ }
336
+ set heightFogDirExponent(val) {
337
+ if (val !== this._heightFogParams.parameter3.w) {
338
+ this._heightFogParams.parameter3.w = val;
339
+ this.invalidate();
340
+ }
154
341
  }
155
- set aerialPerspectiveDensity(val) {
156
- this._aerialPerspectiveDensity = val;
342
+ /** Height fog directional inscattering color */ get heightFogDirColor() {
343
+ return this._heightFogParams.parameter4.xyz();
344
+ }
345
+ set heightFogDirColor(val) {
346
+ if (!val.equalsTo(this._heightFogParams.parameter4.xyz())) {
347
+ this._heightFogParams.parameter4.set(val);
348
+ this.invalidate();
349
+ }
157
350
  }
158
351
  /**
159
352
  * Light density of the sky.
@@ -167,7 +360,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
167
360
  set cloudy(val) {
168
361
  if (val !== this._cloudy && this._skyType === 'scatter') {
169
362
  this._cloudy = val;
170
- this.invalidateIBLMaps();
363
+ this.invalidate();
171
364
  }
172
365
  }
173
366
  /**
@@ -178,7 +371,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
178
371
  set cloudIntensity(val) {
179
372
  if (val !== this._cloudIntensity && this._skyType === 'scatter') {
180
373
  this._cloudIntensity = val;
181
- this.invalidateIBLMaps();
374
+ this.invalidate();
182
375
  }
183
376
  }
184
377
  /**
@@ -195,35 +388,61 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
195
388
  /**
196
389
  * Radiance map of the sky.
197
390
  */ get radianceMap() {
198
- if (!this._radianceMap) {
199
- this._radianceMap = Application.instance.device.createCubeTexture('rgba16f', this._radianceMapWidth);
200
- this._radianceMap.name = 'SkyRadianceMap';
391
+ if (!this._radianceMap.get()) {
392
+ this._radianceMap.set(getDevice().createCubeTexture(this.envTextureFormat, this._radianceMapWidth));
393
+ this._radianceMap.get().name = 'SkyRadianceMap';
201
394
  }
202
- return this._radianceMap;
395
+ return this._radianceMap.get();
396
+ }
397
+ /** @internal */ get atmosphereParams() {
398
+ return this._atmosphereParams;
399
+ }
400
+ /** @internal */ get heightFogParams() {
401
+ return this._heightFogParams;
402
+ }
403
+ /** @internal */ get radianceFramebuffer() {
404
+ if (!this._radianceFrameBuffer.get()) {
405
+ this._radianceFrameBuffer.set(getDevice().createFrameBuffer([
406
+ this.radianceMap
407
+ ], null));
408
+ }
409
+ return this._radianceFrameBuffer.get();
203
410
  }
204
411
  /**
205
- * Irradiance map of the sky.
206
- */ get irradianceMap() {
207
- if (!this._irradianceMap) {
208
- this._irradianceMap = Application.instance.device.createCubeTexture('rgba16f', this._irradianceMapWidth, {
209
- samplerOptions: {
210
- mipFilter: 'none'
211
- }
412
+ * Irradiance SH coeffecients buffer
413
+ */ get irradianceSH() {
414
+ if (!this._irradianceSH.get()) {
415
+ const buffer = getDevice().createBuffer(4 * 4 * 9, {
416
+ usage: 'uniform'
212
417
  });
213
- this._irradianceMap.name = 'SkyIrradianceMap';
418
+ this._irradianceSH.set(buffer);
214
419
  }
215
- return this._irradianceMap;
420
+ return this._irradianceSH.get();
421
+ }
422
+ /**
423
+ * Irradiance SH coeffecients texture
424
+ */ get irradianceSHFB() {
425
+ if (!this._irradianceSHFB.get()) {
426
+ const device = getDevice();
427
+ const texture = device.createTexture2D('rgba32f', 3, 3, {
428
+ mipmapping: false
429
+ });
430
+ this._irradianceSHFB.set(device.createFrameBuffer([
431
+ texture
432
+ ], null));
433
+ }
434
+ return this._irradianceSHFB.get();
216
435
  }
217
436
  /**
218
437
  * Cube texture for skybox.
219
438
  */ get skyboxTexture() {
220
- return this._skyboxTexture;
439
+ return this._skyboxTexture.get();
221
440
  }
222
441
  set skyboxTexture(tex) {
223
- if (tex !== this._skyboxTexture) {
224
- this._skyboxTexture = tex;
442
+ if (tex !== this.skyboxTexture) {
443
+ this._skyboxTexture.set(tex);
225
444
  if (this._skyType === 'skybox') {
226
- this.invalidateIBLMaps();
445
+ this.invalidate();
227
446
  }
228
447
  }
229
448
  }
@@ -234,7 +453,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
234
453
  val = val ?? defaultSkyWorldMatrix;
235
454
  if (val !== this._skyWorldMatrix) {
236
455
  this._skyWorldMatrix = val;
237
- this.invalidateIBLMaps();
456
+ this.invalidate();
238
457
  }
239
458
  }
240
459
  /** @internal */ get mappedFogType() {
@@ -244,170 +463,268 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
244
463
  return this._fogType;
245
464
  }
246
465
  set fogType(val) {
247
- this._fogType = val;
248
- }
249
- /** Start distance of linear fog */ get fogStart() {
250
- return this._fogParams.x;
466
+ if (val !== this._fogType) {
467
+ this._fogType = val;
468
+ this.invalidate();
469
+ }
251
470
  }
252
- set fogStart(val) {
253
- this._fogParams.x = val;
471
+ /** @internal */ get aerialPerspectiveDebug() {
472
+ return this._debugAerialPerspective;
254
473
  }
255
- /** End distance of linear fog */ get fogEnd() {
256
- return this._fogParams.y;
474
+ set aerialPerspectiveDebug(val) {
475
+ this._debugAerialPerspective = val;
257
476
  }
258
- set fogEnd(val) {
259
- this._fogParams.y = val;
477
+ /** @internal */ get fogPresents() {
478
+ return this._skyType === 'scatter' || this._fogType !== 'none';
260
479
  }
261
- /** Top distance of fog if fog type is not scatter */ get fogTop() {
262
- return this._fogParams.z;
480
+ /**
481
+ * Force the radiance map and irradiance map to be regenerated.
482
+ */ invalidate() {
483
+ this._bakedSkyboxDirty = true;
263
484
  }
264
- set fogTop(val) {
265
- this._fogParams.z = val;
485
+ /** @internal */ drawScatteredFog(_ctx) {
486
+ return this.skyType === 'scatter';
266
487
  }
267
- /** Density of exp/exp2 fog */ get fogDensity() {
268
- return this._fogParams.w;
488
+ /** @internal */ getAerialPerspectiveLUT(_ctx) {
489
+ return getAerialPerspectiveLut();
269
490
  }
270
- set fogDensity(val) {
271
- this._fogParams.w = val;
491
+ /** @internal */ getSkyDistantLightLUT(_ctx) {
492
+ return this._skyDistantLightLut.get().getColorAttachments()[0];
272
493
  }
273
- /** The fog color if fog type is not scatter */ get fogColor() {
274
- return this._fogColor;
494
+ update(ctx) {
495
+ const useScatter = this._skyType === 'scatter';
496
+ if (useScatter || !atmosphereLUTRendered()) {
497
+ this.renderAtmosphereLUTs(ctx);
498
+ }
499
+ const oldSunLight = ctx.sunLight && useScatter ? ctx.sunLight.color : null;
500
+ const sunDir = SkyRenderer._getSunDir(ctx.sunLight);
501
+ const sunColor = SkyRenderer._getSunColor(ctx.sunLight);
502
+ if (this._skyType === 'scatter' && (this._wind.x !== 0 || this._wind.y !== 0)) {
503
+ this._bakedSkyboxDirty = true;
504
+ }
505
+ if (!this._skyDistantLightLut.get()) {
506
+ const tex = ctx.device.createTexture2D(this.envTextureFormat, 1, 1, {
507
+ mipmapping: false
508
+ });
509
+ tex.name = 'DistantSkyLut';
510
+ this._skyDistantLightLut.set(ctx.device.createFrameBuffer([
511
+ tex
512
+ ], null));
513
+ this._bakedSkyboxDirty = true;
514
+ }
515
+ if (!sunDir.equalsTo(this._lastSunDir) || !sunColor.equalsTo(this._lastSunColor)) {
516
+ this._lastSunDir.set(sunDir);
517
+ this._lastSunColor.set(sunColor);
518
+ this._bakedSkyboxDirty = true;
519
+ }
520
+ if (this._bakedSkyboxDirty) {
521
+ this._bakedSkyboxDirty = false;
522
+ this.updateBakedSkyMap(ctx);
523
+ this.renderSkyDistantLut(ctx, this._bakedSkyboxTexture.get());
524
+ 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)) {
525
+ prefilterCubemap(this._bakedSkyboxTexture.get(), 'ggx', this.radianceFramebuffer, this._radianceConvSamples);
526
+ if (ctx.device.type === 'webgl' || !ctx.device.getDeviceCaps().framebufferCaps.supportFloatBlending) {
527
+ this._shProjector.projectCubemapToTexture(this._bakedSkyboxTexture.get(), this.irradianceSHFB);
528
+ } else {
529
+ this._shProjector.projectCubemap(this._bakedSkyboxTexture.get(), this.irradianceSH);
530
+ }
531
+ ctx.scene.env.light.irradianceSH = this.irradianceSH;
532
+ ctx.scene.env.light.irradianceWindow = this._shWindowWeights;
533
+ }
534
+ }
535
+ const newSunLight = oldSunLight ? Vector3.mul(ctx.sunLight.color.xyz(), this.sunTransmittance(ctx.sunLight)) : Vector3.zero();
536
+ if (oldSunLight) {
537
+ ctx.sunLight.setColor(newSunLight);
538
+ }
539
+ // Update height fog parameters
540
+ if (this._fogType === 'height_fog') {
541
+ const cameraY = Math.min(this._heightFogParams.parameter2.y + MAX_FOG_HEIGHT, ctx.camera.getWorldPosition().y);
542
+ const p = Math.max(-125, Math.min(126, -this._heightFogParams.parameter1.w * (cameraY - this._heightFogParams.parameter2.y)));
543
+ this._heightFogParams.parameter3.z = this._heightFogParams.parameter2.x * Math.pow(2, p);
544
+ this._heightFogParams.lightColor.set(newSunLight);
545
+ this._heightFogParams.lightDir.set(SkyRenderer._getSunDir(ctx.sunLight));
546
+ }
547
+ return oldSunLight;
275
548
  }
276
- set fogColor(val) {
277
- this._fogColor.set(val);
549
+ renderAtmosphereLUTs(ctx) {
550
+ this._atmosphereParams.lightDir.set(SkyRenderer._getSunDir(ctx.sunLight));
551
+ this._atmosphereParams.lightColor.set(SkyRenderer._getSunColor(ctx.sunLight));
552
+ this._atmosphereParams.lightColor.w *= this._atmosphereExposure;
553
+ this._atmosphereParams.cameraAspect = ctx.camera.getAspect();
554
+ this._atmosphereParams.cameraWorldMatrix.set(ctx.camera.worldMatrix);
555
+ renderAtmosphereLUTs(this._atmosphereParams);
278
556
  }
279
- /** @internal */ get fogParams() {
280
- return this._fogParams;
557
+ renderSkyDistantLut(ctx, skybox) {
558
+ this._prepareSkyBox(ctx.device);
559
+ ctx.device.pushDeviceStates();
560
+ ctx.device.setRenderStates(SkyRenderer._renderStatesDistantLight);
561
+ ctx.device.setProgram(SkyRenderer._programDistantLight);
562
+ ctx.device.setFramebuffer(this._skyDistantLightLut.get());
563
+ ctx.device.clearFrameBuffer(new Vector4(0, 0, 0, 1), null, null);
564
+ this._bindgroupDistantLight.get().setTexture('skybox', skybox, fetchSampler('clamp_linear_nomip'));
565
+ ctx.device.setBindGroup(0, this._bindgroupDistantLight.get());
566
+ SkyRenderer._primitiveDistantLight.draw();
567
+ ctx.device.popDeviceStates();
281
568
  }
282
- set fogParams(val) {
283
- this._fogParams.set(val);
569
+ updateBakedSkyMap(ctx) {
570
+ const device = ctx.device;
571
+ const tex = this._bakedSkyboxTexture.get() && this._bakedSkyboxTexture.get().width === this._bakedSkyboxTextureSize ? this._bakedSkyboxTexture.get() : device.createCubeTexture(this.envTextureFormat, this._bakedSkyboxTextureSize, {
572
+ mipmapping: false
573
+ });
574
+ tex.name = 'BakedSkyboxTexture';
575
+ if (tex !== this._bakedSkyboxTexture.get()) {
576
+ this._bakedSkyboxFrameBuffer.set(device.createFrameBuffer([
577
+ tex
578
+ ], null));
579
+ }
580
+ const camera = SkyRenderer._skyCamera;
581
+ const saveRenderStates = device.getRenderStates();
582
+ device.pushDeviceStates();
583
+ device.setFramebuffer(this._bakedSkyboxFrameBuffer.get());
584
+ for (const face of [
585
+ CubeFace.PX,
586
+ CubeFace.NX,
587
+ CubeFace.PY,
588
+ CubeFace.NY,
589
+ CubeFace.PZ,
590
+ CubeFace.NZ
591
+ ]){
592
+ camera.lookAtCubeFace(face);
593
+ this._bakedSkyboxFrameBuffer.get().setColorAttachmentCubeFace(0, face);
594
+ this._renderSky(camera, false);
595
+ }
596
+ device.popDeviceStates();
597
+ this.renderSkyDistantLut(ctx, tex);
598
+ device.pushDeviceStates();
599
+ device.setFramebuffer(this._bakedSkyboxFrameBuffer.get());
600
+ for (const face of [
601
+ CubeFace.PX,
602
+ CubeFace.NX,
603
+ CubeFace.PY,
604
+ CubeFace.NY,
605
+ CubeFace.PZ,
606
+ CubeFace.NZ
607
+ ]){
608
+ camera.lookAtCubeFace(face);
609
+ this._bakedSkyboxFrameBuffer.get().setColorAttachmentCubeFace(0, face);
610
+ this.renderFog(camera);
611
+ }
612
+ device.popDeviceStates();
613
+ device.setRenderStates(saveRenderStates);
614
+ this._bakedSkyboxTexture.set(tex);
284
615
  }
285
- /**
286
- * Force the radiance map and irradiance map to be regenerated.
287
- */ invalidateIBLMaps() {
288
- this._radianceMapDirty = true;
289
- }
290
- /** @internal */ drawScatteredFog(ctx) {
291
- return ctx.sunLight && this._fogType === 'scatter';
292
- }
293
- /** @internal */ getAerialPerspectiveLUT(ctx) {
294
- if (this.drawScatteredFog(ctx)) {
295
- const sunDir = SkyRenderer._getSunDir(ctx.sunLight);
296
- const alpha = Math.PI / 2 - Math.acos(Math.max(-1, Math.min(1, sunDir.y)));
297
- const farPlane = ctx.camera.getFarPlane() * this._aerialPerspectiveDensity * this._aerialPerspectiveDensity;
298
- return ScatteringLut.getAerialPerspectiveLut(alpha, farPlane);
299
- } else {
300
- return null;
616
+ renderUberFog(camera, depthTexture) {
617
+ const device = getDevice();
618
+ const fogProgram = depthTexture ? SkyRenderer._programFog : SkyRenderer._programFogNoDepth;
619
+ const renderStates = SkyRenderer._renderStatesFog;
620
+ const bindgroup = depthTexture ? this._bindgroupFog.get() : this._bindgroupFogNoDepth.get();
621
+ if (depthTexture) {
622
+ bindgroup.setTexture('depthTex', depthTexture, fetchSampler('clamp_nearest_nomip'));
301
623
  }
624
+ bindgroup.setTexture('skyDistantLightLut', this._skyDistantLightLut.get().getColorAttachments()[0], fetchSampler('clamp_nearest_nomip'));
625
+ bindgroup.setTexture('apLut', getAerialPerspectiveLut(), fetchSampler('clamp_linear_nomip'));
626
+ bindgroup.setValue('rt', device.getFramebuffer() ? 1 : 0);
627
+ bindgroup.setValue('invProjViewMatrix', camera.invViewProjectionMatrix);
628
+ bindgroup.setValue('cameraNearFar', new Vector2(camera.getNearPlane(), camera.getFarPlane()));
629
+ bindgroup.setValue('cameraPosition', camera.getWorldPosition());
630
+ bindgroup.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);
631
+ bindgroup.setValue('withAerialPerspective', this.skyType === 'scatter' ? 1 : 0);
632
+ bindgroup.setValue('fogType', this.mappedFogType);
633
+ bindgroup.setValue('atmosphereParams', this._atmosphereParams);
634
+ bindgroup.setValue('heightFogParams', this._heightFogParams);
635
+ device.setProgram(fogProgram);
636
+ device.setBindGroup(0, bindgroup);
637
+ device.setVertexLayout(SkyRenderer._vertexLayout);
638
+ device.setRenderStates(renderStates);
639
+ device.draw('triangle-strip', 0, 4);
302
640
  }
303
- /**
304
- * Regenerate the radiance map and irradiance map
305
- *
306
- * @param sunLight - The sun light
307
- */ updateIBLMaps(sunDir) {
308
- const device = Application.instance.device;
309
- let bakedSkyboxTexture = null;
310
- if (this._skyType === 'skybox' && this._skyboxTexture) {
311
- bakedSkyboxTexture = this._skyboxTexture;
312
- } else {
313
- if (!this._scatterSkyboxFramebuffer) {
314
- const texCaps = device.getDeviceCaps().textureCaps;
315
- const format = texCaps.supportHalfFloatColorBuffer && texCaps.supportLinearHalfFloatTexture ? 'rgba16f' : texCaps.supportFloatColorBuffer && texCaps.supportLinearFloatTexture ? 'rgba32f' : 'rgba8unorm';
316
- const tex = device.createCubeTexture(format, this._scatterSkyboxTextureWidth);
317
- tex.name = 'BakedSkyboxTexture';
318
- this._scatterSkyboxFramebuffer = device.createFrameBuffer([
319
- tex
320
- ], null);
321
- this._radianceMapDirty = true;
322
- }
323
- const camera = new Camera(null);
324
- camera.setPerspective(Math.PI / 2, 1, 1, 20);
325
- const saveRenderStates = device.getRenderStates();
641
+ /** @internal */ renderFog(camera) {
642
+ const device = getDevice();
643
+ const currentFramebuffer = device.getFramebuffer();
644
+ const depthBuffer = currentFramebuffer?.getDepthAttachment() ?? null;
645
+ const colorBuffer = currentFramebuffer?.getColorAttachments()[0] ?? null;
646
+ const fogFramebuffer = depthBuffer && colorBuffer ? device.pool.fetchTemporalFramebuffer(false, 0, 0, colorBuffer, null, false) : null;
647
+ if (fogFramebuffer) {
648
+ const vp = device.getViewport();
649
+ const scissor = device.getScissor();
326
650
  device.pushDeviceStates();
327
- device.setFramebuffer(this._scatterSkyboxFramebuffer);
328
- for (const face of [
329
- CubeFace.PX,
330
- CubeFace.NX,
331
- CubeFace.PY,
332
- CubeFace.NY,
333
- CubeFace.PZ,
334
- CubeFace.NZ
335
- ]){
336
- camera.lookAtCubeFace(face);
337
- this._scatterSkyboxFramebuffer.setColorAttachmentCubeFace(0, face);
338
- this._renderSky(camera, false, sunDir, true, false);
339
- }
340
- device.popDeviceStates();
341
- device.setRenderStates(saveRenderStates);
342
- bakedSkyboxTexture = this._scatterSkyboxFramebuffer.getColorAttachments()[0];
651
+ device.setFramebuffer(fogFramebuffer);
652
+ device.setViewport(vp);
653
+ device.setScissor(scissor);
343
654
  }
344
- prefilterCubemap(bakedSkyboxTexture, 'ggx', this.radianceMap);
345
- prefilterCubemap(bakedSkyboxTexture, 'lambertian', this.irradianceMap);
346
- }
347
- /** @internal */ renderFog(ctx) {
348
- const camera = ctx.camera;
349
- const sceneDepthTexture = ctx.linearDepthTexture;
350
- const device = ctx.device;
351
655
  const savedRenderStates = device.getRenderStates();
352
656
  this._prepareSkyBox(device);
353
- const sunLight = ctx.sunLight;
354
- if (this._fogType === 'scatter' && !sunLight) {
355
- console.error('Cannot render scattering fog without sun light');
356
- return;
357
- }
358
- const fogProgram = this._fogType === 'scatter' ? this._programFogScatter : this._programFog;
359
- const renderStates = this._fogType === 'scatter' ? this._renderStatesFogScatter : this._renderStatesFog;
360
- if (fogProgram && sceneDepthTexture) {
361
- const bindgroup = this._fogType === 'scatter' ? this._bindgroupFogScatter : this._bindgroupFog;
362
- bindgroup.setTexture('depthTex', sceneDepthTexture, fetchSampler('clamp_nearest_nomip'));
363
- bindgroup.setValue('rt', device.getFramebuffer() ? 1 : 0);
364
- bindgroup.setValue('invProjViewMatrix', camera.invViewProjectionMatrix);
365
- bindgroup.setValue('cameraNearFar', new Vector2(camera.getNearPlane(), camera.getFarPlane()));
366
- bindgroup.setValue('cameraPosition', camera.getWorldPosition());
367
- bindgroup.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);
368
- if (this._fogType === 'scatter') {
369
- const sunDir = sunLight ? sunLight.directionAndCutoff.xyz().scaleBy(-1) : ShaderHelper.defaultSunDir;
370
- const alpha = Math.PI / 2 - Math.acos(Math.max(-1, Math.min(1, sunDir.y)));
371
- const scale = this._aerialPerspectiveDensity * this._aerialPerspectiveDensity;
372
- const farPlane = ctx.camera.getFarPlane() * scale;
373
- bindgroup.setTexture('apLut', ScatteringLut.getAerialPerspectiveLut(alpha, farPlane));
374
- bindgroup.setValue('sliceDist', farPlane / ScatteringLut.aerialPerspectiveSliceZ);
375
- bindgroup.setValue('sunDir', sunDir);
376
- bindgroup.setValue('worldScale', scale);
377
- } else {
378
- bindgroup.setValue('fogType', this.mappedFogType);
379
- bindgroup.setValue('fogColor', this._fogColor);
380
- bindgroup.setValue('fogParams', this._fogParams);
381
- }
382
- device.setProgram(fogProgram);
383
- device.setBindGroup(0, bindgroup);
384
- device.setVertexLayout(this._vertexLayout);
385
- device.setRenderStates(renderStates);
386
- device.draw('triangle-strip', 0, 4);
387
- device.setRenderStates(savedRenderStates);
657
+ this.renderUberFog(camera, depthBuffer);
658
+ /*
659
+ if (this._skyType === 'scatter') {
660
+ this.renderAtmosphericFog(ctx, depthBuffer);
661
+ }
662
+ */ /*
663
+ if (this._fogType === 'height_fog') {
664
+ this.renderHeightFog(ctx, depthBuffer);
665
+ }
666
+ */ device.setRenderStates(savedRenderStates);
667
+ if (fogFramebuffer) {
668
+ device.popDeviceStates();
669
+ device.pool.releaseFrameBuffer(fogFramebuffer);
388
670
  }
389
671
  }
390
672
  /** @internal */ renderSky(ctx) {
391
- const sunDir = SkyRenderer._getSunDir(ctx.sunLight);
392
- if (!sunDir.equalsTo(this._lastSunDir)) {
393
- this._radianceMapDirty = true;
394
- this._lastSunDir.set(sunDir);
673
+ let skyCamera = ctx.camera;
674
+ if (!skyCamera.isPerspective()) {
675
+ skyCamera = SkyRenderer._skyCamera;
676
+ ctx.camera.worldMatrix.decompose(null, skyCamera.rotation, null);
395
677
  }
396
- this._renderSky(ctx.camera, true, sunDir, this._drawGround, this._skyType === 'scatter' && this._cloudy > 0);
397
- if (this._radianceMapDirty && ctx.env.light.type === 'ibl') {
398
- if (ctx.env.light.radianceMap && (ctx.env.light.radianceMap === this._radianceMap || ctx.env.light.irradianceMap === this._irradianceMap)) {
399
- this._radianceMapDirty = false;
400
- this.updateIBLMaps(sunDir);
401
- }
678
+ this._renderSky(skyCamera, true);
679
+ }
680
+ /** Disposes resources of this SkyRenderer */ onDispose() {
681
+ super.onDispose();
682
+ this._skyboxTexture.dispose();
683
+ this._bakedSkyboxTexture.dispose();
684
+ this._bakedSkyboxFrameBuffer.dispose();
685
+ this._radianceMap.dispose();
686
+ this._radianceFrameBuffer.dispose();
687
+ this._irradianceSH.dispose();
688
+ this._irradianceSHFB.dispose();
689
+ this._irradianceFrameBuffer.dispose();
690
+ this._shProjector.dispose();
691
+ if (this._skyDistantLightLut.get()) {
692
+ this._skyDistantLightLut.get().getColorAttachments()[0].dispose();
693
+ this._skyDistantLightLut.dispose();
694
+ }
695
+ this._bindgroupDistantLight.dispose();
696
+ for (const k of objectKeys(this._bindgroupSky)){
697
+ this._bindgroupSky[k]?.dispose();
698
+ }
699
+ this._bindgroupSky = {};
700
+ this._bindgroupFog.dispose();
701
+ this._bindgroupFogNoDepth.dispose();
702
+ }
703
+ /** @internal */ _updateSkyboxTexture() {
704
+ if (this._panoramaAsset) {
705
+ getEngine().resourceManager.fetchTexture(this._panoramaAsset).then((tex)=>{
706
+ if (!tex.isTexture2D()) {
707
+ console.error(`Invalid panorama texture asset: ${this._panoramaAsset}`);
708
+ } else {
709
+ const skyboxTexture = getDevice().createCubeTexture(this.envTextureFormat, this._skyboxTextureSize, {
710
+ mipmapping: false
711
+ });
712
+ panoramaToCubemap(tex, skyboxTexture);
713
+ skyboxTexture.name = 'SkyboxTexture';
714
+ this.skyboxTexture = skyboxTexture;
715
+ }
716
+ }).catch((err)=>{
717
+ console.error(`Load asset failed: ${this._panoramaAsset}: ${err}`);
718
+ });
402
719
  }
403
720
  }
404
- /** @internal */ _renderSky(camera, depthTest, sunDir, drawGround, drawCloud) {
405
- const device = Application.instance.device;
721
+ /** @internal */ _renderSky(camera, depthTest) {
722
+ const device = getDevice();
406
723
  const savedRenderStates = device.getRenderStates();
407
724
  this._prepareSkyBox(device);
408
725
  if (this._skyType === 'scatter') {
409
- this._drawScattering(camera, sunDir, depthTest, drawGround, drawCloud);
410
- } else if (this._skyType === 'skybox' && this._skyboxTexture) {
726
+ this._drawScattering(camera, depthTest);
727
+ } else if (this._skyType === 'skybox' && this.skyboxTexture) {
411
728
  this._drawSkybox(camera, depthTest);
412
729
  } else {
413
730
  this._drawSkyColor(camera, depthTest);
@@ -415,215 +732,216 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
415
732
  device.setRenderStates(savedRenderStates);
416
733
  }
417
734
  /** @internal */ _drawSkyColor(camera, depthTest) {
418
- const device = Application.instance.device;
419
- const bindgroup = this._bindgroupSky.color;
420
- bindgroup.setValue('viewProjMatrix', camera.viewProjectionMatrix);
421
- bindgroup.setValue('worldMatrix', this._skyWorldMatrix);
422
- bindgroup.setValue('cameraPos', camera.getWorldPosition());
735
+ const device = getDevice();
736
+ const bindgroup = this._bindgroupSky.image.get();
423
737
  bindgroup.setValue('color', this._skyColor);
738
+ bindgroup.setTexture('texture', this._skyImage.get() ?? SkyRenderer._defaultSkyImage.get(), fetchSampler('clamp_linear_nomip'));
739
+ bindgroup.setValue('flip', device.getFramebuffer() && device.type === 'webgpu' ? -1 : 1);
424
740
  bindgroup.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);
425
- device.setProgram(this._programSky.color);
741
+ device.setProgram(SkyRenderer._programSky.image);
426
742
  device.setBindGroup(0, bindgroup);
427
- device.setRenderStates(depthTest ? this._renderStatesSky : this._renderStatesSkyNoDepthTest);
428
- this._primitiveSky.draw();
743
+ drawFullscreenQuad(depthTest ? SkyRenderer._renderStatesSky : SkyRenderer._renderStatesSkyNoDepthTest);
429
744
  }
430
745
  /** @internal */ _drawSkybox(camera, depthTest) {
431
- const device = Application.instance.device;
432
- const bindgroup = this._bindgroupSky.skybox;
433
- bindgroup.setTexture('skyCubeMap', this._skyboxTexture);
746
+ const device = getDevice();
747
+ const bindgroup = this._bindgroupSky.skybox.get();
748
+ bindgroup.setTexture('skyCubeMap', this.skyboxTexture, fetchSampler('clamp_linear_nomip'));
434
749
  bindgroup.setValue('flip', device.getFramebuffer() && device.type === 'webgpu' ? new Vector4(1, -1, 1, 1) : new Vector4(1, 1, 1, 1));
435
750
  bindgroup.setValue('viewProjMatrix', camera.viewProjectionMatrix);
436
751
  bindgroup.setValue('worldMatrix', this._skyWorldMatrix);
437
752
  bindgroup.setValue('cameraPos', camera.getWorldPosition());
438
753
  bindgroup.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);
439
- device.setProgram(this._programSky.skybox);
754
+ device.setProgram(SkyRenderer._programSky.skybox);
440
755
  device.setBindGroup(0, bindgroup);
441
- device.setRenderStates(depthTest ? this._renderStatesSky : this._renderStatesSkyNoDepthTest);
442
- this._primitiveSky.draw();
443
- }
444
- /** @internal */ _drawScattering(camera, sunDir, depthTest, drawGround, drawCloud) {
445
- const device = Application.instance.device;
446
- const alpha = Math.PI / 2 - Math.acos(Math.max(-1, Math.min(1, sunDir.y)));
447
- const tLut = ScatteringLut.getTransmittanceLut();
448
- const skyLut = ScatteringLut.getSkyViewLut(alpha);
756
+ device.setRenderStates(depthTest ? SkyRenderer._renderStatesSky : SkyRenderer._renderStatesSkyNoDepthTest);
757
+ SkyRenderer._primitiveSky.draw();
758
+ }
759
+ /** @internal */ _rayIntersectSphere(radius, rayStart, rayDir) {
760
+ const OS = rayStart.magnitude;
761
+ const SH = -Vector3.dot(rayStart, rayDir);
762
+ const OH = Math.sqrt(Math.max(0, OS * OS - SH * SH));
763
+ const PH = Math.sqrt(Math.max(0, radius * radius - OH * OH));
764
+ if (OH > radius) {
765
+ return -1;
766
+ }
767
+ const t1 = SH - PH;
768
+ const t2 = SH + PH;
769
+ return t1 < 0 ? t2 : t1;
770
+ }
771
+ /** @internal */ sunTransmittance(sunLight) {
772
+ const TRANSMITTANCE_SAMPLES = 32;
773
+ const RAYLEIGH_SIGMA = [
774
+ 5.802,
775
+ 13.558,
776
+ 33.1
777
+ ];
778
+ const MIE_SIGMA = 3.996;
779
+ const MIE_ABSORPTION_SIGMA = 4.4;
780
+ const OZONE_ABSORPTION_SIGMA = [
781
+ 0.65,
782
+ 1.881,
783
+ 0.085
784
+ ];
785
+ function rayleighSc(params, fH) {
786
+ const sigma = new Vector3(RAYLEIGH_SIGMA[0] * 1e-6, RAYLEIGH_SIGMA[1] * 1e-6, RAYLEIGH_SIGMA[2] * 1e-6);
787
+ const rho_h = Math.exp(-fH / params.rayleighScatteringHeight);
788
+ return Vector3.scale(sigma, rho_h);
789
+ }
790
+ function mieSc(params, fH) {
791
+ const sigma = new Vector3(MIE_SIGMA * 1e-6, MIE_SIGMA * 1e-6, MIE_SIGMA * 1e-6);
792
+ const rho_h = Math.exp(-(fH / params.mieScatteringHeight));
793
+ return Vector3.scale(sigma, rho_h);
794
+ }
795
+ function mieAb(params, fH) {
796
+ const sigma = new Vector3(MIE_ABSORPTION_SIGMA * 1e-6, MIE_ABSORPTION_SIGMA * 1e-6, MIE_ABSORPTION_SIGMA * 1e-6);
797
+ const rho_h = Math.exp(-(fH / params.mieScatteringHeight));
798
+ return Vector3.scale(sigma, rho_h);
799
+ }
800
+ function ozoneAb(params, fH) {
801
+ const sigma = new Vector3(OZONE_ABSORPTION_SIGMA[0] * 1e-6, OZONE_ABSORPTION_SIGMA[1] * 1e-6, OZONE_ABSORPTION_SIGMA[2] * 1e-6);
802
+ const rho_h = Math.max(0, 1 - Math.abs(fH - params.ozoneCenter) * 0.5 / params.ozoneWidth);
803
+ return Vector3.scale(sigma, rho_h);
804
+ }
805
+ const eyePos = new Vector3(0, this._atmosphereParams.plantRadius + this._atmosphereParams.cameraHeightScale, 0);
806
+ const lightDir = SkyRenderer._getSunDir(sunLight);
807
+ const d = this._rayIntersectSphere(this._atmosphereParams.plantRadius + this._atmosphereParams.atmosphereHeight, eyePos, lightDir);
808
+ if (d < 0) {
809
+ return new Vector3(0, 0, 0);
810
+ }
811
+ const ds = d / TRANSMITTANCE_SAMPLES;
812
+ const sum = new Vector3(0, 0, 0);
813
+ const p = Vector3.combine(eyePos, lightDir, 1, ds * 0.5);
814
+ for(let i = 0; i < TRANSMITTANCE_SAMPLES; i++){
815
+ const h = p.magnitude - this._atmosphereParams.plantRadius;
816
+ const scattering = Vector3.add(rayleighSc(this._atmosphereParams, h), mieSc(this._atmosphereParams, h));
817
+ const absorption = Vector3.add(ozoneAb(this._atmosphereParams, h), mieAb(this._atmosphereParams, h));
818
+ const extinction = Vector3.add(scattering, absorption);
819
+ Vector3.add(sum, Vector3.scale(extinction, ds), sum);
820
+ Vector3.add(p, Vector3.scale(lightDir, ds), p);
821
+ }
822
+ return new Vector3(Math.exp(-sum.x), Math.exp(-sum.y), Math.exp(-sum.z));
823
+ }
824
+ /** @internal */ _drawScattering(camera, depthTest) {
825
+ const device = getDevice();
826
+ const tLut = getTransmittanceLut();
827
+ const skyLut = getSkyViewLut();
449
828
  //const apLut = ScatteringLut.getAerialPerspectiveLut(alpha, 8000);
450
- const program = drawCloud ? this._programSky.scatter : this._programSky['scatter-nocloud'];
451
- const bindgroup = drawCloud ? this._bindgroupSky.scatter : this._bindgroupSky['scatter-nocloud'];
452
- bindgroup.setValue('sunDir', sunDir);
829
+ const program = SkyRenderer._programSky.scatter;
830
+ const bindgroup = this._bindgroupSky.scatter.get();
453
831
  bindgroup.setValue('flip', device.getFramebuffer() && device.type === 'webgpu' ? new Vector4(1, -1, 1, 1) : new Vector4(1, 1, 1, 1));
832
+ bindgroup.setValue('params', this._atmosphereParams);
454
833
  bindgroup.setValue('viewProjMatrix', camera.viewProjectionMatrix);
455
834
  bindgroup.setValue('worldMatrix', this._skyWorldMatrix);
456
835
  bindgroup.setValue('cameraPos', camera.getWorldPosition());
457
836
  bindgroup.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);
458
- bindgroup.setTexture('tLut', tLut);
459
- bindgroup.setTexture('skyLut', skyLut);
460
- if (drawCloud) {
461
- bindgroup.setValue('cloudy', this._cloudy);
462
- bindgroup.setValue('cloudIntensity', this._cloudIntensity);
463
- bindgroup.setValue('time', device.frameInfo.elapsedOverall * 0.001);
464
- bindgroup.setValue('velocity', this._wind);
465
- }
466
- bindgroup.setValue('drawGround', drawGround ? 1 : 0);
837
+ bindgroup.setTexture('tLut', tLut, fetchSampler('clamp_linear_nomip'));
838
+ bindgroup.setTexture('skyLut', skyLut, fetchSampler('clamp_linear_nomip'));
839
+ bindgroup.setValue('cloudy', this._cloudy);
840
+ bindgroup.setValue('cloudIntensity', this._cloudIntensity);
841
+ bindgroup.setValue('time', device.frameInfo.elapsedOverall * 0.001);
842
+ bindgroup.setValue('velocity', this._wind);
467
843
  device.setProgram(program);
468
844
  device.setBindGroup(0, bindgroup);
469
- device.setRenderStates(depthTest ? this._renderStatesSky : this._renderStatesSkyNoDepthTest);
470
- this._primitiveSky.draw();
845
+ device.setRenderStates(depthTest ? SkyRenderer._renderStatesSky : SkyRenderer._renderStatesSkyNoDepthTest);
846
+ SkyRenderer._primitiveSky.draw();
471
847
  }
472
848
  /** @internal */ _prepareSkyBox(device) {
473
- if (!this._programFogScatter) {
474
- this._programFogScatter = device.buildRenderProgram({
475
- label: 'FogScatter',
849
+ SkyRenderer._createAtmosphereLUTPrograms(device);
850
+ if (!SkyRenderer._defaultSkyImage.get()) {
851
+ const texture = device.createTexture2D('rgba8unorm', 1, 1, {
852
+ mipmapping: false
853
+ });
854
+ texture.update(new Uint8Array([
855
+ 255,
856
+ 255,
857
+ 255,
858
+ 255
859
+ ]), 0, 0, 1, 1);
860
+ SkyRenderer._defaultSkyImage.set(texture);
861
+ }
862
+ if (!SkyRenderer._programDistantLight) {
863
+ SkyRenderer._programDistantLight = device.buildRenderProgram({
476
864
  vertex (pb) {
477
- this.rt = pb.int().uniform(0);
478
- this.$inputs.pos = pb.vec2().attrib('position');
479
- this.$outputs.uv = pb.vec2();
865
+ this.$inputs.vector = pb.vec3().attrib('position');
480
866
  pb.main(function() {
481
- this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
482
- this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
483
- if (device.type === 'webgpu') {
484
- this.$if(pb.notEqual(this.rt, 0), function() {
485
- this.$builtins.position.y = pb.neg(this.$builtins.position.y);
486
- });
867
+ this.$outputs.vector = this.$inputs.vector;
868
+ this.$builtins.position = pb.vec4(0, 0, 0, 1);
869
+ if (pb.getDevice().type !== 'webgpu') {
870
+ this.$builtins.pointSize = 1;
487
871
  }
488
872
  });
489
873
  },
490
874
  fragment (pb) {
491
- this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
492
- this.invProjViewMatrix = pb.mat4().uniform(0);
493
- this.cameraNearFar = pb.vec2().uniform(0);
494
- this.cameraPosition = pb.vec3().uniform(0);
495
- this.apLut = pb.tex2D().uniform(0);
496
- this.worldScale = pb.float().uniform(0);
497
- this.sliceDist = pb.float().uniform(0);
498
- this.sunDir = pb.vec3().uniform(0);
499
- this.srgbOut = pb.int().uniform(0);
500
- this.$outputs.outColor = pb.vec4();
875
+ this.$outputs.color = pb.vec4();
876
+ this.skybox = pb.texCube().uniform(0);
501
877
  pb.main(function() {
502
- this.$l.depthValue = pb.textureSample(this.depthTex, this.$inputs.uv);
503
- if (device.type === 'webgl') {
504
- this.$l.linearDepth = decodeNormalizedFloatFromRGBA(this, this.depthValue);
505
- } else {
506
- this.$l.linearDepth = this.depthValue.r;
507
- }
508
- this.$l.nonLinearDepth = pb.div(pb.sub(pb.div(this.cameraNearFar.x, this.linearDepth), this.cameraNearFar.y), pb.sub(this.cameraNearFar.x, this.cameraNearFar.y));
509
- //this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), this.nonLinearDepth, 1);
510
- this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), pb.sub(pb.mul(this.nonLinearDepth, 2), 1), 1);
511
- this.$l.hPos = pb.mul(this.invProjViewMatrix, this.clipSpacePos);
512
- this.$l.hPos = pb.div(this.$l.hPos, this.$l.hPos.w);
513
- this.$l.viewDir = pb.sub(this.hPos.xyz, this.cameraPosition);
514
- // Assume object is above the sea level
515
- this.viewDir.y = pb.max(0, this.viewDir.y);
516
- this.$l.distance = pb.mul(pb.length(this.viewDir), this.worldScale);
517
- this.$l.slice0 = pb.floor(pb.div(this.distance, this.sliceDist));
518
- this.$l.slice1 = pb.add(this.slice0, 1);
519
- this.$l.factor = pb.sub(pb.div(this.distance, this.sliceDist), this.slice0);
520
- this.$l.viewNormal = pb.normalize(this.viewDir);
521
- this.$l.horizonAngle = pb.acos(pb.clamp(pb.dot(pb.normalize(this.sunDir.xz), pb.normalize(this.viewNormal.xz)), 0, 1));
522
- this.$l.zenithAngle = pb.asin(this.viewNormal.y);
523
- this.$l.sliceU = pb.max(pb.div(this.horizonAngle, Math.PI * 2), 0.5 / ScatteringLut.aerialPerspectiveSliceZ);
524
- this.$l.u0 = pb.div(pb.add(this.slice0, this.sliceU), ScatteringLut.aerialPerspectiveSliceZ);
525
- this.$l.u1 = pb.add(this.u0, 1 / ScatteringLut.aerialPerspectiveSliceZ);
526
- this.$l.v = pb.div(this.zenithAngle, Math.PI / 2);
527
- this.$l.t0 = pb.textureSampleLevel(this.apLut, pb.vec2(this.u0, this.v), 0);
528
- this.$l.t1 = pb.textureSampleLevel(this.apLut, pb.vec2(this.u1, this.v), 0);
529
- this.$l.t = pb.mix(this.t0, this.t1, this.factor);
530
- this.$outputs.outColor = pb.vec4(this.t.rgb, pb.sub(1, this.t.a));
878
+ this.$l.sunColor = pb.vec4();
879
+ this.$l.skyColor = pb.textureSampleLevel(this.skybox, this.$inputs.vector, 0).rgb;
880
+ this.$outputs.color = pb.vec4(pb.mul(this.skyColor, 1 / 64), 1);
531
881
  });
532
882
  }
533
883
  });
534
- this._bindgroupFogScatter = device.createBindGroup(this._programFogScatter.bindGroupLayouts[0]);
884
+ SkyRenderer._programDistantLight.name = '@SkyDistantLight';
885
+ }
886
+ if (!this._bindgroupDistantLight.get()) {
887
+ this._bindgroupDistantLight.set(device.createBindGroup(SkyRenderer._programDistantLight.bindGroupLayouts[0]));
888
+ }
889
+ if (!SkyRenderer._programFog) {
890
+ SkyRenderer._programFog = SkyRenderer._createFogProgram(device, false);
891
+ }
892
+ if (!SkyRenderer._programFogNoDepth) {
893
+ SkyRenderer._programFogNoDepth = SkyRenderer._createFogProgram(device, true);
894
+ }
895
+ if (!this._bindgroupFog.get()) {
896
+ this._bindgroupFog.set(device.createBindGroup(SkyRenderer._programFog.bindGroupLayouts[0]));
897
+ }
898
+ if (!this._bindgroupFogNoDepth.get()) {
899
+ this._bindgroupFogNoDepth.set(device.createBindGroup(SkyRenderer._programFogNoDepth.bindGroupLayouts[0]));
535
900
  }
536
- if (!this._programFog) {
537
- this._programFog = device.buildRenderProgram({
538
- label: 'Fog',
901
+ if (!SkyRenderer._programSky.image) {
902
+ SkyRenderer._programSky.image = device.buildRenderProgram({
903
+ label: 'ImageSky',
539
904
  vertex (pb) {
540
- this.rt = pb.int().uniform(0);
541
905
  this.$inputs.pos = pb.vec2().attrib('position');
542
906
  this.$outputs.uv = pb.vec2();
907
+ this.flip = pb.int().uniform(0);
543
908
  pb.main(function() {
544
909
  this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
545
910
  this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
546
- if (device.type === 'webgpu') {
547
- this.$if(pb.notEqual(this.rt, 0), function() {
548
- this.$builtins.position.y = pb.neg(this.$builtins.position.y);
549
- });
911
+ if (device.type !== 'webgpu') {
912
+ this.$builtins.position.y = pb.neg(this.$builtins.position.y);
550
913
  }
551
914
  });
552
915
  },
553
- fragment (pb) {
554
- this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
555
- this.invProjViewMatrix = pb.mat4().uniform(0);
556
- this.cameraNearFar = pb.vec2().uniform(0);
557
- this.cameraPosition = pb.vec3().uniform(0);
558
- this.fogType = pb.int().uniform(0);
559
- this.fogColor = pb.vec4().uniform(0);
560
- this.fogParams = pb.vec4().uniform(0);
561
- this.srgbOut = pb.int().uniform(0);
562
- this.$outputs.outColor = pb.vec4();
563
- pb.main(function() {
564
- this.$l.depthValue = pb.textureSample(this.depthTex, this.$inputs.uv);
565
- if (device.type === 'webgl') {
566
- this.$l.linearDepth = decodeNormalizedFloatFromRGBA(this, this.depthValue);
567
- } else {
568
- this.$l.linearDepth = this.depthValue.r;
569
- }
570
- this.$l.nonLinearDepth = pb.div(pb.sub(pb.div(this.cameraNearFar.x, this.linearDepth), this.cameraNearFar.y), pb.sub(this.cameraNearFar.x, this.cameraNearFar.y));
571
- //this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), this.nonLinearDepth, 1);
572
- this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), pb.sub(pb.mul(this.nonLinearDepth, 2), 1), 1);
573
- this.$l.hPos = pb.mul(this.invProjViewMatrix, this.clipSpacePos);
574
- this.$l.hPos = pb.div(this.$l.hPos, this.$l.hPos.w);
575
- this.$l.viewDir = pb.sub(this.hPos.xyz, this.cameraPosition);
576
- this.$l.fogFactor = ShaderHelper.computeFogFactor(this, this.viewDir, this.fogType, this.fogParams);
577
- this.$l.color = pb.mul(this.fogColor.rgb, this.fogFactor);
578
- this.$if(pb.equal(this.srgbOut, 0), function() {
579
- this.$outputs.outColor = pb.vec4(this.color, this.fogFactor);
580
- }).$else(function() {
581
- this.$outputs.outColor = pb.vec4(linearToGamma(this, this.color), this.fogFactor);
582
- });
583
- });
584
- }
585
- });
586
- this._bindgroupFog = device.createBindGroup(this._programFog.bindGroupLayouts[0]);
587
- }
588
- if (!this._programSky.color) {
589
- this._programSky.color = device.buildRenderProgram({
590
- label: 'SolidColorSky',
591
- vertex (pb) {
592
- this.$inputs.pos = pb.vec3().attrib('position');
593
- this.worldMatrix = pb.mat4().uniform(0);
594
- this.viewProjMatrix = pb.mat4().uniform(0);
595
- this.cameraPos = pb.vec3().uniform(0);
596
- pb.main(function() {
597
- this.$l.worldDirection = pb.mul(this.worldMatrix, pb.vec4(this.$inputs.pos, 0)).xyz;
598
- this.$builtins.position = pb.mul(this.viewProjMatrix, pb.vec4(pb.add(this.worldDirection, this.cameraPos), 1));
599
- this.$builtins.position.z = this.$builtins.position.w;
600
- });
601
- },
602
916
  fragment (pb) {
603
917
  this.$outputs.outColor = pb.vec4();
604
918
  this.color = pb.vec4().uniform(0);
919
+ this.texture = pb.tex2D().uniform(0);
605
920
  this.srgbOut = pb.int().uniform(0);
606
921
  pb.main(function() {
922
+ this.$l.sampleColor = pb.textureSampleLevel(this.texture, this.$inputs.uv, 0);
923
+ this.$l.outColor = pb.mul(this.sampleColor, this.color);
607
924
  this.$if(pb.equal(this.srgbOut, 0), function() {
608
- this.$outputs.outColor = pb.vec4(this.color.rgb, 1);
925
+ this.$outputs.outColor = pb.vec4(this.outColor.rgb, 1);
609
926
  }).$else(function() {
610
- this.$outputs.outColor = pb.vec4(linearToGamma(this, this.color.rgb), 1);
927
+ this.$outputs.outColor = pb.vec4(linearToGamma(this, this.outColor.rgb), 1);
611
928
  });
612
929
  });
613
930
  }
614
931
  });
615
- this._bindgroupSky.color = device.createBindGroup(this._programSky.color.bindGroupLayouts[0]);
932
+ SkyRenderer._programSky.image.name = '@SkyImage';
933
+ }
934
+ if (!this._bindgroupSky.image) {
935
+ this._bindgroupSky.image = new DRef(device.createBindGroup(SkyRenderer._programSky.image.bindGroupLayouts[0]));
616
936
  }
617
- if (!this._programSky.scatter) {
618
- this._programSky.scatter = SkyRenderer._createScatterProgram(device, true);
619
- this._bindgroupSky.scatter = device.createBindGroup(this._programSky.scatter.bindGroupLayouts[0]);
937
+ if (!SkyRenderer._programSky.scatter) {
938
+ SkyRenderer._programSky.scatter = SkyRenderer._createScatterProgram(device, true);
620
939
  }
621
- if (!this._programSky['scatter-nocloud']) {
622
- this._programSky['scatter-nocloud'] = SkyRenderer._createScatterProgram(device, false);
623
- this._bindgroupSky['scatter-nocloud'] = device.createBindGroup(this._programSky['scatter-nocloud'].bindGroupLayouts[0]);
940
+ if (!this._bindgroupSky.scatter) {
941
+ this._bindgroupSky.scatter = new DRef(device.createBindGroup(SkyRenderer._programSky.scatter.bindGroupLayouts[0]));
624
942
  }
625
- if (!this._programSky.skybox) {
626
- this._programSky.skybox = device.buildRenderProgram({
943
+ if (!SkyRenderer._programSky.skybox) {
944
+ SkyRenderer._programSky.skybox = device.buildRenderProgram({
627
945
  label: 'SkyBoxSky',
628
946
  vertex (pb) {
629
947
  this.$inputs.pos = pb.vec3().attrib('position');
@@ -654,32 +972,41 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
654
972
  });
655
973
  }
656
974
  });
657
- this._bindgroupSky.skybox = device.createBindGroup(this._programSky.skybox.bindGroupLayouts[0]);
658
- }
659
- if (!this._renderStatesSky) {
660
- this._renderStatesSky = device.createRenderStateSet();
661
- this._renderStatesSky.useDepthState().enableTest(true).enableWrite(false).setCompareFunc('le');
662
- this._renderStatesSky.useRasterizerState().setCullMode('none');
663
- }
664
- if (!this._renderStatesSkyNoDepthTest) {
665
- this._renderStatesSkyNoDepthTest = device.createRenderStateSet();
666
- this._renderStatesSkyNoDepthTest.useDepthState().enableTest(false).enableWrite(false);
667
- this._renderStatesSkyNoDepthTest.useRasterizerState().setCullMode('none');
668
- }
669
- if (!this._renderStatesFog) {
670
- this._renderStatesFog = device.createRenderStateSet();
671
- this._renderStatesFog.useRasterizerState().setCullMode('none');
672
- this._renderStatesFog.useBlendingState().enable(true).setBlendFunc('one', 'inv-src-alpha');
673
- this._renderStatesFog.useDepthState().enableTest(false).enableWrite(false);
674
- }
675
- if (!this._renderStatesFogScatter) {
676
- this._renderStatesFogScatter = device.createRenderStateSet();
677
- this._renderStatesFogScatter.useRasterizerState().setCullMode('none');
678
- this._renderStatesFogScatter.useBlendingState().enable(true).setBlendFunc('one', 'inv-src-alpha');
679
- this._renderStatesFogScatter.useDepthState().enableTest(true).enableWrite(false).setCompareFunc('gt');
680
- }
681
- if (!this._vertexLayout) {
682
- this._vertexLayout = device.createVertexLayout({
975
+ SkyRenderer._programSky.skybox.name = '@SkySkybox';
976
+ }
977
+ if (!this._bindgroupSky.skybox) {
978
+ this._bindgroupSky.skybox = new DRef(device.createBindGroup(SkyRenderer._programSky.skybox.bindGroupLayouts[0]));
979
+ }
980
+ if (!SkyRenderer._renderStatesSky) {
981
+ SkyRenderer._renderStatesSky = device.createRenderStateSet();
982
+ SkyRenderer._renderStatesSky.useDepthState().enableTest(true).enableWrite(false).setCompareFunc('le');
983
+ SkyRenderer._renderStatesSky.useRasterizerState().setCullMode('none');
984
+ }
985
+ if (!SkyRenderer._renderStatesSkyNoDepthTest) {
986
+ SkyRenderer._renderStatesSkyNoDepthTest = device.createRenderStateSet();
987
+ SkyRenderer._renderStatesSkyNoDepthTest.useDepthState().enableTest(false).enableWrite(false);
988
+ SkyRenderer._renderStatesSkyNoDepthTest.useRasterizerState().setCullMode('none');
989
+ }
990
+ if (!SkyRenderer._renderStatesFog) {
991
+ SkyRenderer._renderStatesFog = device.createRenderStateSet();
992
+ SkyRenderer._renderStatesFog.useRasterizerState().setCullMode('none');
993
+ SkyRenderer._renderStatesFog.useBlendingState().enable(true).setBlendFunc('one', 'src-alpha');
994
+ SkyRenderer._renderStatesFog.useDepthState().enableTest(false).enableWrite(false);
995
+ }
996
+ if (!SkyRenderer._renderStatesFogScatter) {
997
+ SkyRenderer._renderStatesFogScatter = device.createRenderStateSet();
998
+ SkyRenderer._renderStatesFogScatter.useRasterizerState().setCullMode('none');
999
+ SkyRenderer._renderStatesFogScatter.useBlendingState().enable(true).setBlendFunc('one', 'src-alpha');
1000
+ SkyRenderer._renderStatesFogScatter.useDepthState().enableTest(true).enableWrite(false).setCompareFunc('gt');
1001
+ }
1002
+ if (!SkyRenderer._renderStatesDistantLight) {
1003
+ SkyRenderer._renderStatesDistantLight = device.createRenderStateSet();
1004
+ SkyRenderer._renderStatesDistantLight.useDepthState().enableTest(false).enableWrite(false);
1005
+ SkyRenderer._renderStatesDistantLight.useBlendingState().enable(true).setBlendEquation('add', 'add').setBlendFuncRGB('one', 'one').setBlendFuncAlpha('zero', 'one');
1006
+ SkyRenderer._renderStatesDistantLight.useRasterizerState().setCullMode('none');
1007
+ }
1008
+ if (!SkyRenderer._vertexLayout) {
1009
+ SkyRenderer._vertexLayout = device.createVertexLayout({
683
1010
  vertexBuffers: [
684
1011
  {
685
1012
  buffer: device.createVertexBuffer('position_f32x2', new Float32Array([
@@ -696,18 +1023,102 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
696
1023
  ]
697
1024
  });
698
1025
  }
699
- if (!this._primitiveSky) {
700
- this._primitiveSky = new BoxShape({
1026
+ if (!SkyRenderer._primitiveSky) {
1027
+ SkyRenderer._primitiveSky = new BoxShape({
701
1028
  size: 8
702
1029
  });
703
1030
  }
1031
+ if (!SkyRenderer._primitiveDistantLight) {
1032
+ const data = new Float32Array(uniformSphereSamples.length * 3);
1033
+ let i = 0;
1034
+ for (const v of uniformSphereSamples){
1035
+ data[i++] = v.x;
1036
+ data[i++] = v.y;
1037
+ data[i++] = v.z;
1038
+ }
1039
+ SkyRenderer._primitiveDistantLight = new Primitive();
1040
+ SkyRenderer._primitiveDistantLight.createAndSetVertexBuffer('position_f32x3', data);
1041
+ SkyRenderer._primitiveDistantLight.indexCount = uniformSphereSamples.length;
1042
+ SkyRenderer._primitiveDistantLight.indexStart = 0;
1043
+ SkyRenderer._primitiveDistantLight.primitiveType = 'point-list';
1044
+ }
1045
+ }
1046
+ /** @internal */ static _createFogProgram(device, noDepth) {
1047
+ const program = device.buildRenderProgram({
1048
+ label: 'Fog',
1049
+ vertex (pb) {
1050
+ this.rt = pb.int().uniform(0);
1051
+ this.$inputs.pos = pb.vec2().attrib('position');
1052
+ this.$outputs.uv = pb.vec2();
1053
+ pb.main(function() {
1054
+ this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
1055
+ this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
1056
+ if (device.type === 'webgpu') {
1057
+ this.$if(pb.notEqual(this.rt, 0), function() {
1058
+ this.$builtins.position.y = pb.neg(this.$builtins.position.y);
1059
+ });
1060
+ }
1061
+ });
1062
+ },
1063
+ fragment (pb) {
1064
+ const AtmosphereParams = getAtmosphereParamsStruct(pb);
1065
+ const HeightFogParams = getHeightFogParamsStruct(pb);
1066
+ if (!noDepth) {
1067
+ this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
1068
+ }
1069
+ this.apLut = pb.tex2D().uniform(0);
1070
+ this.skyDistantLightLut = pb.tex2D().uniform(0);
1071
+ this.invProjViewMatrix = pb.mat4().uniform(0);
1072
+ this.cameraNearFar = pb.vec2().uniform(0);
1073
+ this.cameraPosition = pb.vec3().uniform(0);
1074
+ this.withAerialPerspective = pb.int().uniform(0);
1075
+ this.fogType = pb.int().uniform(0);
1076
+ this.atmosphereParams = AtmosphereParams().uniform(0);
1077
+ this.heightFogParams = HeightFogParams().uniform(0);
1078
+ this.srgbOut = pb.int().uniform(0);
1079
+ this.$outputs.outColor = pb.vec4();
1080
+ pb.main(function() {
1081
+ this.$l.depthValue = noDepth ? pb.float(1) : pb.textureSample(this.depthTex, this.$inputs.uv).r;
1082
+ this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), pb.sub(pb.mul(this.depthValue, 2), 1), 1);
1083
+ this.$l.hPos = pb.mul(this.invProjViewMatrix, this.clipSpacePos);
1084
+ this.$l.worldPos = pb.div(this.$l.hPos, this.$l.hPos.w).xyz;
1085
+ this.$l.isSky = pb.equal(this.$l.depthValue, 1);
1086
+ this.$l.color = calculateFog(this, this.withAerialPerspective, this.fogType, this.atmosphereParams, this.heightFogParams, this.$inputs.uv, this.isSky, this.cameraPosition, this.worldPos, 0, this.apLut, this.skyDistantLightLut);
1087
+ this.$if(pb.equal(this.srgbOut, 0), function() {
1088
+ this.$outputs.outColor = this.color;
1089
+ }).$else(function() {
1090
+ this.$outputs.outColor = pb.vec4(linearToGamma(this, this.color.rgb), this.color.a);
1091
+ });
1092
+ });
1093
+ }
1094
+ });
1095
+ program.name = noDepth ? '@FogNoDepth' : '@Fog';
1096
+ return program;
704
1097
  }
705
1098
  /** @internal */ static _getSunDir(sunLight) {
706
1099
  // TODO: reduce GC
707
1100
  return sunLight?.directionAndCutoff.xyz().scaleBy(-1) ?? ShaderHelper.defaultSunDir;
708
1101
  }
1102
+ /** @internal */ static _getSunColor(sunLight) {
1103
+ // TODO: reduce GC
1104
+ return sunLight?.diffuseAndIntensity ?? new Vector4(1, 1, 1, 10);
1105
+ }
1106
+ static _createAtmosphereLUTPrograms(device) {
1107
+ if (!this.transmittanceLutProgram) {
1108
+ this.transmittanceLutProgram = createTransmittanceLutProgram(device);
1109
+ }
1110
+ if (!this.multiScatteringLutProgram) {
1111
+ this.multiScatteringLutProgram = createMultiScatteringLutProgram(device);
1112
+ }
1113
+ if (!this.skyViewLutProgram) {
1114
+ this.skyViewLutProgram = createSkyViewLutProgram(device);
1115
+ }
1116
+ if (!this.APLutProgram) {
1117
+ this.APLutProgram = createAPLutProgram(device);
1118
+ }
1119
+ }
709
1120
  static _createScatterProgram(device, cloud) {
710
- return device.buildRenderProgram({
1121
+ const program = device.buildRenderProgram({
711
1122
  vertex (pb) {
712
1123
  this.$inputs.pos = pb.vec3().attrib('position');
713
1124
  this.worldMatrix = pb.mat4().uniform(0);
@@ -724,26 +1135,14 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
724
1135
  this.$outputs.outColor = pb.vec4();
725
1136
  this.tLut = pb.tex2D().uniform(0);
726
1137
  this.skyLut = pb.tex2D().uniform(0);
727
- this.sunDir = pb.vec3().uniform(0);
1138
+ this.params = getAtmosphereParamsStruct(pb)().uniform(0);
728
1139
  if (cloud) {
729
1140
  this.cloudy = pb.float().uniform(0);
730
1141
  this.cloudIntensity = pb.float().uniform(0);
731
1142
  this.time = pb.float().uniform(0);
732
1143
  this.velocity = pb.vec2().uniform(0);
733
1144
  }
734
- this.drawGround = pb.int().uniform(0);
735
1145
  this.srgbOut = pb.int().uniform(0);
736
- this.viewPos = pb.vec3(ScatteringLut.viewPosition.x, ScatteringLut.viewPosition.y, ScatteringLut.viewPosition.z);
737
- pb.func('getMiePhase', [
738
- pb.float('cosTheta')
739
- ], function() {
740
- this.$l.g = pb.float(0.8);
741
- this.$l.scale = pb.float(3 / (Math.PI * 8));
742
- this.$l.gg = pb.mul(this.g, this.g);
743
- this.$l.num = pb.mul(pb.sub(1, this.gg), pb.add(pb.mul(this.cosTheta, this.cosTheta), 1));
744
- this.$l.denom = pb.mul(pb.add(2, this.gg), pb.pow(pb.sub(pb.add(1, this.gg), pb.mul(this.g, this.cosTheta, 2)), 1.5));
745
- this.$return(pb.div(pb.mul(this.scale, this.num), this.denom));
746
- });
747
1146
  pb.func('noise', [
748
1147
  pb.vec3('p'),
749
1148
  pb.float('t')
@@ -764,77 +1163,12 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
764
1163
  this.f = pb.add(this.f, pb.mul(smoothNoise3D(this, this.p2), 0.015625));
765
1164
  this.$return(this.f);
766
1165
  });
767
- pb.func('getValFromSkyLUT', [
768
- pb.vec3('rayDir'),
769
- pb.vec3('sunDir')
770
- ], function() {
771
- this.$l.height = pb.length(this.viewPos);
772
- this.$l.up = pb.div(this.viewPos, this.height);
773
- this.$l.c = pb.div(pb.sqrt(pb.sub(pb.mul(this.height, this.height), pb.mul(ScatteringLut.groundRadius, ScatteringLut.groundRadius))), this.height);
774
- this.$l.horizonAngle = pb.acos(pb.clamp(this.c, -1, 1));
775
- this.$l.altitudeAngle = pb.sub(this.horizonAngle, pb.acos(pb.dot(this.rayDir, this.up)));
776
- this.$l.azimuthAngle = pb.float();
777
- this.$if(pb.greaterThan(pb.abs(this.altitudeAngle), Math.PI * 0.5 - 0.0001), function() {
778
- this.azimuthAngle = 0;
779
- }).$else(function() {
780
- this.$l.right = pb.cross(this.sunDir, this.up);
781
- this.$l.forward = pb.cross(this.up, this.right);
782
- this.$l.projectedDir = pb.normalize(pb.sub(this.rayDir, pb.mul(this.up, pb.dot(this.rayDir, this.up))));
783
- this.$l.sinTheta = pb.dot(this.projectedDir, this.right);
784
- this.$l.cosTheta = pb.dot(this.projectedDir, this.forward);
785
- this.azimuthAngle = pb.add(pb.atan2(this.sinTheta, this.cosTheta), Math.PI);
786
- });
787
- this.$l.v = pb.add(0.5, pb.mul(0.5, pb.sign(this.altitudeAngle), pb.sqrt(pb.mul(pb.abs(this.altitudeAngle), 2 / Math.PI))));
788
- this.$l.uv = pb.vec2(pb.div(this.azimuthAngle, Math.PI * 2), this.v);
789
- this.$return(pb.textureSampleLevel(this.skyLut, this.uv, 0).rgb);
790
- });
791
- pb.func('sunWithBloom', [
792
- pb.vec3('rayDir'),
793
- pb.vec3('sunDir')
794
- ], function() {
795
- this.$l.sunSolidAngle = 0.53 * Math.PI / 180;
796
- this.$l.minSunCosTheta = pb.cos(this.sunSolidAngle);
797
- this.$l.cosTheta = pb.dot(this.rayDir, this.sunDir);
798
- this.$if(pb.greaterThanEqual(this.cosTheta, this.minSunCosTheta), function() {
799
- this.$return(pb.vec3(1));
800
- });
801
- this.$l.offset = pb.sub(this.minSunCosTheta, this.cosTheta);
802
- this.$l.gaussianBloom = pb.mul(pb.exp(pb.mul(this.offset, -50000)), 0.5);
803
- this.$l.invBloom = pb.mul(pb.div(1, pb.add(0.02, pb.mul(this.offset, 300))), 0.01);
804
- this.$return(pb.vec3(pb.add(this.gaussianBloom, this.invBloom)));
805
- });
806
- pb.func('rayIntersectSphere', [
807
- pb.vec3('ro'),
808
- pb.vec3('rd'),
809
- pb.float('rad')
810
- ], function() {
811
- this.$l.b = pb.dot(this.ro, this.rd);
812
- this.$l.c = pb.sub(pb.dot(this.ro, this.ro), pb.mul(this.rad, this.rad));
813
- this.$if(pb.and(pb.greaterThan(this.c, 0), pb.greaterThan(this.b, 0)), function() {
814
- this.$return(pb.float(-1));
815
- });
816
- this.$l.bb = pb.mul(this.b, this.b);
817
- this.$l.discr = pb.sub(this.bb, this.c);
818
- this.$if(pb.lessThan(this.discr, 0), function() {
819
- this.$return(pb.float(-1));
820
- });
821
- this.$if(pb.greaterThan(this.discr, this.bb), function() {
822
- this.$return(pb.sub(pb.sqrt(this.discr), this.b));
823
- });
824
- this.$return(pb.sub(pb.neg(pb.sqrt(this.discr)), this.b));
825
- });
826
- pb.func('getValFromTLUT', [
827
- pb.vec3('pos'),
828
- pb.vec3('sunDir')
829
- ], function() {
830
- this.$l.height = pb.length(this.pos);
831
- this.$l.up = pb.div(this.pos, this.height);
832
- this.$l.sunCosZenithAngle = pb.dot(this.sunDir, this.up);
833
- this.$l.uv = pb.vec2(pb.clamp(pb.add(0.5, pb.mul(this.sunCosZenithAngle, 0.5)), 0, 1), pb.max(0, pb.min(1, pb.div(pb.sub(this.height, ScatteringLut.groundRadius), pb.sub(ScatteringLut.atmosphereRadius, ScatteringLut.groundRadius)))));
834
- this.$return(pb.textureSampleLevel(this.tLut, this.uv, 0).rgb);
835
- });
836
1166
  pb.main(function() {
1167
+ // Calculate sky color
1168
+ this.$l.sunColor = pb.vec4();
1169
+ this.$l.skyColor = skyBox(this, this.params, this.sunColor, this.$inputs.worldDirection, pb.float(0.01), this.tLut, this.skyLut).rgb;
837
1170
  this.$l.rayDir = pb.normalize(this.$inputs.worldDirection);
1171
+ this.$l.sunDir = this.params.lightDir;
838
1172
  // ad-hoc
839
1173
  this.$l.sunIntensity = pb.sqrt(pb.max(0, pb.mul(this.sunDir.y, this.rayDir.y)));
840
1174
  // compute cloud
@@ -852,33 +1186,22 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
852
1186
  this.noiseValue = pb.smoothStep(1, pb.add(1, this.cloudy), this.noiseValue);
853
1187
  });
854
1188
  // use sun color as cloud color
855
- this.$l.sunColor = pb.mul(this.getValFromSkyLUT(this.sunDir, this.sunDir), this.sunIntensity);
856
- this.$l.cloudColor = pb.mul(this.sunColor.rgb, pb.mul(this.noiseValue, this.cloudIntensity));
1189
+ /*
1190
+ this.$l.sunColor = pb.mul(
1191
+ pb.textureSampleLevel(this.skyLut, viewDirToUV(this, this.sunDir), 0),
1192
+ this.sunIntensity
1193
+ );
1194
+ */ this.$l.cloudColor = pb.mul(this.sunColor.rgb, this.sunIntensity, pb.mul(this.noiseValue, this.cloudIntensity));
857
1195
  }
858
1196
  // Compute sky color
859
- this.$l.skyRayDir = this.$choice(pb.equal(this.drawGround, 0), pb.normalize(pb.vec3(this.rayDir.x, pb.max(0, this.rayDir.y), this.rayDir.z)), this.rayDir);
860
- this.$l.lum = this.getValFromSkyLUT(this.skyRayDir, this.sunDir);
861
- this.$l.sunLum = this.sunWithBloom(this.rayDir, this.sunDir);
862
- this.sunLum = pb.smoothStep(pb.vec3(0.002), pb.vec3(1), this.sunLum);
863
- this.$if(pb.greaterThan(pb.length(this.sunLum), 0), function() {
864
- this.$if(pb.greaterThanEqual(this.rayIntersectSphere(this.viewPos, this.rayDir, ScatteringLut.groundRadius), 0), function() {
865
- this.sunLum = pb.vec3(0);
866
- }).$else(function() {
867
- this.sunLum = pb.mul(this.sunLum, this.getValFromTLUT(this.viewPos, this.sunDir));
868
- });
869
- });
870
1197
  if (cloud) {
871
- this.lum = pb.add(this.lum, this.sunLum);
872
1198
  // blend
873
1199
  this.$l.vfactor = pb.clamp(pb.div(pb.sub(this.rayDir.y, 0.01), pb.sub(0.03, 0.01)), 0, 1);
874
1200
  this.$l.factor = pb.clamp(pb.mul(this.noiseValue, this.vfactor), 0, 1);
875
- this.$l.color = pb.mix(this.lum, this.cloudColor, this.factor);
1201
+ this.$l.color = pb.mix(this.skyColor, this.cloudColor, this.factor);
876
1202
  } else {
877
- this.$l.color = this.lum;
1203
+ this.$l.color = this.skyColor;
878
1204
  }
879
- this.color = pb.mul(this.color, 8);
880
- this.color = pb.pow(this.color, pb.vec3(1.3));
881
- this.color = pb.div(this.color, pb.add(pb.mul(pb.smoothStep(0, 0.2, pb.clamp(this.sunDir.y, 0, 1)), 2), 0.15));
882
1205
  this.$if(pb.equal(this.srgbOut, 0), function() {
883
1206
  this.$outputs.outColor = pb.vec4(this.color, 1);
884
1207
  }).$else(function() {
@@ -887,6 +1210,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
887
1210
  });
888
1211
  }
889
1212
  });
1213
+ program.name = cloud ? '@SkyScatterCloud' : '@SkyScatter';
1214
+ return program;
890
1215
  }
891
1216
  }
892
1217