@zephyr3d/scene 0.4.0 → 0.6.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 (233) hide show
  1. package/dist/animation/animation.js +25 -117
  2. package/dist/animation/animation.js.map +1 -1
  3. package/dist/animation/animationset.js +191 -51
  4. package/dist/animation/animationset.js.map +1 -1
  5. package/dist/animation/animationtrack.js +6 -18
  6. package/dist/animation/animationtrack.js.map +1 -1
  7. package/dist/animation/eulerrotationtrack.js +16 -6
  8. package/dist/animation/eulerrotationtrack.js.map +1 -1
  9. package/dist/animation/morphtarget.js +104 -0
  10. package/dist/animation/morphtarget.js.map +1 -0
  11. package/dist/animation/morphtrack.js +70 -0
  12. package/dist/animation/morphtrack.js.map +1 -0
  13. package/dist/animation/rotationtrack.js +15 -7
  14. package/dist/animation/rotationtrack.js.map +1 -1
  15. package/dist/animation/scaletrack.js +15 -7
  16. package/dist/animation/scaletrack.js.map +1 -1
  17. package/dist/animation/skeleton.js +107 -5
  18. package/dist/animation/skeleton.js.map +1 -1
  19. package/dist/animation/translationtrack.js +15 -7
  20. package/dist/animation/translationtrack.js.map +1 -1
  21. package/dist/app.js +4 -26
  22. package/dist/app.js.map +1 -1
  23. package/dist/asset/assetmanager.js +60 -109
  24. package/dist/asset/assetmanager.js.map +1 -1
  25. package/dist/asset/loaders/dds/dds.js +77 -3
  26. package/dist/asset/loaders/dds/dds.js.map +1 -1
  27. package/dist/asset/loaders/dds/dds_loader.js +1 -1
  28. package/dist/asset/loaders/gltf/gltf_loader.js +287 -40
  29. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  30. package/dist/asset/loaders/image/tga_Loader.js +1 -1
  31. package/dist/asset/loaders/image/webimage_loader.js +16 -0
  32. package/dist/asset/loaders/image/webimage_loader.js.map +1 -1
  33. package/dist/asset/model.js +16 -9
  34. package/dist/asset/model.js.map +1 -1
  35. package/dist/blitter/bilateralblur.js +222 -0
  36. package/dist/{render/temporalcache.js.map → blitter/bilateralblur.js.map} +1 -1
  37. package/dist/blitter/blitter.js +9 -3
  38. package/dist/blitter/blitter.js.map +1 -1
  39. package/dist/blitter/depthlimitedgaussion.js +96 -39
  40. package/dist/blitter/depthlimitedgaussion.js.map +1 -1
  41. package/dist/blitter/gaussianblur.js +21 -21
  42. package/dist/camera/camera.js +200 -4
  43. package/dist/camera/camera.js.map +1 -1
  44. package/dist/index.d.ts +6406 -5786
  45. package/dist/index.js +12 -10
  46. package/dist/index.js.map +1 -1
  47. package/dist/material/blinn.js +15 -4
  48. package/dist/material/blinn.js.map +1 -1
  49. package/dist/material/lambert.js +26 -17
  50. package/dist/material/lambert.js.map +1 -1
  51. package/dist/material/material.js +13 -2
  52. package/dist/material/material.js.map +1 -1
  53. package/dist/material/meshmaterial.js +103 -31
  54. package/dist/material/meshmaterial.js.map +1 -1
  55. package/dist/material/mixins/albedocolor.js +5 -4
  56. package/dist/material/mixins/albedocolor.js.map +1 -1
  57. package/dist/material/mixins/lightmodel/blinnphong.js +17 -7
  58. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  59. package/dist/material/mixins/lightmodel/lambert.js +5 -5
  60. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -7
  61. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +16 -7
  63. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  64. package/dist/material/mixins/lit.js +2 -2
  65. package/dist/material/mixins/pbr/common.js +454 -19
  66. package/dist/material/mixins/pbr/common.js.map +1 -1
  67. package/dist/material/pbrmr.js +28 -6
  68. package/dist/material/pbrmr.js.map +1 -1
  69. package/dist/material/pbrsg.js +27 -9
  70. package/dist/material/pbrsg.js.map +1 -1
  71. package/dist/material/shader/helper.js +128 -23
  72. package/dist/material/shader/helper.js.map +1 -1
  73. package/dist/material/unlit.js +8 -4
  74. package/dist/material/unlit.js.map +1 -1
  75. package/dist/posteffect/bloom.js +34 -53
  76. package/dist/posteffect/bloom.js.map +1 -1
  77. package/dist/posteffect/compositor.js +48 -58
  78. package/dist/posteffect/compositor.js.map +1 -1
  79. package/dist/posteffect/fxaa.js +3 -11
  80. package/dist/posteffect/fxaa.js.map +1 -1
  81. package/dist/posteffect/grayscale.js +3 -11
  82. package/dist/posteffect/grayscale.js.map +1 -1
  83. package/dist/posteffect/posteffect.js +4 -0
  84. package/dist/posteffect/posteffect.js.map +1 -1
  85. package/dist/posteffect/sao.js +55 -48
  86. package/dist/posteffect/sao.js.map +1 -1
  87. package/dist/posteffect/ssr.js +536 -0
  88. package/dist/{material/lit.js.map → posteffect/ssr.js.map} +1 -1
  89. package/dist/posteffect/tonemap.js +3 -11
  90. package/dist/posteffect/tonemap.js.map +1 -1
  91. package/dist/posteffect/water.js +306 -340
  92. package/dist/posteffect/water.js.map +1 -1
  93. package/dist/render/abuffer_oit.js +2 -2
  94. package/dist/render/clipmap.js +16 -19
  95. package/dist/render/clipmap.js.map +1 -1
  96. package/dist/render/cull_visitor.js +8 -6
  97. package/dist/render/cull_visitor.js.map +1 -1
  98. package/dist/render/depthpass.js +30 -14
  99. package/dist/render/depthpass.js.map +1 -1
  100. package/dist/render/drawable_mixin.js +70 -22
  101. package/dist/render/drawable_mixin.js.map +1 -1
  102. package/dist/render/envlight.js +169 -33
  103. package/dist/render/envlight.js.map +1 -1
  104. package/dist/render/fft_wavegenerator.js +989 -0
  105. package/dist/{shaders/framework.js.map → render/fft_wavegenerator.js.map} +1 -1
  106. package/dist/render/gerstner_wavegenerator.js +265 -0
  107. package/dist/{material/standard.js.map → render/gerstner_wavegenerator.js.map} +1 -1
  108. package/dist/render/globalbindgroup_allocator.js +2 -1
  109. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  110. package/dist/render/hzb.js +273 -0
  111. package/dist/{material/terrainlightmodel.js.map → render/hzb.js.map} +1 -1
  112. package/dist/render/lightpass.js +68 -28
  113. package/dist/render/lightpass.js.map +1 -1
  114. package/dist/render/objectcolorpass.js +51 -0
  115. package/dist/render/objectcolorpass.js.map +1 -0
  116. package/dist/render/render_queue.js +211 -158
  117. package/dist/render/render_queue.js.map +1 -1
  118. package/dist/render/renderbundle_wrapper.js +79 -0
  119. package/dist/render/renderbundle_wrapper.js.map +1 -1
  120. package/dist/render/renderer.js +151 -35
  121. package/dist/render/renderer.js.map +1 -1
  122. package/dist/render/renderpass.js +27 -20
  123. package/dist/render/renderpass.js.map +1 -1
  124. package/dist/render/shadowmap_pass.js +20 -14
  125. package/dist/render/shadowmap_pass.js.map +1 -1
  126. package/dist/render/sky.js +12 -13
  127. package/dist/render/sky.js.map +1 -1
  128. package/dist/render/watermesh.js +94 -828
  129. package/dist/render/watermesh.js.map +1 -1
  130. package/dist/render/wavegenerator.js +8 -0
  131. package/dist/render/wavegenerator.js.map +1 -0
  132. package/dist/render/weightedblended_oit.js +11 -28
  133. package/dist/render/weightedblended_oit.js.map +1 -1
  134. package/dist/scene/batchgroup.js +60 -14
  135. package/dist/scene/batchgroup.js.map +1 -1
  136. package/dist/scene/environment.js +24 -3
  137. package/dist/scene/environment.js.map +1 -1
  138. package/dist/scene/graph_node.js +0 -14
  139. package/dist/scene/graph_node.js.map +1 -1
  140. package/dist/scene/light.js +5 -5
  141. package/dist/scene/mesh.js +62 -15
  142. package/dist/scene/mesh.js.map +1 -1
  143. package/dist/scene/octree.js +5 -2
  144. package/dist/scene/octree.js.map +1 -1
  145. package/dist/scene/raycast_visitor.js +4 -2
  146. package/dist/scene/raycast_visitor.js.map +1 -1
  147. package/dist/scene/scene.js +6 -9
  148. package/dist/scene/scene.js.map +1 -1
  149. package/dist/scene/scene_node.js +11 -8
  150. package/dist/scene/scene_node.js.map +1 -1
  151. package/dist/scene/terrain/grass.js +10 -2
  152. package/dist/scene/terrain/grass.js.map +1 -1
  153. package/dist/scene/terrain/heightfield.js +135 -53
  154. package/dist/scene/terrain/heightfield.js.map +1 -1
  155. package/dist/scene/terrain/patch.js +10 -2
  156. package/dist/scene/terrain/patch.js.map +1 -1
  157. package/dist/scene/terrain/quadtree.js +2 -2
  158. package/dist/scene/terrain/terrain.js +1 -1
  159. package/dist/scene/xform.js +7 -9
  160. package/dist/scene/xform.js.map +1 -1
  161. package/dist/shaders/misc.js +10 -1
  162. package/dist/shaders/misc.js.map +1 -1
  163. package/dist/shaders/noise.js +81 -16
  164. package/dist/shaders/noise.js.map +1 -1
  165. package/dist/shaders/shadow.js +1 -9
  166. package/dist/shaders/shadow.js.map +1 -1
  167. package/dist/shaders/ssr.js +442 -0
  168. package/dist/{material/terrainmat.js.map → shaders/ssr.js.map} +1 -1
  169. package/dist/shaders/water.js +377 -250
  170. package/dist/shaders/water.js.map +1 -1
  171. package/dist/shadow/esm.js +4 -22
  172. package/dist/shadow/esm.js.map +1 -1
  173. package/dist/shadow/shadowmapper.js +56 -31
  174. package/dist/shadow/shadowmapper.js.map +1 -1
  175. package/dist/shadow/vsm.js +4 -24
  176. package/dist/shadow/vsm.js.map +1 -1
  177. package/dist/shapes/cylinder.js +6 -5
  178. package/dist/shapes/cylinder.js.map +1 -1
  179. package/dist/utility/bounding_volume.js +1 -53
  180. package/dist/utility/bounding_volume.js.map +1 -1
  181. package/dist/utility/draco/decoder.js +116 -0
  182. package/dist/utility/draco/decoder.js.map +1 -0
  183. package/dist/utility/misc.js +93 -0
  184. package/dist/utility/misc.js.map +1 -0
  185. package/dist/utility/shprojection.js +2 -7
  186. package/dist/utility/shprojection.js.map +1 -1
  187. package/dist/utility/textures/ggxlut.js +213 -0
  188. package/dist/utility/textures/ggxlut.js.map +1 -0
  189. package/dist/utility/textures/gradientnoise.js +61 -0
  190. package/dist/utility/textures/gradientnoise.js.map +1 -0
  191. package/dist/utility/textures/randomnoise.js +41 -0
  192. package/dist/utility/textures/randomnoise.js.map +1 -0
  193. package/dist/values.js +25 -1
  194. package/dist/values.js.map +1 -1
  195. package/package.json +5 -8
  196. package/dist/animation/usertrack.js +0 -47
  197. package/dist/animation/usertrack.js.map +0 -1
  198. package/dist/material/grassmat.js +0 -127
  199. package/dist/material/grassmat.js.map +0 -1
  200. package/dist/material/lightmodel.js +0 -2074
  201. package/dist/material/lightmodel.js.map +0 -1
  202. package/dist/material/lit.js +0 -578
  203. package/dist/material/mixins/pbr/metallicroughness.js +0 -126
  204. package/dist/material/mixins/pbr/metallicroughness.js.map +0 -1
  205. package/dist/material/mixins/pbr/specularglossness.js +0 -104
  206. package/dist/material/mixins/pbr/specularglossness.js.map +0 -1
  207. package/dist/material/pbr.js +0 -27
  208. package/dist/material/pbr.js.map +0 -1
  209. package/dist/material/standard.js +0 -282
  210. package/dist/material/terrainlightmodel.js +0 -259
  211. package/dist/material/terrainmat.js +0 -357
  212. package/dist/render/depth_pass.js +0 -47
  213. package/dist/render/depth_pass.js.map +0 -1
  214. package/dist/render/forward.js +0 -186
  215. package/dist/render/forward.js.map +0 -1
  216. package/dist/render/forward_pass.js +0 -137
  217. package/dist/render/forward_pass.js.map +0 -1
  218. package/dist/render/helper.js +0 -38
  219. package/dist/render/helper.js.map +0 -1
  220. package/dist/render/renderscheme.js +0 -61
  221. package/dist/render/renderscheme.js.map +0 -1
  222. package/dist/render/temporalcache.js +0 -222
  223. package/dist/scene/model.js +0 -111
  224. package/dist/scene/model.js.map +0 -1
  225. package/dist/scene/octree_update_visitor.js +0 -20
  226. package/dist/scene/octree_update_visitor.js.map +0 -1
  227. package/dist/shaders/builtins.js +0 -110
  228. package/dist/shaders/builtins.js.map +0 -1
  229. package/dist/shaders/framework.js +0 -723
  230. package/dist/shaders/lighting.js +0 -335
  231. package/dist/shaders/lighting.js.map +0 -1
  232. package/dist/utility/sheenlut.js +0 -196
  233. package/dist/utility/sheenlut.js.map +0 -1
