@zephyr3d/scene 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/dist/animation/animation.js +173 -0
  2. package/dist/animation/animation.js.map +1 -0
  3. package/dist/animation/animationset.js +95 -0
  4. package/dist/animation/animationset.js.map +1 -0
  5. package/dist/animation/animationtrack.js +38 -0
  6. package/dist/animation/animationtrack.js.map +1 -0
  7. package/dist/animation/eulerrotationtrack.js +33 -0
  8. package/dist/animation/eulerrotationtrack.js.map +1 -0
  9. package/dist/animation/rotationtrack.js +37 -0
  10. package/dist/animation/rotationtrack.js.map +1 -0
  11. package/dist/animation/scaletrack.js +36 -0
  12. package/dist/animation/scaletrack.js.map +1 -0
  13. package/dist/animation/skeleton.js +97 -0
  14. package/dist/animation/skeleton.js.map +1 -0
  15. package/dist/animation/translationtrack.js +36 -0
  16. package/dist/animation/translationtrack.js.map +1 -0
  17. package/dist/animation/usertrack.js +47 -0
  18. package/dist/animation/usertrack.js.map +1 -0
  19. package/dist/app.js +173 -0
  20. package/dist/app.js.map +1 -0
  21. package/dist/asset/assetmanager.js +476 -0
  22. package/dist/asset/assetmanager.js.map +1 -0
  23. package/dist/asset/builtin.js +373 -0
  24. package/dist/asset/builtin.js.map +1 -0
  25. package/dist/asset/loaders/dds/dds.js +472 -0
  26. package/dist/asset/loaders/dds/dds.js.map +1 -0
  27. package/dist/asset/loaders/dds/dds_loader.js +38 -0
  28. package/dist/asset/loaders/dds/dds_loader.js.map +1 -0
  29. package/dist/asset/loaders/gltf/gltf_loader.js +981 -0
  30. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -0
  31. package/dist/asset/loaders/gltf/helpers.js +314 -0
  32. package/dist/asset/loaders/gltf/helpers.js.map +1 -0
  33. package/dist/asset/loaders/hdr/hdr.js +175 -0
  34. package/dist/asset/loaders/hdr/hdr.js.map +1 -0
  35. package/dist/asset/loaders/image/tga_Loader.js +117 -0
  36. package/dist/asset/loaders/image/tga_Loader.js.map +1 -0
  37. package/dist/asset/loaders/image/webimage_loader.js +50 -0
  38. package/dist/asset/loaders/image/webimage_loader.js.map +1 -0
  39. package/dist/asset/loaders/loader.js +45 -0
  40. package/dist/asset/loaders/loader.js.map +1 -0
  41. package/dist/asset/model.js +264 -0
  42. package/dist/asset/model.js.map +1 -0
  43. package/dist/blitter/blitter.js +389 -0
  44. package/dist/blitter/blitter.js.map +1 -0
  45. package/dist/blitter/box.js +118 -0
  46. package/dist/blitter/box.js.map +1 -0
  47. package/dist/blitter/copy.js +22 -0
  48. package/dist/blitter/copy.js.map +1 -0
  49. package/dist/blitter/depthlimitedgaussion.js +166 -0
  50. package/dist/blitter/depthlimitedgaussion.js.map +1 -0
  51. package/dist/blitter/gaussianblur.js +229 -0
  52. package/dist/blitter/gaussianblur.js.map +1 -0
  53. package/dist/camera/base.js +90 -0
  54. package/dist/camera/base.js.map +1 -0
  55. package/dist/camera/camera.js +358 -0
  56. package/dist/camera/camera.js.map +1 -0
  57. package/dist/camera/fps.js +246 -0
  58. package/dist/camera/fps.js.map +1 -0
  59. package/dist/camera/orbit.js +157 -0
  60. package/dist/camera/orbit.js.map +1 -0
  61. package/dist/camera/orthocamera.js +126 -0
  62. package/dist/camera/orthocamera.js.map +1 -0
  63. package/dist/camera/perspectivecamera.js +133 -0
  64. package/dist/camera/perspectivecamera.js.map +1 -0
  65. package/dist/index.d.ts +8402 -0
  66. package/dist/index.js +87 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/input/inputmgr.js +242 -0
  69. package/dist/input/inputmgr.js.map +1 -0
  70. package/dist/material/blinn.js +75 -0
  71. package/dist/material/blinn.js.map +1 -0
  72. package/dist/material/grassmaterial.js +221 -0
  73. package/dist/material/grassmaterial.js.map +1 -0
  74. package/dist/material/lambert.js +52 -0
  75. package/dist/material/lambert.js.map +1 -0
  76. package/dist/material/lightmodel.js +2074 -0
  77. package/dist/material/lightmodel.js.map +1 -0
  78. package/dist/material/lit.js +578 -0
  79. package/dist/material/lit.js.map +1 -0
  80. package/dist/material/material.js +458 -0
  81. package/dist/material/material.js.map +1 -0
  82. package/dist/material/meshmaterial.js +311 -0
  83. package/dist/material/meshmaterial.js.map +1 -0
  84. package/dist/material/mixins/albedocolor.js +130 -0
  85. package/dist/material/mixins/albedocolor.js.map +1 -0
  86. package/dist/material/mixins/texture.js +110 -0
  87. package/dist/material/mixins/texture.js.map +1 -0
  88. package/dist/material/mixins/vertexcolor.js +45 -0
  89. package/dist/material/mixins/vertexcolor.js.map +1 -0
  90. package/dist/material/pbr.js +27 -0
  91. package/dist/material/pbr.js.map +1 -0
  92. package/dist/material/standard.js +282 -0
  93. package/dist/material/standard.js.map +1 -0
  94. package/dist/material/terrainlightmodel.js +259 -0
  95. package/dist/material/terrainlightmodel.js.map +1 -0
  96. package/dist/material/terrainmaterial.js +139 -0
  97. package/dist/material/terrainmaterial.js.map +1 -0
  98. package/dist/material/unlit.js +29 -0
  99. package/dist/material/unlit.js.map +1 -0
  100. package/dist/posteffect/bloom.js +398 -0
  101. package/dist/posteffect/bloom.js.map +1 -0
  102. package/dist/posteffect/compositor.js +264 -0
  103. package/dist/posteffect/compositor.js.map +1 -0
  104. package/dist/posteffect/fxaa.js +291 -0
  105. package/dist/posteffect/fxaa.js.map +1 -0
  106. package/dist/posteffect/grayscale.js +87 -0
  107. package/dist/posteffect/grayscale.js.map +1 -0
  108. package/dist/posteffect/posteffect.js +165 -0
  109. package/dist/posteffect/posteffect.js.map +1 -0
  110. package/dist/posteffect/sao.js +327 -0
  111. package/dist/posteffect/sao.js.map +1 -0
  112. package/dist/posteffect/tonemap.js +112 -0
  113. package/dist/posteffect/tonemap.js.map +1 -0
  114. package/dist/posteffect/water.js +535 -0
  115. package/dist/posteffect/water.js.map +1 -0
  116. package/dist/render/clipmap.js +462 -0
  117. package/dist/render/clipmap.js.map +1 -0
  118. package/dist/render/cluster_light.js +329 -0
  119. package/dist/render/cluster_light.js.map +1 -0
  120. package/dist/render/cull_visitor.js +124 -0
  121. package/dist/render/cull_visitor.js.map +1 -0
  122. package/dist/render/depth_pass.js +47 -0
  123. package/dist/render/depth_pass.js.map +1 -0
  124. package/dist/render/envlight.js +282 -0
  125. package/dist/render/envlight.js.map +1 -0
  126. package/dist/render/forward.js +186 -0
  127. package/dist/render/forward.js.map +1 -0
  128. package/dist/render/forward_pass.js +137 -0
  129. package/dist/render/forward_pass.js.map +1 -0
  130. package/dist/render/helper.js +38 -0
  131. package/dist/render/helper.js.map +1 -0
  132. package/dist/render/primitive.js +246 -0
  133. package/dist/render/primitive.js.map +1 -0
  134. package/dist/render/render_queue.js +163 -0
  135. package/dist/render/render_queue.js.map +1 -0
  136. package/dist/render/renderpass.js +151 -0
  137. package/dist/render/renderpass.js.map +1 -0
  138. package/dist/render/renderscheme.js +61 -0
  139. package/dist/render/renderscheme.js.map +1 -0
  140. package/dist/render/scatteringlut.js +634 -0
  141. package/dist/render/scatteringlut.js.map +1 -0
  142. package/dist/render/shadowmap_pass.js +70 -0
  143. package/dist/render/shadowmap_pass.js.map +1 -0
  144. package/dist/render/sky.js +881 -0
  145. package/dist/render/sky.js.map +1 -0
  146. package/dist/render/temporalcache.js +222 -0
  147. package/dist/render/temporalcache.js.map +1 -0
  148. package/dist/render/watermesh.js +835 -0
  149. package/dist/render/watermesh.js.map +1 -0
  150. package/dist/scene/environment.js +146 -0
  151. package/dist/scene/environment.js.map +1 -0
  152. package/dist/scene/graph_node.js +69 -0
  153. package/dist/scene/graph_node.js.map +1 -0
  154. package/dist/scene/light.js +436 -0
  155. package/dist/scene/light.js.map +1 -0
  156. package/dist/scene/mesh.js +215 -0
  157. package/dist/scene/mesh.js.map +1 -0
  158. package/dist/scene/model.js +111 -0
  159. package/dist/scene/model.js.map +1 -0
  160. package/dist/scene/octree.js +651 -0
  161. package/dist/scene/octree.js.map +1 -0
  162. package/dist/scene/octree_update_visitor.js +16 -0
  163. package/dist/scene/octree_update_visitor.js.map +1 -0
  164. package/dist/scene/raycast_visitor.js +72 -0
  165. package/dist/scene/raycast_visitor.js.map +1 -0
  166. package/dist/scene/scene.js +225 -0
  167. package/dist/scene/scene.js.map +1 -0
  168. package/dist/scene/scene_node.js +299 -0
  169. package/dist/scene/scene_node.js.map +1 -0
  170. package/dist/scene/terrain/grass.js +277 -0
  171. package/dist/scene/terrain/grass.js.map +1 -0
  172. package/dist/scene/terrain/heightfield.js +391 -0
  173. package/dist/scene/terrain/heightfield.js.map +1 -0
  174. package/dist/scene/terrain/patch.js +530 -0
  175. package/dist/scene/terrain/patch.js.map +1 -0
  176. package/dist/scene/terrain/quadtree.js +430 -0
  177. package/dist/scene/terrain/quadtree.js.map +1 -0
  178. package/dist/scene/terrain/terrain.js +258 -0
  179. package/dist/scene/terrain/terrain.js.map +1 -0
  180. package/dist/scene/xform.js +224 -0
  181. package/dist/scene/xform.js.map +1 -0
  182. package/dist/shaders/builtins.js +110 -0
  183. package/dist/shaders/builtins.js.map +1 -0
  184. package/dist/shaders/framework.js +709 -0
  185. package/dist/shaders/framework.js.map +1 -0
  186. package/dist/shaders/lighting.js +335 -0
  187. package/dist/shaders/lighting.js.map +1 -0
  188. package/dist/shaders/misc.js +405 -0
  189. package/dist/shaders/misc.js.map +1 -0
  190. package/dist/shaders/noise.js +157 -0
  191. package/dist/shaders/noise.js.map +1 -0
  192. package/dist/shaders/pbr.js +132 -0
  193. package/dist/shaders/pbr.js.map +1 -0
  194. package/dist/shaders/shadow.js +642 -0
  195. package/dist/shaders/shadow.js.map +1 -0
  196. package/dist/shaders/water.js +630 -0
  197. package/dist/shaders/water.js.map +1 -0
  198. package/dist/shadow/esm.js +235 -0
  199. package/dist/shadow/esm.js.map +1 -0
  200. package/dist/shadow/pcf_opt.js +182 -0
  201. package/dist/shadow/pcf_opt.js.map +1 -0
  202. package/dist/shadow/pcf_pd.js +190 -0
  203. package/dist/shadow/pcf_pd.js.map +1 -0
  204. package/dist/shadow/shadow_impl.js +15 -0
  205. package/dist/shadow/shadow_impl.js.map +1 -0
  206. package/dist/shadow/shadowmapper.js +709 -0
  207. package/dist/shadow/shadowmapper.js.map +1 -0
  208. package/dist/shadow/ssm.js +194 -0
  209. package/dist/shadow/ssm.js.map +1 -0
  210. package/dist/shadow/vsm.js +298 -0
  211. package/dist/shadow/vsm.js.map +1 -0
  212. package/dist/shapes/box.js +313 -0
  213. package/dist/shapes/box.js.map +1 -0
  214. package/dist/shapes/cylinder.js +74 -0
  215. package/dist/shapes/cylinder.js.map +1 -0
  216. package/dist/shapes/plane.js +48 -0
  217. package/dist/shapes/plane.js.map +1 -0
  218. package/dist/shapes/shape.js +33 -0
  219. package/dist/shapes/shape.js.map +1 -0
  220. package/dist/shapes/sphere.js +91 -0
  221. package/dist/shapes/sphere.js.map +1 -0
  222. package/dist/shapes/torus.js +100 -0
  223. package/dist/shapes/torus.js.map +1 -0
  224. package/dist/utility/aabbtree.js +390 -0
  225. package/dist/utility/aabbtree.js.map +1 -0
  226. package/dist/utility/bounding_volume.js +78 -0
  227. package/dist/utility/bounding_volume.js.map +1 -0
  228. package/dist/utility/panorama.js +163 -0
  229. package/dist/utility/panorama.js.map +1 -0
  230. package/dist/utility/pmrem.js +345 -0
  231. package/dist/utility/pmrem.js.map +1 -0
  232. package/dist/utility/shprojection.js +448 -0
  233. package/dist/utility/shprojection.js.map +1 -0
  234. package/dist/values.js +48 -0
  235. package/dist/values.js.map +1 -0
  236. package/package.json +70 -0