@@ -0,0 +1,989 @@
1
+ import { Vector4, PRNG, Vector2 } from '@zephyr3d/base';
2
+ import { WaveGenerator } from './wavegenerator.js';
3
+ import { Primitive } from './primitive.js';
4
+ import { Application } from '../app.js';
5
+ import '@zephyr3d/device';
6
+ import { createProgramH0, createProgramHk, createProgramFFT2H, createProgramFFT2V, createProgramPostFFT2 } from '../shaders/water.js';
7
+ import { fetchSampler } from '../utility/misc.js';
8
+
9
+ function getDefaultBuildParams() {
10
+ return {
11
+ cascades: [
12
+ {
13
+ size: 400.0,
14
+ strength: 0.4,
15
+ croppiness: -1.5,
16
+ minWave: 0,
17
+ maxWave: 100
18
+ },
19
+ {
20
+ size: 100.0,
21
+ strength: 0.4,
22
+ croppiness: -1.2,
23
+ minWave: 0,
24
+ maxWave: 100
25
+ },
26
+ {
27
+ size: 15,
28
+ strength: 0.2,
29
+ croppiness: -0.5,
30
+ minWave: 0,
31
+ maxWave: 7
32
+ }
33
+ ],
34
+ resolution: 256,
35
+ wind: new Vector2(2, 2),
36
+ alignment: 1,
37
+ foamParams: new Vector2(1.2, 7.2),
38
+ randomSeed: 0
39
+ };
40
+ }
41
+ const RENDER_NONE = 0;
42
+ const RENDER_NORMAL = 1;
43
+ const RENDER_TWO_PASS = 2;
44
+ const THREAD_GROUP_SIZE = 16;
45
+ /**
46
+ * This class generates a 2D ocean field using the Fast Fourier Transform (FFT) algorithm.
47
+ * @public
48
+ */ class FFTWaveGenerator extends WaveGenerator {
49
+ static _globals = null;
50
+ _useComputeShader;
51
+ _h0BindGroup;
52
+ _hkBindGroup;
53
+ _hkBindGroup2;
54
+ _hkBindGroup4;
55
+ _fft2hBindGroup;
56
+ _fft2vBindGroup;
57
+ _fft2hBindGroup2Used;
58
+ _fft2hBindGroup2Free;
59
+ _fft2hBindGroup4Used;
60
+ _fft2hBindGroup4Free;
61
+ _fft2vBindGroup2Used;
62
+ _fft2vBindGroup2Free;
63
+ _fft2vBindGroup4Used;
64
+ _fft2vBindGroup4Free;
65
+ _postfft2BindGroup;
66
+ _postfft2BindGroup2;
67
+ _postfft2BindGroup4;
68
+ _updateRenderStates;
69
+ _sizes;
70
+ _croppinesses;
71
+ _params;
72
+ _instanceData;
73
+ _ifftTextures;
74
+ _cascades;
75
+ _paramsChanged;
76
+ _resolutionChanged;
77
+ _textureFormat;
78
+ _h0TextureFormat;
79
+ _dataTextureFormat;
80
+ _renderMode;
81
+ /**
82
+ * Create a new instance of the FFTWaveGenerator class.
83
+ * @param params - Ocean field build parameters. If not provided, default parameters will be used.
84
+ */ constructor(params){
85
+ super();
86
+ const device = Application.instance.device;
87
+ const renderTargetFloat16 = device.getDeviceCaps().textureCaps.supportHalfFloatColorBuffer;
88
+ const maxDrawBuffers = /*device.type !== 'webgl' && */ renderTargetFloat16 ? device.getDeviceCaps().framebufferCaps.maxDrawBuffers : 0;
89
+ this._textureFormat = 'rgba16f';
90
+ this._h0TextureFormat = 'rgba16f';
91
+ this._dataTextureFormat = 'rgba16f';
92
+ this._useComputeShader = device.type === 'webgpu';
93
+ const maxSampleBytes = device.getDeviceCaps().framebufferCaps.maxColorAttachmentBytesPerSample;
94
+ if (maxDrawBuffers === 0) {
95
+ this._renderMode = RENDER_NONE;
96
+ } else if (this._useComputeShader || maxSampleBytes >= 48) {
97
+ this._renderMode = RENDER_NORMAL;
98
+ } else {
99
+ this._renderMode = RENDER_TWO_PASS;
100
+ }
101
+ if (this._renderMode !== RENDER_NONE) {
102
+ FFTWaveGenerator._globals = FFTWaveGenerator._globals ?? {
103
+ programs: {
104
+ h0Program: createProgramH0(this._useComputeShader, THREAD_GROUP_SIZE, this._h0TextureFormat),
105
+ hkProgram: this._renderMode === RENDER_NORMAL ? createProgramHk(this._useComputeShader, THREAD_GROUP_SIZE, this._dataTextureFormat) : null,
106
+ hkProgram2: this._renderMode === RENDER_TWO_PASS ? createProgramHk(false, 0, null, 2) : null,
107
+ hkProgram4: this._renderMode === RENDER_TWO_PASS ? createProgramHk(false, 0, null, 4) : null,
108
+ fft2hProgram: this._renderMode === RENDER_NORMAL ? createProgramFFT2H(this._useComputeShader, THREAD_GROUP_SIZE, this._dataTextureFormat) : null,
109
+ fft2hProgram2: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2H(false, 0, null, 2) : null,
110
+ fft2hProgram4: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2H(false, 0, null, 4) : null,
111
+ fft2vProgram: this._renderMode === RENDER_NORMAL ? createProgramFFT2V(this._useComputeShader, THREAD_GROUP_SIZE, this._dataTextureFormat) : null,
112
+ fft2vProgram2: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2V(false, 0, null, 2) : null,
113
+ fft2vProgram4: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2V(false, 0, null, 4) : null,
114
+ postfft2Program: this._renderMode === RENDER_NORMAL ? createProgramPostFFT2(this._useComputeShader, THREAD_GROUP_SIZE, this._dataTextureFormat) : null,
115
+ postfft2Program2: this._renderMode === RENDER_TWO_PASS ? createProgramPostFFT2(false, 0, null, 2) : null,
116
+ postfft2Program4: this._renderMode === RENDER_TWO_PASS ? createProgramPostFFT2(false, 0, null, 4) : null
117
+ },
118
+ quad: FFTWaveGenerator.createQuad(device),
119
+ noiseTextures: new Map(),
120
+ butterflyTextures: new Map()
121
+ };
122
+ this._params = params ?? getDefaultBuildParams();
123
+ const programs = FFTWaveGenerator._globals.programs;
124
+ this._h0BindGroup = device.createBindGroup(programs.h0Program.bindGroupLayouts[0]);
125
+ this._hkBindGroup = programs.hkProgram ? device.createBindGroup(FFTWaveGenerator._globals.programs.hkProgram.bindGroupLayouts[0]) : null;
126
+ this._hkBindGroup2 = programs.hkProgram2 ? device.createBindGroup(FFTWaveGenerator._globals.programs.hkProgram2.bindGroupLayouts[0]) : null;
127
+ this._hkBindGroup4 = programs.hkProgram4 ? device.createBindGroup(FFTWaveGenerator._globals.programs.hkProgram4.bindGroupLayouts[0]) : null;
128
+ this._fft2hBindGroup = programs.fft2hProgram ? device.createBindGroup(FFTWaveGenerator._globals.programs.fft2hProgram.bindGroupLayouts[0]) : null;
129
+ this._fft2vBindGroup = programs.fft2vProgram ? device.createBindGroup(FFTWaveGenerator._globals.programs.fft2vProgram.bindGroupLayouts[0]) : null;
130
+ this._fft2hBindGroup2Used = [
131
+ [],
132
+ []
133
+ ];
134
+ this._fft2hBindGroup2Free = [
135
+ [],
136
+ []
137
+ ];
138
+ this._fft2hBindGroup4Used = [
139
+ [],
140
+ []
141
+ ];
142
+ this._fft2hBindGroup4Free = [
143
+ [],
144
+ []
145
+ ];
146
+ this._fft2vBindGroup2Used = [
147
+ [],
148
+ []
149
+ ];
150
+ this._fft2vBindGroup2Free = [
151
+ [],
152
+ []
153
+ ];
154
+ this._fft2vBindGroup4Used = [
155
+ [],
156
+ []
157
+ ];
158
+ this._fft2vBindGroup4Free = [
159
+ [],
160
+ []
161
+ ];
162
+ this._postfft2BindGroup = programs.postfft2Program ? device.createBindGroup(FFTWaveGenerator._globals.programs.postfft2Program.bindGroupLayouts[0]) : null;
163
+ this._postfft2BindGroup2 = programs.postfft2Program2 ? device.createBindGroup(FFTWaveGenerator._globals.programs.postfft2Program2.bindGroupLayouts[0]) : null;
164
+ this._postfft2BindGroup4 = programs.postfft2Program4 ? device.createBindGroup(FFTWaveGenerator._globals.programs.postfft2Program4.bindGroupLayouts[0]) : null;
165
+ this._instanceData = null;
166
+ this._ifftTextures = null;
167
+ this._sizes = new Vector4();
168
+ this._croppinesses = new Vector4();
169
+ this._cascades = [
170
+ new Vector4(),
171
+ new Vector4(),
172
+ new Vector4(),
173
+ new Vector4()
174
+ ];
175
+ this._updateRenderStates = Application.instance.device.createRenderStateSet();
176
+ this._updateRenderStates.useRasterizerState().setCullMode('none');
177
+ this._updateRenderStates.useDepthState().enableTest(false).enableWrite(false);
178
+ this._paramsChanged = true;
179
+ }
180
+ }
181
+ /*
182
+ get params() {
183
+ return this._params;
184
+ }
185
+ set params(val: OceanFieldBuildParams) {
186
+ if (val && val !== this._params) {
187
+ this._params = val;
188
+ this.paramsChanged();
189
+ }
190
+ }
191
+ */ paramsChanged() {
192
+ this._paramsChanged = true;
193
+ }
194
+ /** Gets the wave alighment */ get alignment() {
195
+ return this._params.alignment;
196
+ }
197
+ set alignment(val) {
198
+ if (this._params.alignment !== val) {
199
+ this._params.alignment = val;
200
+ this.paramsChanged();
201
+ }
202
+ }
203
+ /** Gets the wind vector */ get wind() {
204
+ return this._params.wind;
205
+ }
206
+ set wind(val) {
207
+ if (val !== this._params.wind && (val.x !== this._params.wind.x || val.y !== this._params.wind.y)) {
208
+ this._params.wind.x = val.x;
209
+ this._params.wind.y = val.y;
210
+ this.paramsChanged();
211
+ }
212
+ }
213
+ /** Gets the foam width */ get foamWidth() {
214
+ return this._params.foamParams.x;
215
+ }
216
+ set foamWidth(val) {
217
+ this._params.foamParams.x = val;
218
+ }
219
+ /** Gets the foam contrast */ get foamContrast() {
220
+ return this._params.foamParams.y;
221
+ }
222
+ set foamContrast(val) {
223
+ this._params.foamParams.y = val;
224
+ }
225
+ /** Gets the wave length for the specified cascade */ getWaveLength(cascade) {
226
+ return this._params.cascades[cascade].size;
227
+ }
228
+ /**
229
+ * Sets the wave length for the specified cascade
230
+ * @param cascade - The cascade index
231
+ * @param length - The new wave length for the specified cascade
232
+ */ setWaveLength(cascade, length) {
233
+ if (this._params.cascades[cascade].size !== length) {
234
+ this._params.cascades[cascade].size = length;
235
+ this.paramsChanged();
236
+ }
237
+ }
238
+ /** Gets the wave strength for the specified cascade */ getWaveStrength(cascade) {
239
+ return this._params.cascades[cascade].strength;
240
+ }
241
+ /**
242
+ * Sets the wave strength for the specified cascade
243
+ * @param cascade - The cascade index
244
+ * @param strength - The new wave strength for the specified cascade
245
+ */ setWaveStrength(cascade, strength) {
246
+ if (this._params.cascades[cascade].strength !== strength) {
247
+ this._params.cascades[cascade].strength = strength;
248
+ this.paramsChanged();
249
+ }
250
+ }
251
+ /** Gets the wave croppiness for the specified cascade */ getWaveCroppiness(cascade) {
252
+ return this._params.cascades[cascade].croppiness;
253
+ }
254
+ /**
255
+ * Sets the wave croppiness for the specified cascade
256
+ * @param cascade - The cascade index
257
+ * @param croppiness - The new wave croppiness for the specified cascade
258
+ */ setWaveCroppiness(cascade, croppiness) {
259
+ if (this._params.cascades[cascade].croppiness !== croppiness) {
260
+ this._params.cascades[cascade].croppiness = croppiness;
261
+ this.paramsChanged();
262
+ }
263
+ }
264
+ /** @internal */ static createQuad(device) {
265
+ const vertexData = new Float32Array([
266
+ -1,
267
+ -1,
268
+ 0,
269
+ 0.0,
270
+ 0.0,
271
+ 1,
272
+ -1,
273
+ 0,
274
+ 1.0,
275
+ 0.0,
276
+ 1,
277
+ 1,
278
+ 0,
279
+ 1.0,
280
+ 1.0,
281
+ -1,
282
+ 1,
283
+ 0,
284
+ 0.0,
285
+ 1.0
286
+ ]);
287
+ const indexData = new Uint32Array([
288
+ 0,
289
+ 1,
290
+ 2,
291
+ 0,
292
+ 2,
293
+ 3
294
+ ]);
295
+ const prim = new Primitive();
296
+ const vb = device.createInterleavedVertexBuffer([
297
+ 'position_f32x3',
298
+ 'tex0_f32x2'
299
+ ], vertexData);
300
+ const ib = device.createIndexBuffer(indexData);
301
+ prim.setVertexBuffer(vb);
302
+ prim.setIndexBuffer(ib);
303
+ prim.primitiveType = 'triangle-list';
304
+ prim.indexStart = 0;
305
+ prim.indexCount = ib.length;
306
+ return prim;
307
+ }
308
+ /** @internal */ getButterflyTexture(size) {
309
+ const device = Application.instance.device;
310
+ let tex = FFTWaveGenerator._globals.butterflyTextures.get(size);
311
+ if (!tex) {
312
+ tex = device.createTexture2D('rgba32f', Math.log2(size), size, {
313
+ samplerOptions: {
314
+ mipFilter: 'none'
315
+ }
316
+ });
317
+ tex.name = `butterfly${size}`;
318
+ tex.update(this.createButterflyTexture(size), 0, 0, tex.width, tex.height);
319
+ FFTWaveGenerator._globals.butterflyTextures.set(size, tex);
320
+ }
321
+ return tex;
322
+ }
323
+ /** @internal */ generateInitialSpectrum() {
324
+ const device = Application.instance.device;
325
+ const instanceData = this.getInstanceData();
326
+ device.setProgram(FFTWaveGenerator._globals.programs.h0Program);
327
+ device.setBindGroup(0, this._h0BindGroup);
328
+ this._h0BindGroup.setTexture('noise', this.getNoiseTexture(this._params.resolution, this._params.randomSeed), fetchSampler('repeat_nearest_nomip'));
329
+ this._h0BindGroup.setValue('resolution', this._params.resolution);
330
+ this._h0BindGroup.setValue('wind', this._params.wind);
331
+ this._h0BindGroup.setValue('alignment', this._params.alignment);
332
+ for(let i = 0; i < this._params.cascades.length; i++){
333
+ this._cascades[i].x = this._params.cascades[i].size;
334
+ this._cascades[i].y = this._params.cascades[i].strength * 0.081 / (this._params.cascades[i].size * this._params.cascades[i].size);
335
+ this._cascades[i].z = 2 * Math.PI / this._params.cascades[i].maxWave;
336
+ this._cascades[i].w = 2 * Math.PI / this._params.cascades[i].minWave;
337
+ }
338
+ this._h0BindGroup.setValue('cascade0', this._cascades[0]);
339
+ this._h0BindGroup.setValue('cascade1', this._cascades[1]);
340
+ this._h0BindGroup.setValue('cascade2', this._cascades[2]);
341
+ if (device.type === 'webgpu') {
342
+ this._h0BindGroup.setTexture('spectrum', instanceData.h0Textures);
343
+ device.compute(this._params.resolution / THREAD_GROUP_SIZE, this._params.resolution / THREAD_GROUP_SIZE, 1);
344
+ } else {
345
+ device.setFramebuffer(instanceData.h0Framebuffer);
346
+ device.clearFrameBuffer(Vector4.zero(), null, null);
347
+ FFTWaveGenerator._globals.quad.draw();
348
+ }
349
+ }
350
+ /** @internal */ getNoiseTexture(size, randomSeed) {
351
+ const device = Application.instance.device;
352
+ let tex = FFTWaveGenerator._globals.noiseTextures.get(size);
353
+ if (!tex) {
354
+ tex = device.createTexture2D(device.type === 'webgl' ? 'rgba32f' : 'rg32f', size, size, {
355
+ samplerOptions: {
356
+ mipFilter: 'none'
357
+ }
358
+ });
359
+ tex.name = `noiseTex${size}`;
360
+ tex.update(this.getNoise2d(size, randomSeed, device.type === 'webgl'), 0, 0, size, size);
361
+ FFTWaveGenerator._globals.noiseTextures.set(size, tex);
362
+ }
363
+ return tex;
364
+ }
365
+ /** @internal */ getNoise2d(size, randomSeed, rgba) {
366
+ const rand = new PRNG(randomSeed);
367
+ if (rgba) {
368
+ const array = new Float32Array(size * size * 4);
369
+ for(let i = 0; i < size * size; i++){
370
+ array[i * 4 + 0] = rand.get();
371
+ array[i * 4 + 1] = rand.get();
372
+ }
373
+ return array;
374
+ } else {
375
+ return Float32Array.from([
376
+ ...Array(size * size * 2)
377
+ ].map(()=>rand.get()));
378
+ }
379
+ }
380
+ /** @internal */ reverseBits(v, width) {
381
+ return parseInt(v.toString(2).padStart(width, '0').split('').reverse().join(''), 2);
382
+ }
383
+ /** @internal */ createButterflyTexture(size) {
384
+ const width = Math.log2(size);
385
+ const height = size;
386
+ const texture = new Float32Array(width * height * 4);
387
+ const w = 2.0 * Math.PI / size;
388
+ const bitReversed = [
389
+ ...Array(size).keys()
390
+ ].map((v)=>this.reverseBits(v, width));
391
+ for(let j = 0; j < width; j++){
392
+ for(let i = 0; i < height; i++){
393
+ const k = i * (size >> j + 1);
394
+ const c = Math.cos(k * w);
395
+ const s = Math.sin(k * w);
396
+ const span = 2 ** j;
397
+ const wing = i % 2 ** (j + 1) < span ? 0 : 1; // 0 - top wing, 1 - bottom wing
398
+ const texel = new Vector4();
399
+ if (j === 0) {
400
+ if (wing === 0) {
401
+ texel.setXYZW(c, s, bitReversed[i], bitReversed[i + 1]);
402
+ } else {
403
+ texel.setXYZW(c, s, bitReversed[i - 1], bitReversed[i]);
404
+ }
405
+ } else {
406
+ if (wing === 0) {
407
+ texel.setXYZW(c, s, i, i + span);
408
+ } else {
409
+ texel.setXYZW(c, s, i - span, i);
410
+ }
411
+ }
412
+ texture[(width * i + j) * 4] = texel[0];
413
+ texture[(width * i + j) * 4 + 1] = texel[1];
414
+ texture[(width * i + j) * 4 + 2] = texel[2];
415
+ texture[(width * i + j) * 4 + 3] = texel[3];
416
+ }
417
+ }
418
+ return texture;
419
+ }
420
+ /** @internal */ getInstanceData() {
421
+ if (!this._instanceData) {
422
+ const device = Application.instance.device;
423
+ const h0Textures = this.createNTextures(device, this._h0TextureFormat, this._params.resolution, 3, 'Water-h0', false);
424
+ const dataTextures = this.createNTextures(device, this._dataTextureFormat, this._params.resolution, 6, 'Water-data', true);
425
+ const spectrumTextures = this.createNTextures(device, this._textureFormat, this._params.resolution, 6, 'Water-spectrum', true);
426
+ const pingpongTextures = this.createNTextures(device, this._textureFormat, this._params.resolution, 6, 'Water-pingpong', false);
427
+ this._instanceData = {
428
+ dataTextures,
429
+ h0Textures: h0Textures,
430
+ pingpongTextures: pingpongTextures,
431
+ spectrumTextures: spectrumTextures,
432
+ h0Framebuffer: this._useComputeShader ? null : device.createFrameBuffer(h0Textures, null),
433
+ spectrumFramebuffer: !this._useComputeShader && this._renderMode === RENDER_NORMAL ? device.createFrameBuffer(spectrumTextures, null) : null,
434
+ spectrumFramebuffer2: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(spectrumTextures.slice(4, 6), null) : null,
435
+ spectrumFramebuffer4: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(spectrumTextures.slice(0, 4), null) : null,
436
+ pingpongFramebuffer: !this._useComputeShader && this._renderMode === RENDER_NORMAL ? device.createFrameBuffer(pingpongTextures, null) : null,
437
+ pingpongFramebuffer2: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(pingpongTextures.slice(4, 6), null) : null,
438
+ pingpongFramebuffer4: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(pingpongTextures.slice(0, 4), null) : null,
439
+ postIfft2Framebuffer: !this._useComputeShader && this._renderMode === RENDER_NORMAL ? device.createFrameBuffer(dataTextures, null) : null,
440
+ postIfft2Framebuffer2: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(dataTextures.slice(4, 6), null) : null,
441
+ postIfft2Framebuffer4: this._renderMode === RENDER_TWO_PASS ? device.createFrameBuffer(dataTextures.slice(0, 4), null) : null
442
+ };
443
+ }
444
+ return this._instanceData;
445
+ }
446
+ /** @internal */ createNTextures(device, format, size, num, name, linear) {
447
+ const options = {
448
+ samplerOptions: {
449
+ minFilter: linear ? 'linear' : 'nearest',
450
+ magFilter: linear ? 'linear' : 'nearest',
451
+ mipFilter: 'none',
452
+ addressU: 'repeat',
453
+ addressV: 'repeat'
454
+ },
455
+ writable: !!this._useComputeShader
456
+ };
457
+ if (this._useComputeShader) {
458
+ const tex = device.createTexture2DArray(format, size, size, num, options);
459
+ tex.name = name;
460
+ return tex;
461
+ } else {
462
+ return Array.from({
463
+ length: num
464
+ }).map((val, index)=>{
465
+ const tex = device.createTexture2D(format, size, size, options);
466
+ tex.name = `${name}-${index}`;
467
+ return tex;
468
+ });
469
+ }
470
+ }
471
+ /** {@inheritDoc WaveGenerator.update} */ update(time) {
472
+ const device = Application.instance.device;
473
+ device.pushDeviceStates();
474
+ device.setRenderStates(this._updateRenderStates);
475
+ if (this._resolutionChanged) {
476
+ this.disposeInstanceData();
477
+ }
478
+ if (this._paramsChanged) {
479
+ this.generateInitialSpectrum();
480
+ }
481
+ this._resolutionChanged = false;
482
+ this._paramsChanged = false;
483
+ for(let i = 0; i < 3; i++){
484
+ this._sizes[i] = this._params.cascades[i].size;
485
+ this._croppinesses[i] = this._params.cascades[i].croppiness;
486
+ }
487
+ if (this._renderMode === RENDER_NORMAL) {
488
+ this.generateSpectrum(time);
489
+ this.ifft2();
490
+ this.postIfft2();
491
+ } else {
492
+ this.generateSpectrumTwoPass(time);
493
+ this.ifft2TwoPass();
494
+ this.postIfft2TwoPass();
495
+ }
496
+ device.popDeviceStates();
497
+ }
498
+ /** @internal */ disposeNTextures(texture) {
499
+ if (Array.isArray(texture)) {
500
+ texture.forEach((tex)=>tex.dispose());
501
+ } else if (texture) {
502
+ texture.dispose();
503
+ }
504
+ }
505
+ /** @internal */ disposeInstanceData() {
506
+ if (this._instanceData) {
507
+ this.disposeNTextures(this._instanceData.dataTextures);
508
+ this._instanceData.dataTextures = null;
509
+ this.disposeNTextures(this._instanceData.h0Textures);
510
+ this._instanceData.h0Textures = null;
511
+ this.disposeNTextures(this._instanceData.pingpongTextures);
512
+ this._instanceData.pingpongTextures = null;
513
+ this.disposeNTextures(this._instanceData.spectrumTextures);
514
+ this._instanceData.spectrumTextures = null;
515
+ this._instanceData.h0Framebuffer?.dispose();
516
+ this._instanceData.pingpongFramebuffer?.dispose();
517
+ this._instanceData.pingpongFramebuffer2?.dispose();
518
+ this._instanceData.pingpongFramebuffer4?.dispose();
519
+ this._instanceData.spectrumFramebuffer?.dispose();
520
+ this._instanceData.spectrumFramebuffer2?.dispose();
521
+ this._instanceData.spectrumFramebuffer4?.dispose();
522
+ this._instanceData.postIfft2Framebuffer?.dispose();
523
+ this._instanceData.postIfft2Framebuffer2?.dispose();
524
+ this._instanceData.postIfft2Framebuffer4?.dispose();
525
+ this._instanceData = null;
526
+ }
527
+ }
528
+ /** @internal */ generateSpectrum(time) {
529
+ const device = Application.instance.device;
530
+ const instanceData = this.getInstanceData();
531
+ const nearestRepeatSampler = fetchSampler('repeat_nearest_nomip');
532
+ device.setProgram(FFTWaveGenerator._globals.programs.hkProgram);
533
+ device.setBindGroup(0, this._hkBindGroup);
534
+ this._hkBindGroup.setValue('t', time);
535
+ this._hkBindGroup.setValue('resolution', this._params.resolution);
536
+ this._hkBindGroup.setValue('sizes', this._sizes);
537
+ if (this._useComputeShader) {
538
+ this._hkBindGroup.setTexture('h0Texture', instanceData.h0Textures);
539
+ this._hkBindGroup.setTexture('spectrum', instanceData.spectrumTextures);
540
+ device.compute(this._params.resolution / THREAD_GROUP_SIZE, this._params.resolution / THREAD_GROUP_SIZE, 1);
541
+ } else {
542
+ this._hkBindGroup.setTexture('h0Texture0', instanceData.h0Textures[0], nearestRepeatSampler);
543
+ this._hkBindGroup.setTexture('h0Texture1', instanceData.h0Textures[1], nearestRepeatSampler);
544
+ this._hkBindGroup.setTexture('h0Texture2', instanceData.h0Textures[2], nearestRepeatSampler);
545
+ if (device.type === 'webgl') {
546
+ this._hkBindGroup.setValue('h0TexSize', new Vector2(instanceData.h0Textures[0].width, instanceData.h0Textures[0].height));
547
+ }
548
+ device.setFramebuffer(instanceData.spectrumFramebuffer);
549
+ FFTWaveGenerator._globals.quad.draw();
550
+ }
551
+ }
552
+ /** @internal */ generateSpectrumTwoPass(time) {
553
+ const device = Application.instance.device;
554
+ const instanceData = this.getInstanceData();
555
+ const nearestRepeatSampler = fetchSampler('repeat_nearest_nomip');
556
+ device.setProgram(FFTWaveGenerator._globals.programs.hkProgram4);
557
+ device.setBindGroup(0, this._hkBindGroup4);
558
+ this._hkBindGroup4.setValue('resolution', this._params.resolution);
559
+ this._hkBindGroup4.setValue('sizes', this._sizes);
560
+ this._hkBindGroup4.setTexture('h0Texture0', instanceData.h0Textures[0], nearestRepeatSampler);
561
+ this._hkBindGroup4.setTexture('h0Texture1', instanceData.h0Textures[1], nearestRepeatSampler);
562
+ this._hkBindGroup4.setValue('t', time);
563
+ if (device.type === 'webgl') {
564
+ this._hkBindGroup4.setValue('h0TexSize', new Vector2(instanceData.h0Textures[0].width, instanceData.h0Textures[0].height));
565
+ }
566
+ device.setFramebuffer(instanceData.spectrumFramebuffer4);
567
+ FFTWaveGenerator._globals.quad.draw();
568
+ device.setProgram(FFTWaveGenerator._globals.programs.hkProgram2);
569
+ device.setBindGroup(0, this._hkBindGroup2);
570
+ this._hkBindGroup2.setValue('resolution', this._params.resolution);
571
+ this._hkBindGroup2.setValue('sizes', this._sizes);
572
+ this._hkBindGroup2.setTexture('h0Texture2', instanceData.h0Textures[2], nearestRepeatSampler);
573
+ this._hkBindGroup2.setValue('t', time);
574
+ if (device.type === 'webgl') {
575
+ this._hkBindGroup2.setValue('h0TexSize', new Vector2(instanceData.h0Textures[0].width, instanceData.h0Textures[0].height));
576
+ }
577
+ device.setFramebuffer(instanceData.spectrumFramebuffer2);
578
+ FFTWaveGenerator._globals.quad.draw();
579
+ }
580
+ /** @internal */ ifft2() {
581
+ const device = Application.instance.device;
582
+ const instanceData = this.getInstanceData();
583
+ const nearestRepeatSampler = fetchSampler('repeat_nearest_nomip');
584
+ const phases = Math.log2(this._params.resolution);
585
+ const pingPongTextures = [
586
+ instanceData.spectrumTextures,
587
+ instanceData.pingpongTextures
588
+ ];
589
+ const pingPongFramebuffers = this._useComputeShader ? [
590
+ instanceData.pingpongTextures,
591
+ instanceData.spectrumTextures
592
+ ] : [
593
+ instanceData.pingpongFramebuffer,
594
+ instanceData.spectrumFramebuffer
595
+ ];
596
+ const butterflyTex = this.getButterflyTexture(this._params.resolution);
597
+ let pingPong = 0;
598
+ // horizontal ifft
599
+ device.setProgram(FFTWaveGenerator._globals.programs.fft2hProgram);
600
+ device.setBindGroup(0, this._fft2hBindGroup);
601
+ this._fft2hBindGroup.setTexture('butterfly', butterflyTex, nearestRepeatSampler);
602
+ for(let phase = 0; phase < phases; phase++){
603
+ this._fft2hBindGroup.setValue('phase', phase);
604
+ if (this._useComputeShader) {
605
+ this._fft2hBindGroup.setTexture('spectrum', pingPongTextures[pingPong], nearestRepeatSampler);
606
+ this._fft2hBindGroup.setTexture('ifft', pingPongFramebuffers[pingPong]);
607
+ device.compute(this._params.resolution / THREAD_GROUP_SIZE, this._params.resolution / THREAD_GROUP_SIZE, 1);
608
+ } else {
609
+ device.setFramebuffer(pingPongFramebuffers[pingPong]);
610
+ this._fft2hBindGroup.setTexture('spectrum0', pingPongTextures[pingPong][0], nearestRepeatSampler);
611
+ this._fft2hBindGroup.setTexture('spectrum1', pingPongTextures[pingPong][1], nearestRepeatSampler);
612
+ this._fft2hBindGroup.setTexture('spectrum2', pingPongTextures[pingPong][2], nearestRepeatSampler);
613
+ this._fft2hBindGroup.setTexture('spectrum3', pingPongTextures[pingPong][3], nearestRepeatSampler);
614
+ this._fft2hBindGroup.setTexture('spectrum4', pingPongTextures[pingPong][4], nearestRepeatSampler);
615
+ this._fft2hBindGroup.setTexture('spectrum5', pingPongTextures[pingPong][5], nearestRepeatSampler);
616
+ if (device.type === 'webgl') {
617
+ this._fft2hBindGroup.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
618
+ }
619
+ FFTWaveGenerator._globals.quad.draw();
620
+ }
621
+ pingPong = 1 - pingPong; //(pingPong + 1) % 2;
622
+ }
623
+ // vertical ifft
624
+ device.setProgram(FFTWaveGenerator._globals.programs.fft2vProgram);
625
+ device.setBindGroup(0, this._fft2vBindGroup);
626
+ this._fft2vBindGroup.setTexture('butterfly', butterflyTex, nearestRepeatSampler);
627
+ for(let phase = 0; phase < phases; phase++){
628
+ this._fft2vBindGroup.setValue('phase', phase);
629
+ if (this._useComputeShader) {
630
+ this._fft2vBindGroup.setTexture('spectrum', pingPongTextures[pingPong], nearestRepeatSampler);
631
+ this._fft2vBindGroup.setTexture('ifft', pingPongFramebuffers[pingPong]);
632
+ device.compute(this._params.resolution / THREAD_GROUP_SIZE, this._params.resolution / THREAD_GROUP_SIZE, 1);
633
+ } else {
634
+ device.setFramebuffer(pingPongFramebuffers[pingPong]);
635
+ this._fft2vBindGroup.setTexture('spectrum0', pingPongTextures[pingPong][0], nearestRepeatSampler);
636
+ this._fft2vBindGroup.setTexture('spectrum1', pingPongTextures[pingPong][1], nearestRepeatSampler);
637
+ this._fft2vBindGroup.setTexture('spectrum2', pingPongTextures[pingPong][2], nearestRepeatSampler);
638
+ this._fft2vBindGroup.setTexture('spectrum3', pingPongTextures[pingPong][3], nearestRepeatSampler);
639
+ this._fft2vBindGroup.setTexture('spectrum4', pingPongTextures[pingPong][4], nearestRepeatSampler);
640
+ this._fft2vBindGroup.setTexture('spectrum5', pingPongTextures[pingPong][5], nearestRepeatSampler);
641
+ if (device.type === 'webgl') {
642
+ this._fft2vBindGroup.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
643
+ }
644
+ FFTWaveGenerator._globals.quad.draw();
645
+ }
646
+ pingPong = 1 - pingPong;
647
+ }
648
+ this._ifftTextures = pingPongTextures[pingPong];
649
+ }
650
+ /** @internal */ getFFT2hBindGroup2(device, pingpong) {
651
+ let bindGroup = this._fft2hBindGroup2Used[pingpong].pop();
652
+ if (!bindGroup) {
653
+ bindGroup = device.createBindGroup(FFTWaveGenerator._globals.programs.fft2hProgram2.bindGroupLayouts[0]);
654
+ }
655
+ this._fft2hBindGroup2Free[pingpong].push(bindGroup);
656
+ return bindGroup;
657
+ }
658
+ /** @internal */ getFFT2hBindGroup4(device, pingpong) {
659
+ let bindGroup = this._fft2hBindGroup4Used[pingpong].pop();
660
+ if (!bindGroup) {
661
+ bindGroup = device.createBindGroup(FFTWaveGenerator._globals.programs.fft2hProgram4.bindGroupLayouts[0]);
662
+ }
663
+ this._fft2hBindGroup4Free[pingpong].push(bindGroup);
664
+ return bindGroup;
665
+ }
666
+ /** @internal */ getFFT2vBindGroup2(device, pingpong) {
667
+ let bindGroup = this._fft2vBindGroup2Used[pingpong].pop();
668
+ if (!bindGroup) {
669
+ bindGroup = device.createBindGroup(FFTWaveGenerator._globals.programs.fft2vProgram2.bindGroupLayouts[0]);
670
+ }
671
+ this._fft2vBindGroup2Free[pingpong].push(bindGroup);
672
+ return bindGroup;
673
+ }
674
+ /** @internal */ getFFT2vBindGroup4(device, pingpong) {
675
+ let bindGroup = this._fft2vBindGroup4Used[pingpong].pop();
676
+ if (!bindGroup) {
677
+ bindGroup = device.createBindGroup(FFTWaveGenerator._globals.programs.fft2vProgram4.bindGroupLayouts[0]);
678
+ }
679
+ this._fft2vBindGroup4Free[pingpong].push(bindGroup);
680
+ return bindGroup;
681
+ }
682
+ /** @internal */ ifft2TwoPass() {
683
+ const device = Application.instance.device;
684
+ const instanceData = this.getInstanceData();
685
+ const nearestRepeatSampler = fetchSampler('repeat_nearest_nomip');
686
+ const phases = Math.log2(this._params.resolution);
687
+ const pingPongTextures = [
688
+ instanceData.spectrumTextures,
689
+ instanceData.pingpongTextures
690
+ ];
691
+ const pingPongFramebuffers4 = [
692
+ instanceData.pingpongFramebuffer4,
693
+ instanceData.spectrumFramebuffer4
694
+ ];
695
+ const pingPongFramebuffers2 = [
696
+ instanceData.pingpongFramebuffer2,
697
+ instanceData.spectrumFramebuffer2
698
+ ];
699
+ const butterflyTex = this.getButterflyTexture(this._params.resolution);
700
+ // horizontal ifft
701
+ let pingPong = 0;
702
+ for(let phase = 0; phase < phases; phase++){
703
+ device.setFramebuffer(pingPongFramebuffers4[pingPong]);
704
+ device.setProgram(FFTWaveGenerator._globals.programs.fft2hProgram4);
705
+ const fft2hBindGroup4 = this.getFFT2hBindGroup4(device, pingPong);
706
+ device.setBindGroup(0, fft2hBindGroup4);
707
+ fft2hBindGroup4.setTexture('butterfly', butterflyTex, nearestRepeatSampler);
708
+ fft2hBindGroup4.setValue('phase', phase);
709
+ fft2hBindGroup4.setTexture('spectrum0', pingPongTextures[pingPong][0], nearestRepeatSampler);
710
+ fft2hBindGroup4.setTexture('spectrum1', pingPongTextures[pingPong][1], nearestRepeatSampler);
711
+ fft2hBindGroup4.setTexture('spectrum2', pingPongTextures[pingPong][2], nearestRepeatSampler);
712
+ fft2hBindGroup4.setTexture('spectrum3', pingPongTextures[pingPong][3], nearestRepeatSampler);
713
+ if (device.type === 'webgl') {
714
+ fft2hBindGroup4.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
715
+ }
716
+ FFTWaveGenerator._globals.quad.draw();
717
+ device.setFramebuffer(pingPongFramebuffers2[pingPong]);
718
+ device.setProgram(FFTWaveGenerator._globals.programs.fft2hProgram2);
719
+ const fft2hBindGroup2 = this.getFFT2hBindGroup2(device, pingPong);
720
+ device.setBindGroup(0, fft2hBindGroup2);
721
+ fft2hBindGroup2.setTexture('butterfly', butterflyTex, nearestRepeatSampler);
722
+ fft2hBindGroup2.setValue('phase', phase);
723
+ fft2hBindGroup2.setTexture('spectrum4', pingPongTextures[pingPong][4], nearestRepeatSampler);
724
+ fft2hBindGroup2.setTexture('spectrum5', pingPongTextures[pingPong][5], nearestRepeatSampler);
725
+ if (device.type === 'webgl') {
726
+ fft2hBindGroup2.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
727
+ }
728
+ FFTWaveGenerator._globals.quad.draw();
729
+ pingPong = (pingPong + 1) % 2;
730
+ }
731
+ // vertical ifft
732
+ for(let phase = 0; phase < phases; phase++){
733
+ device.setFramebuffer(pingPongFramebuffers4[pingPong]);
734
+ device.setProgram(FFTWaveGenerator._globals.programs.fft2vProgram4);
735
+ const fft2vBindGroup4 = this.getFFT2vBindGroup4(device, pingPong);
736
+ device.setBindGroup(0, fft2vBindGroup4);
737
+ fft2vBindGroup4.setTexture('butterfly', butterflyTex, nearestRepeatSampler);
738
+ fft2vBindGroup4.setValue('phase', phase);
739
+ fft2vBindGroup4.setTexture('spectrum0', pingPongTextures[pingPong][0], nearestRepeatSampler);
740
+ fft2vBindGroup4.setTexture('spectrum1', pingPongTextures[pingPong][1], nearestRepeatSampler);
741
+ fft2vBindGroup4.setTexture('spectrum2', pingPongTextures[pingPong][2], nearestRepeatSampler);
742
+ fft2vBindGroup4.setTexture('spectrum3', pingPongTextures[pingPong][3], nearestRepeatSampler);
743
+ if (device.type === 'webgl') {
744
+ fft2vBindGroup4.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
745
+ }
746
+ FFTWaveGenerator._globals.quad.draw();
747
+ device.setFramebuffer(pingPongFramebuffers2[pingPong]);
748
+ device.setProgram(FFTWaveGenerator._globals.programs.fft2vProgram2);
749
+ const fft2vBindGroup2 = this.getFFT2vBindGroup2(device, pingPong);
750
+ device.setBindGroup(0, fft2vBindGroup2);
751
+ fft2vBindGroup2.setTexture('butterfly', butterflyTex, nearestRepeatSampler);
752
+ fft2vBindGroup2.setValue('phase', phase);
753
+ fft2vBindGroup2.setTexture('spectrum4', pingPongTextures[pingPong][4], nearestRepeatSampler);
754
+ fft2vBindGroup2.setTexture('spectrum5', pingPongTextures[pingPong][5], nearestRepeatSampler);
755
+ if (device.type === 'webgl') {
756
+ fft2vBindGroup2.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
757
+ }
758
+ FFTWaveGenerator._globals.quad.draw();
759
+ pingPong = (pingPong + 1) % 2;
760
+ }
761
+ this._ifftTextures = pingPongTextures[pingPong];
762
+ for(let i = 0; i < 2; i++){
763
+ this._fft2hBindGroup2Used[i].push(...this._fft2hBindGroup2Free[i]);
764
+ this._fft2hBindGroup2Free[i].length = 0;
765
+ this._fft2hBindGroup4Used[i].push(...this._fft2hBindGroup4Free[i]);
766
+ this._fft2hBindGroup4Free[i].length = 0;
767
+ this._fft2vBindGroup2Used[i].push(...this._fft2vBindGroup2Free[i]);
768
+ this._fft2vBindGroup2Free[i].length = 0;
769
+ this._fft2vBindGroup4Used[i].push(...this._fft2vBindGroup4Free[i]);
770
+ this._fft2vBindGroup4Free[i].length = 0;
771
+ }
772
+ }
773
+ /** @internal */ postIfft2() {
774
+ const device = Application.instance.device;
775
+ const instanceData = this.getInstanceData();
776
+ const nearestRepeatSampler = fetchSampler('repeat_nearest_nomip');
777
+ device.setProgram(FFTWaveGenerator._globals.programs.postfft2Program);
778
+ device.setBindGroup(0, this._postfft2BindGroup);
779
+ this._postfft2BindGroup.setValue('N2', this._params.resolution * this._params.resolution);
780
+ if (this._useComputeShader) {
781
+ this._postfft2BindGroup.setTexture('output', instanceData.dataTextures);
782
+ this._postfft2BindGroup.setTexture('ifft', this._ifftTextures, nearestRepeatSampler);
783
+ device.compute(this._params.resolution / THREAD_GROUP_SIZE, this._params.resolution / THREAD_GROUP_SIZE, 1);
784
+ } else {
785
+ device.setFramebuffer(instanceData.postIfft2Framebuffer);
786
+ this._postfft2BindGroup.setTexture('ifft0', this._ifftTextures[0], nearestRepeatSampler);
787
+ this._postfft2BindGroup.setTexture('ifft1', this._ifftTextures[1], nearestRepeatSampler);
788
+ this._postfft2BindGroup.setTexture('ifft2', this._ifftTextures[2], nearestRepeatSampler);
789
+ this._postfft2BindGroup.setTexture('ifft3', this._ifftTextures[3], nearestRepeatSampler);
790
+ this._postfft2BindGroup.setTexture('ifft4', this._ifftTextures[4], nearestRepeatSampler);
791
+ this._postfft2BindGroup.setTexture('ifft5', this._ifftTextures[5], nearestRepeatSampler);
792
+ if (device.type === 'webgl') {
793
+ this._postfft2BindGroup.setValue('ifftTexSize', new Vector2(this._ifftTextures[0].width, this._ifftTextures[0].height));
794
+ }
795
+ FFTWaveGenerator._globals.quad.draw();
796
+ }
797
+ }
798
+ /** @internal */ postIfft2TwoPass() {
799
+ const device = Application.instance.device;
800
+ const instanceData = this.getInstanceData();
801
+ const nearestRepeatSampler = fetchSampler('repeat_nearest_nomip');
802
+ device.setFramebuffer(instanceData.postIfft2Framebuffer4);
803
+ device.setProgram(FFTWaveGenerator._globals.programs.postfft2Program4);
804
+ device.setBindGroup(0, this._postfft2BindGroup4);
805
+ this._postfft2BindGroup4.setValue('N2', this._params.resolution * this._params.resolution);
806
+ this._postfft2BindGroup4.setTexture('ifft0', this._ifftTextures[0], nearestRepeatSampler);
807
+ this._postfft2BindGroup4.setTexture('ifft1', this._ifftTextures[1], nearestRepeatSampler);
808
+ this._postfft2BindGroup4.setTexture('ifft2', this._ifftTextures[2], nearestRepeatSampler);
809
+ this._postfft2BindGroup4.setTexture('ifft3', this._ifftTextures[3], nearestRepeatSampler);
810
+ if (device.type === 'webgl') {
811
+ this._postfft2BindGroup4.setValue('ifftTexSize', new Vector2(this._ifftTextures[0].width, this._ifftTextures[0].height));
812
+ }
813
+ FFTWaveGenerator._globals.quad.draw();
814
+ device.setFramebuffer(instanceData.postIfft2Framebuffer2);
815
+ device.setProgram(FFTWaveGenerator._globals.programs.postfft2Program2);
816
+ device.setBindGroup(0, this._postfft2BindGroup2);
817
+ this._postfft2BindGroup2.setValue('N2', this._params.resolution * this._params.resolution);
818
+ this._postfft2BindGroup2.setTexture('ifft4', this._ifftTextures[4], nearestRepeatSampler);
819
+ this._postfft2BindGroup2.setTexture('ifft5', this._ifftTextures[5], nearestRepeatSampler);
820
+ if (device.type === 'webgl') {
821
+ this._postfft2BindGroup2.setValue('ifftTexSize', new Vector2(this._ifftTextures[0].width, this._ifftTextures[0].height));
822
+ }
823
+ FFTWaveGenerator._globals.quad.draw();
824
+ }
825
+ /** {@inheritDoc WaveGenerator.setupUniforms} */ setupUniforms(scope) {
826
+ const pb = scope.$builder;
827
+ scope.sizes = pb.vec4().uniform(0);
828
+ scope.croppinesses = pb.vec4().uniform(0);
829
+ if (this._useComputeShader) {
830
+ scope.dataTexture = pb.tex2DArray().uniform(0);
831
+ } else {
832
+ scope.dx_hy_dz_dxdz0 = pb.tex2D().uniform(0);
833
+ scope.sx_sz_dxdx_dzdz0 = pb.tex2D().uniform(0);
834
+ scope.dx_hy_dz_dxdz1 = pb.tex2D().uniform(0);
835
+ scope.sx_sz_dxdx_dzdz1 = pb.tex2D().uniform(0);
836
+ scope.dx_hy_dz_dxdz2 = pb.tex2D().uniform(0);
837
+ scope.sx_sz_dxdx_dzdz2 = pb.tex2D().uniform(0);
838
+ }
839
+ if (pb.shaderKind === 'fragment') {
840
+ scope.foamParams = pb.vec2().uniform(0);
841
+ }
842
+ }
843
+ /** {@inheritDoc WaveGenerator.calcVertexPositionAndNormal} */ calcVertexPositionAndNormal(scope, inPos, outPos, outNormal) {
844
+ const pb = scope.$builder;
845
+ const that = this;
846
+ pb.func('calcPositionAndNormal', [
847
+ pb.vec3('inPos'),
848
+ pb.vec3('outPos').out(),
849
+ pb.vec3('outNormal').out()
850
+ ], function() {
851
+ this.$l.xz = this.inPos.xz;
852
+ this.$l.uv0 = pb.div(this.xz, this.sizes.x);
853
+ this.$l.uv1 = pb.div(this.xz, this.sizes.y);
854
+ this.$l.uv2 = pb.div(this.xz, this.sizes.z);
855
+ if (that._useComputeShader) {
856
+ this.$l.a = pb.mul(pb.textureArraySampleLevel(this.dataTexture, this.uv0, 0, 0).rgb, pb.vec3(this.croppinesses.x, 1, this.croppinesses.x));
857
+ this.$l.b = pb.mul(pb.textureArraySampleLevel(this.dataTexture, this.uv1, 2, 0).rgb, pb.vec3(this.croppinesses.y, 1, this.croppinesses.y));
858
+ this.$l.c = pb.mul(pb.textureArraySampleLevel(this.dataTexture, this.uv2, 4, 0).rgb, pb.vec3(this.croppinesses.z, 1, this.croppinesses.z));
859
+ } else {
860
+ this.$l.a = pb.mul(pb.textureSampleLevel(this.dx_hy_dz_dxdz0, this.uv0, 0).rgb, pb.vec3(this.croppinesses.x, 1, this.croppinesses.x));
861
+ this.$l.b = pb.mul(pb.textureSampleLevel(this.dx_hy_dz_dxdz1, this.uv1, 0).rgb, pb.vec3(this.croppinesses.y, 1, this.croppinesses.y));
862
+ this.$l.c = pb.mul(pb.textureSampleLevel(this.dx_hy_dz_dxdz2, this.uv2, 0).rgb, pb.vec3(this.croppinesses.z, 1, this.croppinesses.z));
863
+ }
864
+ this.$l.displacement = pb.add(this.a, this.b, this.c);
865
+ this.outPos = pb.add(this.inPos, this.displacement);
866
+ this.outNormal = pb.vec3(0, 1, 0);
867
+ });
868
+ scope.calcPositionAndNormal(inPos, outPos, outNormal);
869
+ }
870
+ /** {@inheritDoc WaveGenerator.calcFragmentNormal} */ calcFragmentNormal(scope, xz, vertexNormal) {
871
+ const pb = scope.$builder;
872
+ const that = this;
873
+ pb.func('calcFragmentNormal', [
874
+ pb.vec2('xz')
875
+ ], function() {
876
+ this.$l.uv0 = pb.div(this.xz, this.sizes.x);
877
+ this.$l.uv1 = pb.div(this.xz, this.sizes.y);
878
+ this.$l.uv2 = pb.div(this.xz, this.sizes.z);
879
+ if (that._useComputeShader) {
880
+ this.$l._sx_sz_dxdx_dzdz0 = pb.textureArraySampleLevel(this.dataTexture, this.uv0, 1, 0);
881
+ this.$l._sx_sz_dxdx_dzdz1 = pb.textureArraySampleLevel(this.dataTexture, this.uv1, 3, 0);
882
+ this.$l._sx_sz_dxdx_dzdz2 = pb.textureArraySampleLevel(this.dataTexture, this.uv2, 5, 0);
883
+ } else {
884
+ this.$l._sx_sz_dxdx_dzdz0 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz0, this.uv0, 0);
885
+ this.$l._sx_sz_dxdx_dzdz1 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz1, this.uv1, 0);
886
+ this.$l._sx_sz_dxdx_dzdz2 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz2, this.uv2, 0);
887
+ }
888
+ this.$l.sx = pb.add(this._sx_sz_dxdx_dzdz0.x, this._sx_sz_dxdx_dzdz1.x, this._sx_sz_dxdx_dzdz2.x);
889
+ this.$l.sz = pb.add(this._sx_sz_dxdx_dzdz0.y, this._sx_sz_dxdx_dzdz1.y, this._sx_sz_dxdx_dzdz2.y);
890
+ this.$l.dxdx_dzdz = pb.add(pb.mul(this._sx_sz_dxdx_dzdz0.zw, this.croppinesses.x), pb.mul(this._sx_sz_dxdx_dzdz1.zw, this.croppinesses.y), pb.mul(this._sx_sz_dxdx_dzdz2.zw, this.croppinesses.z));
891
+ this.$l.slope = pb.vec2(pb.div(this.sx, pb.add(1.0, this.dxdx_dzdz.x)), pb.div(this.sz, pb.add(1.0, this.dxdx_dzdz.y)));
892
+ this.$l.normal = pb.normalize(pb.vec3(pb.neg(this.slope.x), 1.0, pb.neg(this.slope.y)));
893
+ this.$return(this.normal);
894
+ });
895
+ return scope.calcFragmentNormal(xz);
896
+ }
897
+ /** {@inheritDoc WaveGenerator.calcFragmentNormalAndFoam} */ calcFragmentNormalAndFoam(scope, xz) {
898
+ const pb = scope.$builder;
899
+ const that = this;
900
+ pb.func('jacobian', [
901
+ pb.float('dxdx'),
902
+ pb.float('dxdz'),
903
+ pb.float('dzdz')
904
+ ], function() {
905
+ this.$l.Jxx = pb.add(this.dxdx, 1);
906
+ this.$l.Jxz = this.dxdz;
907
+ this.$l.Jzz = pb.add(this.dzdz, 1);
908
+ this.$return(pb.vec4(this.Jxx, this.Jxz, this.Jxz, this.Jzz));
909
+ });
910
+ pb.func('det', [
911
+ pb.vec4('jacobian')
912
+ ], function() {
913
+ this.$return(pb.sub(pb.mul(this.jacobian.x, this.jacobian.w), pb.mul(this.jacobian.y, this.jacobian.z)));
914
+ });
915
+ pb.func('calcNormalAndFoam', [
916
+ pb.vec2('xz')
917
+ ], function() {
918
+ this.$l.uv0 = pb.div(this.xz, this.sizes.x);
919
+ this.$l.uv1 = pb.div(this.xz, this.sizes.y);
920
+ this.$l.uv2 = pb.div(this.xz, this.sizes.z);
921
+ if (that._useComputeShader) {
922
+ this.$l._sx_sz_dxdx_dzdz0 = pb.textureArraySampleLevel(this.dataTexture, this.uv0, 1, 0);
923
+ this.$l._sx_sz_dxdx_dzdz1 = pb.textureArraySampleLevel(this.dataTexture, this.uv1, 3, 0);
924
+ this.$l._sx_sz_dxdx_dzdz2 = pb.textureArraySampleLevel(this.dataTexture, this.uv2, 5, 0);
925
+ } else {
926
+ this.$l._sx_sz_dxdx_dzdz0 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz0, this.uv0, 0);
927
+ this.$l._sx_sz_dxdx_dzdz1 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz1, this.uv1, 0);
928
+ this.$l._sx_sz_dxdx_dzdz2 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz2, this.uv2, 0);
929
+ }
930
+ this.$l.sx = pb.add(this._sx_sz_dxdx_dzdz0.x, this._sx_sz_dxdx_dzdz1.x, this._sx_sz_dxdx_dzdz2.x);
931
+ this.$l.sz = pb.add(this._sx_sz_dxdx_dzdz0.y, this._sx_sz_dxdx_dzdz1.y, this._sx_sz_dxdx_dzdz2.y);
932
+ this.$l.dxdx_dzdz = pb.add(pb.mul(this._sx_sz_dxdx_dzdz0.zw, this.croppinesses.x), pb.mul(this._sx_sz_dxdx_dzdz1.zw, this.croppinesses.y), pb.mul(this._sx_sz_dxdx_dzdz2.zw, this.croppinesses.z));
933
+ this.$l.slope = pb.vec2(pb.div(this.sx, pb.add(1.0, this.dxdx_dzdz.x)), pb.div(this.sz, pb.add(1.0, this.dxdx_dzdz.y)));
934
+ this.$l.normal = pb.normalize(pb.vec3(pb.neg(this.slope.x), 1.0, pb.neg(this.slope.y)));
935
+ // foam
936
+ this.$l.dxdx_dzdz0 = this._sx_sz_dxdx_dzdz0.zw;
937
+ this.$l.dxdx_dzdz1 = this._sx_sz_dxdx_dzdz1.zw;
938
+ this.$l.dxdx_dzdz2 = this._sx_sz_dxdx_dzdz2.zw;
939
+ if (that._useComputeShader) {
940
+ this.$l.dxdz0 = pb.textureArraySampleLevel(this.dataTexture, this.uv0, 0, 0).w;
941
+ this.$l.dxdz1 = pb.textureArraySampleLevel(this.dataTexture, this.uv1, 2, 0).w;
942
+ this.$l.dxdz2 = pb.textureArraySampleLevel(this.dataTexture, this.uv2, 4, 0).w;
943
+ } else {
944
+ this.$l.dxdz0 = pb.textureSampleLevel(this.dx_hy_dz_dxdz0, this.uv0, 0).w;
945
+ this.$l.dxdz1 = pb.textureSampleLevel(this.dx_hy_dz_dxdz1, this.uv1, 0).w;
946
+ this.$l.dxdz2 = pb.textureSampleLevel(this.dx_hy_dz_dxdz2, this.uv2, 0).w;
947
+ }
948
+ this.$l.dxdz = pb.add(pb.mul(this.dxdz0, this.croppinesses.x), pb.mul(this.dxdz1, this.croppinesses.y), pb.mul(this.dxdz2, this.croppinesses.z));
949
+ this.$l.val = this.det(this.jacobian(this.dxdx_dzdz.x, this.dxdz, this.dxdx_dzdz.y));
950
+ this.$l.foam = pb.abs(pb.pow(pb.neg(pb.min(0, pb.sub(this.val, this.foamParams.x))), this.foamParams.y));
951
+ this.$return(pb.vec4(this.normal, this.foam));
952
+ });
953
+ return scope.calcNormalAndFoam(xz);
954
+ }
955
+ /** {@inheritDoc WaveGenerator.isOk} */ isOk() {
956
+ return this._renderMode !== RENDER_NONE;
957
+ }
958
+ /** {@inheritDoc WaveGenerator.applyWaterBindGroup} */ applyWaterBindGroup(bindGroup) {
959
+ const instanceData = this.getInstanceData();
960
+ const linearRepeatSampler = fetchSampler('repeat_linear_nomip');
961
+ if (this._useComputeShader) {
962
+ bindGroup.setTexture('dataTexture', instanceData.dataTextures, linearRepeatSampler);
963
+ } else {
964
+ bindGroup.setTexture('dx_hy_dz_dxdz0', instanceData.dataTextures[0], linearRepeatSampler);
965
+ bindGroup.setTexture('sx_sz_dxdx_dzdz0', instanceData.dataTextures[1], linearRepeatSampler);
966
+ bindGroup.setTexture('dx_hy_dz_dxdz1', instanceData.dataTextures[2], linearRepeatSampler);
967
+ bindGroup.setTexture('sx_sz_dxdx_dzdz1', instanceData.dataTextures[3], linearRepeatSampler);
968
+ bindGroup.setTexture('dx_hy_dz_dxdz2', instanceData.dataTextures[4], linearRepeatSampler);
969
+ bindGroup.setTexture('sx_sz_dxdx_dzdz2', instanceData.dataTextures[5], linearRepeatSampler);
970
+ }
971
+ bindGroup.setValue('foamParams', this._params.foamParams);
972
+ bindGroup.setValue('sizes', this._sizes);
973
+ bindGroup.setValue('croppinesses', this._croppinesses);
974
+ }
975
+ /** {@inheritDoc WaveGenerator.dispose} */ dispose() {
976
+ this.disposeInstanceData();
977
+ }
978
+ /** {@inheritDoc WaveGenerator.calcClipmapTileAABB} */ calcClipmapTileAABB(minX, maxX, minZ, maxZ, y, outAABB) {
979
+ const disturb = Math.max(Math.abs(this.wind.x), Math.abs(this.wind.y), 2);
980
+ outAABB.minPoint.setXYZ(minX - 8 * disturb, y - 8 * disturb, minZ - 8 * disturb);
981
+ outAABB.maxPoint.setXYZ(maxX + 8 * disturb, y + 8 * disturb, maxZ + 8 * disturb);
982
+ }
983
+ /** {@inheritDoc WaveGenerator.getHash} */ getHash() {
984
+ return '';
985
+ }
986
+ }
987
+
988
+ export { FFTWaveGenerator };
989
+ //# sourceMappingURL=fft_wavegenerator.js.map