@@ -0,0 +1,835 @@
1
+ import { Vector2, Vector4, Vector3, PRNG } from '@zephyr3d/base';
2
+ import { Application } from '../app.js';
3
+ import { Clipmap } from './clipmap.js';
4
+ import { Primitive } from './primitive.js';
5
+ import { createProgramH0, createProgramHk, createProgramFFT2H, createProgramFFT2V, createProgramPostFFT2, createProgramOcean } from '../shaders/water.js';
6
+
7
+ /** @internal */ const defaultBuildParams = {
8
+ cascades: [
9
+ {
10
+ size: 450.0,
11
+ strength: 0.8,
12
+ croppiness: -1.2,
13
+ minWave: 0,
14
+ maxWave: 100
15
+ },
16
+ {
17
+ size: 103.0,
18
+ strength: 0.8,
19
+ croppiness: -1.5,
20
+ minWave: 0,
21
+ maxWave: 100
22
+ },
23
+ {
24
+ size: 13,
25
+ strength: 0.9,
26
+ croppiness: -1.5,
27
+ minWave: 0,
28
+ maxWave: 7
29
+ }
30
+ ],
31
+ resolution: 256,
32
+ wind: new Vector2(2, 2),
33
+ alignment: 0.01,
34
+ foamParams: new Vector2(1, 2),
35
+ randomSeed: 0
36
+ };
37
+ const RENDER_NONE = 0;
38
+ const RENDER_NORMAL = 1;
39
+ const RENDER_TWO_PASS = 2;
40
+ /** @internal */ class WaterMesh {
41
+ static _globals = null;
42
+ _h0BindGroup;
43
+ _hkBindGroup;
44
+ _hkBindGroup2;
45
+ _hkBindGroup4;
46
+ _fft2hBindGroup;
47
+ _fft2hBindGroup2;
48
+ _fft2hBindGroup4;
49
+ _fft2vBindGroup;
50
+ _fft2vBindGroup2;
51
+ _fft2vBindGroup4;
52
+ _postfft2BindGroup;
53
+ _postfft2BindGroup2;
54
+ _postfft2BindGroup4;
55
+ _waterBindGroup;
56
+ _nearestRepeatSampler;
57
+ _linearRepeatSampler;
58
+ _updateRenderStates;
59
+ _waterRenderStates;
60
+ _wireframe;
61
+ _gridScale;
62
+ _level;
63
+ _tileSize;
64
+ _regionMin;
65
+ _regionMax;
66
+ _sizes;
67
+ _croppinesses;
68
+ _params;
69
+ _instanceData;
70
+ _ifftTextures;
71
+ _clipmap;
72
+ _aabbExtents;
73
+ _cascades;
74
+ _paramsChanged;
75
+ _resolutionChanged;
76
+ _textureFormat;
77
+ _h0TextureFormat;
78
+ _dataTextureFormat;
79
+ _renderMode;
80
+ _updateFrameStamp;
81
+ // private _impl: WaterShaderImpl;
82
+ constructor(device, impl){
83
+ const renderTargetFloat32 = device.getDeviceCaps().textureCaps.supportFloatColorBuffer;
84
+ const linearFloat32 = renderTargetFloat32 && device.getDeviceCaps().textureCaps.supportLinearFloatTexture;
85
+ const renderTargetFloat16 = device.getDeviceCaps().textureCaps.supportHalfFloatColorBuffer;
86
+ const maxDrawBuffers = /*device.type !== 'webgl' && */ renderTargetFloat16 ? device.getDeviceCaps().framebufferCaps.maxDrawBuffers : 0;
87
+ const maxSampleBytes = device.getDeviceCaps().framebufferCaps.maxColorAttachmentBytesPerSample;
88
+ if (maxDrawBuffers >= 6 && maxSampleBytes >= 96) {
89
+ this._renderMode = RENDER_NORMAL;
90
+ this._textureFormat = renderTargetFloat32 ? 'rgba32f' : 'rgba16f';
91
+ this._h0TextureFormat = renderTargetFloat32 ? 'rgba32f' : 'rgba16f';
92
+ this._dataTextureFormat = linearFloat32 ? 'rgba32f' : 'rgba16f';
93
+ } else if (maxDrawBuffers >= 6 && maxSampleBytes >= 48) {
94
+ this._renderMode = RENDER_NORMAL;
95
+ this._textureFormat = 'rgba16f';
96
+ this._h0TextureFormat = renderTargetFloat32 ? 'rgba32f' : 'rgba16f';
97
+ this._dataTextureFormat = 'rgba16f';
98
+ } else if (maxDrawBuffers >= 4 && maxSampleBytes >= 64) {
99
+ this._renderMode = RENDER_TWO_PASS;
100
+ this._textureFormat = renderTargetFloat32 ? 'rgba32f' : 'rgba16f';
101
+ this._h0TextureFormat = renderTargetFloat32 ? 'rgba32f' : 'rgba16f';
102
+ this._dataTextureFormat = renderTargetFloat32 && linearFloat32 ? 'rgba32f' : 'rgba16f';
103
+ } else if (maxDrawBuffers >= 4 && maxSampleBytes >= 32) {
104
+ this._renderMode = RENDER_TWO_PASS;
105
+ this._textureFormat = 'rgba16f';
106
+ this._h0TextureFormat = 'rgba16f';
107
+ this._dataTextureFormat = 'rgba16f';
108
+ } else {
109
+ this._renderMode = RENDER_NONE;
110
+ this._textureFormat = null;
111
+ this._h0TextureFormat = null;
112
+ this._dataTextureFormat = null;
113
+ }
114
+ if (this._renderMode !== RENDER_NONE) {
115
+ WaterMesh._globals = WaterMesh._globals ?? {
116
+ programs: {
117
+ h0Program: createProgramH0(),
118
+ hkProgram: this._renderMode === RENDER_NORMAL ? createProgramHk() : null,
119
+ hkProgram2: this._renderMode === RENDER_TWO_PASS ? createProgramHk(2) : null,
120
+ hkProgram4: this._renderMode === RENDER_TWO_PASS ? createProgramHk(4) : null,
121
+ fft2hProgram: this._renderMode === RENDER_NORMAL ? createProgramFFT2H() : null,
122
+ fft2hProgram2: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2H(2) : null,
123
+ fft2hProgram4: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2H(4) : null,
124
+ fft2vProgram: this._renderMode === RENDER_NORMAL ? createProgramFFT2V() : null,
125
+ fft2vProgram2: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2V(2) : null,
126
+ fft2vProgram4: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2V(4) : null,
127
+ postfft2Program: this._renderMode === RENDER_NORMAL ? createProgramPostFFT2() : null,
128
+ postfft2Program2: this._renderMode === RENDER_TWO_PASS ? createProgramPostFFT2(2) : null,
129
+ postfft2Program4: this._renderMode === RENDER_TWO_PASS ? createProgramPostFFT2(4) : null,
130
+ waterProgram: createProgramOcean(impl)
131
+ },
132
+ quad: WaterMesh.createQuad(device),
133
+ noiseTextures: new Map(),
134
+ butterflyTextures: new Map()
135
+ };
136
+ this._params = defaultBuildParams;
137
+ const programs = WaterMesh._globals.programs;
138
+ this._h0BindGroup = device.createBindGroup(programs.h0Program.bindGroupLayouts[0]);
139
+ this._hkBindGroup = programs.hkProgram ? device.createBindGroup(WaterMesh._globals.programs.hkProgram.bindGroupLayouts[0]) : null;
140
+ this._hkBindGroup2 = programs.hkProgram2 ? device.createBindGroup(WaterMesh._globals.programs.hkProgram2.bindGroupLayouts[0]) : null;
141
+ this._hkBindGroup4 = programs.hkProgram4 ? device.createBindGroup(WaterMesh._globals.programs.hkProgram4.bindGroupLayouts[0]) : null;
142
+ this._fft2hBindGroup = programs.fft2hProgram ? device.createBindGroup(WaterMesh._globals.programs.fft2hProgram.bindGroupLayouts[0]) : null;
143
+ this._fft2hBindGroup2 = programs.fft2hProgram2 ? device.createBindGroup(WaterMesh._globals.programs.fft2hProgram2.bindGroupLayouts[0]) : null;
144
+ this._fft2hBindGroup4 = programs.fft2hProgram4 ? device.createBindGroup(WaterMesh._globals.programs.fft2hProgram4.bindGroupLayouts[0]) : null;
145
+ this._fft2vBindGroup = programs.fft2vProgram ? device.createBindGroup(WaterMesh._globals.programs.fft2vProgram.bindGroupLayouts[0]) : null;
146
+ this._fft2vBindGroup2 = programs.fft2vProgram2 ? device.createBindGroup(WaterMesh._globals.programs.fft2vProgram2.bindGroupLayouts[0]) : null;
147
+ this._fft2vBindGroup4 = programs.fft2vProgram4 ? device.createBindGroup(WaterMesh._globals.programs.fft2vProgram4.bindGroupLayouts[0]) : null;
148
+ this._postfft2BindGroup = programs.postfft2Program ? device.createBindGroup(WaterMesh._globals.programs.postfft2Program.bindGroupLayouts[0]) : null;
149
+ this._postfft2BindGroup2 = programs.postfft2Program2 ? device.createBindGroup(WaterMesh._globals.programs.postfft2Program2.bindGroupLayouts[0]) : null;
150
+ this._postfft2BindGroup4 = programs.postfft2Program4 ? device.createBindGroup(WaterMesh._globals.programs.postfft2Program4.bindGroupLayouts[0]) : null;
151
+ this._waterBindGroup = device.createBindGroup(WaterMesh._globals.programs.waterProgram.bindGroupLayouts[0]);
152
+ this._instanceData = null;
153
+ this._ifftTextures = null;
154
+ this._wireframe = false;
155
+ this._gridScale = 1;
156
+ this._level = 0;
157
+ this._regionMin = new Vector2(-99999, -99999);
158
+ this._regionMax = new Vector2(99999, 99999);
159
+ this._sizes = new Vector4();
160
+ this._tileSize = 32;
161
+ this._croppinesses = new Vector4();
162
+ this._cascades = [
163
+ new Vector4(),
164
+ new Vector4(),
165
+ new Vector4(),
166
+ new Vector4()
167
+ ];
168
+ this._nearestRepeatSampler = Application.instance.device.createSampler({
169
+ minFilter: 'nearest',
170
+ magFilter: 'nearest',
171
+ mipFilter: 'none',
172
+ addressU: 'repeat',
173
+ addressV: 'repeat'
174
+ });
175
+ this._linearRepeatSampler = Application.instance.device.createSampler({
176
+ minFilter: 'linear',
177
+ magFilter: 'linear',
178
+ mipFilter: 'none',
179
+ addressU: 'repeat',
180
+ addressV: 'repeat'
181
+ });
182
+ this._updateRenderStates = Application.instance.device.createRenderStateSet();
183
+ this._updateRenderStates.useRasterizerState().setCullMode('none');
184
+ this._updateRenderStates.useDepthState().enableTest(false).enableWrite(false);
185
+ this._waterRenderStates = Application.instance.device.createRenderStateSet();
186
+ this._waterRenderStates.useRasterizerState().setCullMode('none');
187
+ this._waterRenderStates.useDepthState().enableTest(true).enableWrite(true).setCompareFunc('le');
188
+ this._clipmap = new Clipmap(this._tileSize);
189
+ this._aabbExtents = new Vector2();
190
+ this._paramsChanged = true;
191
+ this._resolutionChanged = true;
192
+ this._updateFrameStamp = -1;
193
+ // this._impl = impl;
194
+ }
195
+ }
196
+ get params() {
197
+ return this._params;
198
+ }
199
+ paramsChanged() {
200
+ this._paramsChanged = true;
201
+ }
202
+ /*
203
+ private resolutionChanged() {
204
+ this._resolutionChanged = true;
205
+ this._paramsChanged = true;
206
+ }
207
+ */ get alignment() {
208
+ return this._params.alignment;
209
+ }
210
+ set alignment(val) {
211
+ if (this._params.alignment !== val) {
212
+ this._params.alignment = val;
213
+ this.paramsChanged();
214
+ }
215
+ }
216
+ get wind() {
217
+ return this._params.wind;
218
+ }
219
+ set wind(val) {
220
+ if (val !== this._params.wind && (val.x !== this._params.wind.x || val.y !== this._params.wind.y)) {
221
+ this._params.wind.x = val.x;
222
+ this._params.wind.y = val.y;
223
+ this.paramsChanged();
224
+ }
225
+ }
226
+ get foamWidth() {
227
+ return this._params.foamParams.x;
228
+ }
229
+ set foamWidth(val) {
230
+ this._params.foamParams.x = val;
231
+ }
232
+ get foamContrast() {
233
+ return this._params.foamParams.y;
234
+ }
235
+ set foamContrast(val) {
236
+ this._params.foamParams.y = val;
237
+ }
238
+ getWaveLength(cascade) {
239
+ return this._params.cascades[cascade].size;
240
+ }
241
+ setWaveLength(cascade, size) {
242
+ if (this._params.cascades[cascade].size !== size) {
243
+ this._params.cascades[cascade].size = size;
244
+ this.paramsChanged();
245
+ }
246
+ }
247
+ getWaveStrength(cascade) {
248
+ return this._params.cascades[cascade].strength;
249
+ }
250
+ setWaveStrength(cascade, strength) {
251
+ if (this._params.cascades[cascade].strength !== strength) {
252
+ this._params.cascades[cascade].strength = strength;
253
+ this.paramsChanged();
254
+ }
255
+ }
256
+ getWaveCroppiness(cascade) {
257
+ return this._params.cascades[cascade].croppiness;
258
+ }
259
+ setWaveCroppiness(cascade, croppiness) {
260
+ if (this._params.cascades[cascade].croppiness !== croppiness) {
261
+ this._params.cascades[cascade].croppiness = croppiness;
262
+ this.paramsChanged();
263
+ }
264
+ }
265
+ get bindGroup() {
266
+ return this._waterBindGroup;
267
+ }
268
+ get level() {
269
+ return this._level;
270
+ }
271
+ set level(val) {
272
+ this._level = val;
273
+ }
274
+ get wireframe() {
275
+ return this._wireframe;
276
+ }
277
+ set wireframe(val) {
278
+ this._wireframe = val;
279
+ }
280
+ get gridScale() {
281
+ return this._gridScale;
282
+ }
283
+ set gridScale(val) {
284
+ this._gridScale = val;
285
+ }
286
+ get tileSize() {
287
+ return this._tileSize;
288
+ }
289
+ set tileSize(val) {
290
+ if (val !== this._tileSize) {
291
+ this._tileSize = val;
292
+ if (!this._clipmap) {
293
+ this._clipmap = new Clipmap(this._tileSize);
294
+ } else {
295
+ this._clipmap.tileResolution = this._tileSize;
296
+ }
297
+ }
298
+ }
299
+ get regionMin() {
300
+ return this._regionMin;
301
+ }
302
+ set regionMin(val) {
303
+ this._regionMin.set(val);
304
+ }
305
+ get regionMax() {
306
+ return this._regionMax;
307
+ }
308
+ set regionMax(val) {
309
+ this._regionMax.set(val);
310
+ }
311
+ render(camera, flip) {
312
+ if (this._renderMode === RENDER_NONE) {
313
+ return;
314
+ }
315
+ const device = Application.instance.device;
316
+ device.pushDeviceStates();
317
+ {
318
+ this._updateFrameStamp = device.frameInfo.frameCounter;
319
+ this.update(device, device.frameInfo.elapsedOverall * 0.001);
320
+ }
321
+ device.popDeviceStates();
322
+ const cameraPos = camera.getWorldPosition();
323
+ const instanceData = this.getInstanceData();
324
+ device.setProgram(WaterMesh._globals.programs.waterProgram);
325
+ device.setBindGroup(0, this._waterBindGroup);
326
+ device.setRenderStates(this._waterRenderStates);
327
+ const sampler = this._linearRepeatSampler;
328
+ this._waterBindGroup.setTexture('dx_hy_dz_dxdz0', instanceData.dataTextures[0], sampler);
329
+ this._waterBindGroup.setTexture('sx_sz_dxdx_dzdz0', instanceData.dataTextures[1], sampler);
330
+ this._waterBindGroup.setTexture('dx_hy_dz_dxdz1', instanceData.dataTextures[2], sampler);
331
+ this._waterBindGroup.setTexture('sx_sz_dxdx_dzdz1', instanceData.dataTextures[3], this._linearRepeatSampler);
332
+ this._waterBindGroup.setTexture('dx_hy_dz_dxdz2', instanceData.dataTextures[4], this._linearRepeatSampler);
333
+ this._waterBindGroup.setTexture('sx_sz_dxdx_dzdz2', instanceData.dataTextures[5], this._linearRepeatSampler);
334
+ this._waterBindGroup.setValue('foamParams', this._params.foamParams);
335
+ this._waterBindGroup.setValue('sizes', this._sizes);
336
+ this._waterBindGroup.setValue('regionMin', this._regionMin);
337
+ this._waterBindGroup.setValue('regionMax', this._regionMax);
338
+ this._waterBindGroup.setValue('croppinesses', this._croppinesses);
339
+ this._waterBindGroup.setValue('viewProjMatrix', camera.viewProjectionMatrix);
340
+ this._waterBindGroup.setValue('level', this._level);
341
+ this._waterBindGroup.setValue('pos', cameraPos);
342
+ this._waterBindGroup.setValue('scale', 1);
343
+ this._waterBindGroup.setValue('flip', flip ? 1 : 0);
344
+ const that = this;
345
+ const position = new Vector3(cameraPos.x, cameraPos.z, 0);
346
+ const distX = Math.max(Math.abs(position.x - this._regionMin.x), Math.abs(position.x - this._regionMax.x));
347
+ const distY = Math.max(Math.abs(position.y - this._regionMin.y), Math.abs(position.y - this._regionMax.y));
348
+ const maxDist = Math.min(Math.max(distX, distY), camera.getFarPlane());
349
+ const gridScale = Math.max(0.01, this._gridScale);
350
+ const mipLevels = Math.ceil(Math.log2(maxDist / (this._tileSize * gridScale))) + 1;
351
+ const disturb = Math.max(this.wind.x, this.wind.y, 2);
352
+ this._aabbExtents.setXY(disturb * 2, disturb * 8 + this._level);
353
+ this._clipmap.draw({
354
+ camera,
355
+ position,
356
+ minWorldPos: this._regionMin,
357
+ maxWorldPos: this._regionMax,
358
+ gridScale: gridScale,
359
+ AABBExtents: this._aabbExtents,
360
+ drawPrimitive (prim, modelMatrix, offset, scale, gridScale) {
361
+ that._waterBindGroup.setValue('modelMatrix', modelMatrix);
362
+ that._waterBindGroup.setValue('offset', offset);
363
+ that._waterBindGroup.setValue('scale', scale);
364
+ that._waterBindGroup.setValue('gridScale', gridScale);
365
+ prim.primitiveType = that._wireframe ? 'line-strip' : 'triangle-list';
366
+ prim.draw();
367
+ }
368
+ }, mipLevels);
369
+ }
370
+ update(device, time) {
371
+ device.setRenderStates(this._updateRenderStates);
372
+ if (this._resolutionChanged) {
373
+ this.disposeInstanceData();
374
+ }
375
+ if (this._paramsChanged) {
376
+ this.generateInitialSpectrum();
377
+ }
378
+ this._resolutionChanged = false;
379
+ this._paramsChanged = false;
380
+ for(let i = 0; i < 3; i++){
381
+ this._sizes[i] = this._params.cascades[i].size;
382
+ this._croppinesses[i] = this._params.cascades[i].croppiness;
383
+ }
384
+ if (this._renderMode === RENDER_NORMAL) {
385
+ this.generateSpectrum(time);
386
+ this.ifft2();
387
+ this.postIfft2();
388
+ } else {
389
+ this.generateSpectrumTwoPass(time);
390
+ this.ifft2TwoPass();
391
+ this.postIfft2TwoPass();
392
+ }
393
+ }
394
+ disposeInstanceData() {
395
+ if (this._instanceData) {
396
+ this._instanceData.dataTextures.forEach((tex)=>tex.dispose());
397
+ this._instanceData.dataTextures = null;
398
+ this._instanceData.h0Textures.forEach((tex)=>tex.dispose());
399
+ this._instanceData.h0Textures = null;
400
+ this._instanceData.pingpongTextures.forEach((tex)=>tex.dispose());
401
+ this._instanceData.pingpongTextures = null;
402
+ this._instanceData.spectrumTextures.forEach((tex)=>tex.dispose());
403
+ this._instanceData.spectrumTextures = null;
404
+ this._instanceData.h0Framebuffer.dispose();
405
+ this._instanceData.pingpongFramebuffer?.dispose();
406
+ this._instanceData.pingpongFramebuffer2?.dispose();
407
+ this._instanceData.pingpongFramebuffer4?.dispose();
408
+ this._instanceData.spectrumFramebuffer?.dispose();
409
+ this._instanceData.spectrumFramebuffer2?.dispose();
410
+ this._instanceData.spectrumFramebuffer4?.dispose();
411
+ this._instanceData.postIfft2Framebuffer?.dispose();
412
+ this._instanceData.postIfft2Framebuffer2?.dispose();
413
+ this._instanceData.postIfft2Framebuffer4?.dispose();
414
+ this._instanceData = null;
415
+ }
416
+ }
417
+ generateSpectrum(time) {
418
+ const device = Application.instance.device;
419
+ const instanceData = this.getInstanceData();
420
+ device.setProgram(WaterMesh._globals.programs.hkProgram);
421
+ device.setBindGroup(0, this._hkBindGroup);
422
+ this._hkBindGroup.setValue('resolution', this._params.resolution);
423
+ this._hkBindGroup.setValue('sizes', this._sizes);
424
+ this._hkBindGroup.setTexture('h0Texture0', instanceData.h0Textures[0], this._nearestRepeatSampler);
425
+ this._hkBindGroup.setTexture('h0Texture1', instanceData.h0Textures[1], this._nearestRepeatSampler);
426
+ this._hkBindGroup.setTexture('h0Texture2', instanceData.h0Textures[2], this._nearestRepeatSampler);
427
+ this._hkBindGroup.setValue('t', time);
428
+ if (device.type === 'webgl') {
429
+ this._hkBindGroup.setValue('h0TexSize', new Vector2(instanceData.h0Textures[0].width, instanceData.h0Textures[0].height));
430
+ }
431
+ device.setFramebuffer(instanceData.spectrumFramebuffer);
432
+ WaterMesh._globals.quad.draw();
433
+ }
434
+ generateSpectrumTwoPass(time) {
435
+ const device = Application.instance.device;
436
+ const instanceData = this.getInstanceData();
437
+ device.setProgram(WaterMesh._globals.programs.hkProgram4);
438
+ device.setBindGroup(0, this._hkBindGroup4);
439
+ this._hkBindGroup4.setValue('resolution', this._params.resolution);
440
+ this._hkBindGroup4.setValue('sizes', this._sizes);
441
+ this._hkBindGroup4.setTexture('h0Texture0', instanceData.h0Textures[0], this._nearestRepeatSampler);
442
+ this._hkBindGroup4.setTexture('h0Texture1', instanceData.h0Textures[1], this._nearestRepeatSampler);
443
+ this._hkBindGroup4.setValue('t', time);
444
+ if (device.type === 'webgl') {
445
+ this._hkBindGroup4.setValue('h0TexSize', new Vector2(instanceData.h0Textures[0].width, instanceData.h0Textures[0].height));
446
+ }
447
+ device.setFramebuffer(instanceData.spectrumFramebuffer4);
448
+ WaterMesh._globals.quad.draw();
449
+ device.setProgram(WaterMesh._globals.programs.hkProgram2);
450
+ device.setBindGroup(0, this._hkBindGroup2);
451
+ this._hkBindGroup2.setValue('resolution', this._params.resolution);
452
+ this._hkBindGroup2.setValue('sizes', this._sizes);
453
+ this._hkBindGroup2.setTexture('h0Texture2', instanceData.h0Textures[2], this._nearestRepeatSampler);
454
+ this._hkBindGroup2.setValue('t', time);
455
+ if (device.type === 'webgl') {
456
+ this._hkBindGroup2.setValue('h0TexSize', new Vector2(instanceData.h0Textures[0].width, instanceData.h0Textures[0].height));
457
+ }
458
+ device.setFramebuffer(instanceData.spectrumFramebuffer2);
459
+ WaterMesh._globals.quad.draw();
460
+ }
461
+ ifft2() {
462
+ const device = Application.instance.device;
463
+ const instanceData = this.getInstanceData();
464
+ const phases = Math.log2(this._params.resolution);
465
+ const pingPongTextures = [
466
+ instanceData.spectrumTextures,
467
+ instanceData.pingpongTextures
468
+ ];
469
+ const pingPongFramebuffers = [
470
+ instanceData.pingpongFramebuffer,
471
+ instanceData.spectrumFramebuffer
472
+ ];
473
+ const butterflyTex = this.getButterflyTexture(this._params.resolution);
474
+ // horizontal ifft
475
+ let pingPong = 0;
476
+ device.setProgram(WaterMesh._globals.programs.fft2hProgram);
477
+ device.setBindGroup(0, this._fft2hBindGroup);
478
+ this._fft2hBindGroup.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
479
+ for(let phase = 0; phase < phases; phase++){
480
+ device.setFramebuffer(pingPongFramebuffers[pingPong]);
481
+ this._fft2hBindGroup.setValue('phase', phase);
482
+ this._fft2hBindGroup.setTexture('spectrum0', pingPongTextures[pingPong][0], this._nearestRepeatSampler);
483
+ this._fft2hBindGroup.setTexture('spectrum1', pingPongTextures[pingPong][1], this._nearestRepeatSampler);
484
+ this._fft2hBindGroup.setTexture('spectrum2', pingPongTextures[pingPong][2], this._nearestRepeatSampler);
485
+ this._fft2hBindGroup.setTexture('spectrum3', pingPongTextures[pingPong][3], this._nearestRepeatSampler);
486
+ this._fft2hBindGroup.setTexture('spectrum4', pingPongTextures[pingPong][4], this._nearestRepeatSampler);
487
+ this._fft2hBindGroup.setTexture('spectrum5', pingPongTextures[pingPong][5], this._nearestRepeatSampler);
488
+ if (device.type === 'webgl') {
489
+ this._fft2hBindGroup.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
490
+ }
491
+ WaterMesh._globals.quad.draw();
492
+ pingPong = (pingPong + 1) % 2;
493
+ }
494
+ // vertical ifft
495
+ device.setProgram(WaterMesh._globals.programs.fft2vProgram);
496
+ device.setBindGroup(0, this._fft2vBindGroup);
497
+ this._fft2vBindGroup.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
498
+ for(let phase = 0; phase < phases; phase++){
499
+ device.setFramebuffer(pingPongFramebuffers[pingPong]);
500
+ this._fft2vBindGroup.setValue('phase', phase);
501
+ this._fft2vBindGroup.setTexture('spectrum0', pingPongTextures[pingPong][0], this._nearestRepeatSampler);
502
+ this._fft2vBindGroup.setTexture('spectrum1', pingPongTextures[pingPong][1], this._nearestRepeatSampler);
503
+ this._fft2vBindGroup.setTexture('spectrum2', pingPongTextures[pingPong][2], this._nearestRepeatSampler);
504
+ this._fft2vBindGroup.setTexture('spectrum3', pingPongTextures[pingPong][3], this._nearestRepeatSampler);
505
+ this._fft2vBindGroup.setTexture('spectrum4', pingPongTextures[pingPong][4], this._nearestRepeatSampler);
506
+ this._fft2vBindGroup.setTexture('spectrum5', pingPongTextures[pingPong][5], this._nearestRepeatSampler);
507
+ if (device.type === 'webgl') {
508
+ this._fft2vBindGroup.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
509
+ }
510
+ WaterMesh._globals.quad.draw();
511
+ pingPong = (pingPong + 1) % 2;
512
+ }
513
+ this._ifftTextures = pingPongTextures[pingPong];
514
+ }
515
+ ifft2TwoPass() {
516
+ const device = Application.instance.device;
517
+ const instanceData = this.getInstanceData();
518
+ const phases = Math.log2(this._params.resolution);
519
+ const pingPongTextures = [
520
+ instanceData.spectrumTextures,
521
+ instanceData.pingpongTextures
522
+ ];
523
+ const pingPongFramebuffers4 = [
524
+ instanceData.pingpongFramebuffer4,
525
+ instanceData.spectrumFramebuffer4
526
+ ];
527
+ const pingPongFramebuffers2 = [
528
+ instanceData.pingpongFramebuffer2,
529
+ instanceData.spectrumFramebuffer2
530
+ ];
531
+ const butterflyTex = this.getButterflyTexture(this._params.resolution);
532
+ // horizontal ifft
533
+ let pingPong = 0;
534
+ for(let phase = 0; phase < phases; phase++){
535
+ device.setFramebuffer(pingPongFramebuffers4[pingPong]);
536
+ device.setProgram(WaterMesh._globals.programs.fft2hProgram4);
537
+ device.setBindGroup(0, this._fft2hBindGroup4);
538
+ this._fft2hBindGroup4.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
539
+ this._fft2hBindGroup4.setValue('phase', phase);
540
+ this._fft2hBindGroup4.setTexture('spectrum0', pingPongTextures[pingPong][0], this._nearestRepeatSampler);
541
+ this._fft2hBindGroup4.setTexture('spectrum1', pingPongTextures[pingPong][1], this._nearestRepeatSampler);
542
+ this._fft2hBindGroup4.setTexture('spectrum2', pingPongTextures[pingPong][2], this._nearestRepeatSampler);
543
+ this._fft2hBindGroup4.setTexture('spectrum3', pingPongTextures[pingPong][3], this._nearestRepeatSampler);
544
+ if (device.type === 'webgl') {
545
+ this._fft2hBindGroup4.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
546
+ }
547
+ WaterMesh._globals.quad.draw();
548
+ device.setFramebuffer(pingPongFramebuffers2[pingPong]);
549
+ device.setProgram(WaterMesh._globals.programs.fft2hProgram2);
550
+ device.setBindGroup(0, this._fft2hBindGroup2);
551
+ this._fft2hBindGroup2.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
552
+ this._fft2hBindGroup2.setValue('phase', phase);
553
+ this._fft2hBindGroup2.setTexture('spectrum4', pingPongTextures[pingPong][4], this._nearestRepeatSampler);
554
+ this._fft2hBindGroup2.setTexture('spectrum5', pingPongTextures[pingPong][5], this._nearestRepeatSampler);
555
+ if (device.type === 'webgl') {
556
+ this._fft2hBindGroup2.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
557
+ }
558
+ WaterMesh._globals.quad.draw();
559
+ pingPong = (pingPong + 1) % 2;
560
+ }
561
+ // vertical ifft
562
+ for(let phase = 0; phase < phases; phase++){
563
+ device.setFramebuffer(pingPongFramebuffers4[pingPong]);
564
+ device.setProgram(WaterMesh._globals.programs.fft2vProgram4);
565
+ device.setBindGroup(0, this._fft2vBindGroup4);
566
+ this._fft2vBindGroup4.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
567
+ this._fft2vBindGroup4.setValue('phase', phase);
568
+ this._fft2vBindGroup4.setTexture('spectrum0', pingPongTextures[pingPong][0], this._nearestRepeatSampler);
569
+ this._fft2vBindGroup4.setTexture('spectrum1', pingPongTextures[pingPong][1], this._nearestRepeatSampler);
570
+ this._fft2vBindGroup4.setTexture('spectrum2', pingPongTextures[pingPong][2], this._nearestRepeatSampler);
571
+ this._fft2vBindGroup4.setTexture('spectrum3', pingPongTextures[pingPong][3], this._nearestRepeatSampler);
572
+ if (device.type === 'webgl') {
573
+ this._fft2vBindGroup4.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
574
+ }
575
+ WaterMesh._globals.quad.draw();
576
+ device.setFramebuffer(pingPongFramebuffers2[pingPong]);
577
+ device.setProgram(WaterMesh._globals.programs.fft2vProgram2);
578
+ device.setBindGroup(0, this._fft2vBindGroup2);
579
+ this._fft2vBindGroup2.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
580
+ this._fft2vBindGroup2.setValue('phase', phase);
581
+ this._fft2vBindGroup2.setTexture('spectrum4', pingPongTextures[pingPong][4], this._nearestRepeatSampler);
582
+ this._fft2vBindGroup2.setTexture('spectrum5', pingPongTextures[pingPong][5], this._nearestRepeatSampler);
583
+ if (device.type === 'webgl') {
584
+ this._fft2vBindGroup2.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
585
+ }
586
+ WaterMesh._globals.quad.draw();
587
+ pingPong = (pingPong + 1) % 2;
588
+ }
589
+ this._ifftTextures = pingPongTextures[pingPong];
590
+ }
591
+ postIfft2() {
592
+ const device = Application.instance.device;
593
+ const instanceData = this.getInstanceData();
594
+ device.setFramebuffer(instanceData.postIfft2Framebuffer);
595
+ device.setProgram(WaterMesh._globals.programs.postfft2Program);
596
+ device.setBindGroup(0, this._postfft2BindGroup);
597
+ this._postfft2BindGroup.setValue('N2', this._params.resolution * this._params.resolution);
598
+ this._postfft2BindGroup.setTexture('ifft0', this._ifftTextures[0], this._nearestRepeatSampler);
599
+ this._postfft2BindGroup.setTexture('ifft1', this._ifftTextures[1], this._nearestRepeatSampler);
600
+ this._postfft2BindGroup.setTexture('ifft2', this._ifftTextures[2], this._nearestRepeatSampler);
601
+ this._postfft2BindGroup.setTexture('ifft3', this._ifftTextures[3], this._nearestRepeatSampler);
602
+ this._postfft2BindGroup.setTexture('ifft4', this._ifftTextures[4], this._nearestRepeatSampler);
603
+ this._postfft2BindGroup.setTexture('ifft5', this._ifftTextures[5], this._nearestRepeatSampler);
604
+ if (device.type === 'webgl') {
605
+ this._postfft2BindGroup.setValue('ifftTexSize', new Vector2(this._ifftTextures[0].width, this._ifftTextures[0].height));
606
+ }
607
+ WaterMesh._globals.quad.draw();
608
+ }
609
+ postIfft2TwoPass() {
610
+ const device = Application.instance.device;
611
+ const instanceData = this.getInstanceData();
612
+ device.setFramebuffer(instanceData.postIfft2Framebuffer4);
613
+ device.setProgram(WaterMesh._globals.programs.postfft2Program4);
614
+ device.setBindGroup(0, this._postfft2BindGroup4);
615
+ this._postfft2BindGroup4.setValue('N2', this._params.resolution * this._params.resolution);
616
+ this._postfft2BindGroup4.setTexture('ifft0', this._ifftTextures[0], this._nearestRepeatSampler);
617
+ this._postfft2BindGroup4.setTexture('ifft1', this._ifftTextures[1], this._nearestRepeatSampler);
618
+ this._postfft2BindGroup4.setTexture('ifft2', this._ifftTextures[2], this._nearestRepeatSampler);
619
+ this._postfft2BindGroup4.setTexture('ifft3', this._ifftTextures[3], this._nearestRepeatSampler);
620
+ if (device.type === 'webgl') {
621
+ this._postfft2BindGroup4.setValue('ifftTexSize', new Vector2(this._ifftTextures[0].width, this._ifftTextures[0].height));
622
+ }
623
+ WaterMesh._globals.quad.draw();
624
+ device.setFramebuffer(instanceData.postIfft2Framebuffer2);
625
+ device.setProgram(WaterMesh._globals.programs.postfft2Program2);
626
+ device.setBindGroup(0, this._postfft2BindGroup2);
627
+ this._postfft2BindGroup2.setValue('N2', this._params.resolution * this._params.resolution);
628
+ this._postfft2BindGroup2.setTexture('ifft4', this._ifftTextures[4], this._nearestRepeatSampler);
629
+ this._postfft2BindGroup2.setTexture('ifft5', this._ifftTextures[5], this._nearestRepeatSampler);
630
+ if (device.type === 'webgl') {
631
+ this._postfft2BindGroup2.setValue('ifftTexSize', new Vector2(this._ifftTextures[0].width, this._ifftTextures[0].height));
632
+ }
633
+ WaterMesh._globals.quad.draw();
634
+ }
635
+ createNTextures(device, format, size, num, name, linear) {
636
+ return Array.from({
637
+ length: num
638
+ }).map((val, index)=>{
639
+ const tex = device.createTexture2D(format, size, size, {
640
+ samplerOptions: {
641
+ mipFilter: 'none'
642
+ }
643
+ });
644
+ tex.name = `${name}-${index}`;
645
+ tex.samplerOptions = {
646
+ minFilter: linear ? 'linear' : 'nearest',
647
+ magFilter: linear ? 'linear' : 'nearest',
648
+ mipFilter: 'none',
649
+ addressU: 'repeat',
650
+ addressV: 'repeat'
651
+ };
652
+ return tex;
653
+ });
654
+ }
655
+ getInstanceData() {
656
+ if (!this._instanceData) {
657
+ const device = Application.instance.device;
658
+ const h0Textures = this.createNTextures(device, this._h0TextureFormat, this._params.resolution, 3, 'Water-h0', false);
659
+ const dataTextures = this.createNTextures(device, this._dataTextureFormat, this._params.resolution, 6, 'Water-data', true);
660
+ const spectrumTextures = this.createNTextures(device, this._textureFormat, this._params.resolution, 6, 'Water-spectrum', false);
661
+ const pingpongTextures = this.createNTextures(device, this._textureFormat, this._params.resolution, 6, 'Water-pingpong', false);
662
+ this._instanceData = {
663
+ dataTextures,
664
+ h0Textures: h0Textures,
665
+ pingpongTextures: pingpongTextures,
666
+ spectrumTextures: spectrumTextures,
667
+ h0Framebuffer: device.createFrameBuffer(h0Textures, null),
668
+ spectrumFramebuffer: this._renderMode === RENDER_NORMAL ? device.createFrameBuffer(spectrumTextures, null) : null,
669
+ spectrumFramebuffer2: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(spectrumTextures.slice(4, 6), null) : null,
670
+ spectrumFramebuffer4: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(spectrumTextures.slice(0, 4), null) : null,
671
+ pingpongFramebuffer: device.createFrameBuffer(pingpongTextures, null),
672
+ pingpongFramebuffer2: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(pingpongTextures.slice(4, 6), null) : null,
673
+ pingpongFramebuffer4: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(pingpongTextures.slice(0, 4), null) : null,
674
+ postIfft2Framebuffer: device.createFrameBuffer(dataTextures, null),
675
+ postIfft2Framebuffer2: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(dataTextures.slice(4, 6), null) : null,
676
+ postIfft2Framebuffer4: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(dataTextures.slice(0, 4), null) : null
677
+ };
678
+ }
679
+ return this._instanceData;
680
+ }
681
+ static createQuad(device) {
682
+ const vertexData = new Float32Array([
683
+ -1,
684
+ -1,
685
+ 0,
686
+ 0.0,
687
+ 0.0,
688
+ 1,
689
+ -1,
690
+ 0,
691
+ 1.0,
692
+ 0.0,
693
+ 1,
694
+ 1,
695
+ 0,
696
+ 1.0,
697
+ 1.0,
698
+ -1,
699
+ 1,
700
+ 0,
701
+ 0.0,
702
+ 1.0
703
+ ]);
704
+ const indexData = new Uint32Array([
705
+ 0,
706
+ 1,
707
+ 2,
708
+ 0,
709
+ 2,
710
+ 3
711
+ ]);
712
+ const prim = new Primitive();
713
+ const vb = device.createInterleavedVertexBuffer([
714
+ 'position_f32x3',
715
+ 'tex0_f32x2'
716
+ ], vertexData);
717
+ const ib = device.createIndexBuffer(indexData);
718
+ prim.setVertexBuffer(vb);
719
+ prim.setIndexBuffer(ib);
720
+ prim.primitiveType = 'triangle-list';
721
+ prim.indexStart = 0;
722
+ prim.indexCount = ib.length;
723
+ return prim;
724
+ }
725
+ getButterflyTexture(size) {
726
+ const device = Application.instance.device;
727
+ let tex = WaterMesh._globals.butterflyTextures.get(size);
728
+ if (!tex) {
729
+ tex = device.createTexture2D('rgba32f', Math.log2(size), size, {
730
+ samplerOptions: {
731
+ mipFilter: 'none'
732
+ }
733
+ });
734
+ tex.name = `butterfly${size}`;
735
+ tex.update(this.createButterflyTexture(size), 0, 0, tex.width, tex.height);
736
+ WaterMesh._globals.butterflyTextures.set(size, tex);
737
+ }
738
+ return tex;
739
+ }
740
+ generateInitialSpectrum() {
741
+ const device = Application.instance.device;
742
+ const instanceData = this.getInstanceData();
743
+ device.setFramebuffer(instanceData.h0Framebuffer);
744
+ device.clearFrameBuffer(Vector4.zero(), null, null);
745
+ device.setProgram(WaterMesh._globals.programs.h0Program);
746
+ device.setBindGroup(0, this._h0BindGroup);
747
+ this._h0BindGroup.setTexture('noise', this.getNoiseTexture(this._params.resolution, this._params.randomSeed), this._nearestRepeatSampler);
748
+ this._h0BindGroup.setValue('resolution', this._params.resolution);
749
+ this._h0BindGroup.setValue('wind', this._params.wind);
750
+ this._h0BindGroup.setValue('alignment', this._params.alignment);
751
+ for(let i = 0; i < this._params.cascades.length; i++){
752
+ this._cascades[i].x = this._params.cascades[i].size;
753
+ this._cascades[i].y = this._params.cascades[i].strength * 0.081 / (this._params.cascades[i].size * this._params.cascades[i].size);
754
+ this._cascades[i].z = 2 * Math.PI / this._params.cascades[i].maxWave;
755
+ this._cascades[i].w = 2 * Math.PI / this._params.cascades[i].minWave;
756
+ }
757
+ this._h0BindGroup.setValue('cascade0', this._cascades[0]);
758
+ this._h0BindGroup.setValue('cascade1', this._cascades[1]);
759
+ this._h0BindGroup.setValue('cascade2', this._cascades[2]);
760
+ WaterMesh._globals.quad.draw();
761
+ }
762
+ getNoiseTexture(size, randomSeed) {
763
+ const device = Application.instance.device;
764
+ let tex = WaterMesh._globals.noiseTextures.get(size);
765
+ if (!tex) {
766
+ tex = device.createTexture2D(device.type === 'webgl' ? 'rgba32f' : 'rg32f', size, size, {
767
+ samplerOptions: {
768
+ mipFilter: 'none'
769
+ }
770
+ });
771
+ tex.name = `noiseTex${size}`;
772
+ tex.update(this.getNoise2d(size, randomSeed, device.type === 'webgl'), 0, 0, size, size);
773
+ WaterMesh._globals.noiseTextures.set(size, tex);
774
+ }
775
+ return tex;
776
+ }
777
+ getNoise2d(size, randomSeed, rgba) {
778
+ const rand = new PRNG(randomSeed);
779
+ if (rgba) {
780
+ const array = new Float32Array(size * size * 4);
781
+ for(let i = 0; i < size * size; i++){
782
+ array[i * 4 + 0] = rand.get();
783
+ array[i * 4 + 1] = rand.get();
784
+ }
785
+ return array;
786
+ } else {
787
+ return Float32Array.from([
788
+ ...Array(size * size * 2)
789
+ ].map(()=>rand.get()));
790
+ }
791
+ }
792
+ reverseBits(v, width) {
793
+ return parseInt(v.toString(2).padStart(width, '0').split('').reverse().join(''), 2);
794
+ }
795
+ createButterflyTexture(size) {
796
+ const width = Math.log2(size);
797
+ const height = size;
798
+ const texture = new Float32Array(width * height * 4);
799
+ const w = 2.0 * Math.PI / size;
800
+ const bitReversed = [
801
+ ...Array(size).keys()
802
+ ].map((v)=>this.reverseBits(v, width));
803
+ for(let j = 0; j < width; j++){
804
+ for(let i = 0; i < height; i++){
805
+ const k = i * (size >> j + 1);
806
+ const c = Math.cos(k * w);
807
+ const s = Math.sin(k * w);
808
+ const span = 2 ** j;
809
+ const wing = i % 2 ** (j + 1) < span ? 0 : 1; // 0 - top wing, 1 - bottom wing
810
+ const texel = new Vector4();
811
+ if (j === 0) {
812
+ if (wing === 0) {
813
+ texel.setXYZW(c, s, bitReversed[i], bitReversed[i + 1]);
814
+ } else {
815
+ texel.setXYZW(c, s, bitReversed[i - 1], bitReversed[i]);
816
+ }
817
+ } else {
818
+ if (wing === 0) {
819
+ texel.setXYZW(c, s, i, i + span);
820
+ } else {
821
+ texel.setXYZW(c, s, i - span, i);
822
+ }
823
+ }
824
+ texture[(width * i + j) * 4] = texel[0];
825
+ texture[(width * i + j) * 4 + 1] = texel[1];
826
+ texture[(width * i + j) * 4 + 2] = texel[2];
827
+ texture[(width * i + j) * 4 + 3] = texel[3];
828
+ }
829
+ }
830
+ return texture;
831
+ }
832
+ }
833
+
834
+ export { WaterMesh, defaultBuildParams };
835
+ //# sourceMappingURL=watermesh.js.map