@zephyr3d/scene 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/README.md +1 -1
  2. package/dist/animation/animationset.js +37 -37
  3. package/dist/animation/morphtrack.js +7 -5
  4. package/dist/animation/morphtrack.js.map +1 -1
  5. package/dist/animation/skeleton.js +11 -9
  6. package/dist/animation/skeleton.js.map +1 -1
  7. package/dist/asset/assetmanager.js +2 -2
  8. package/dist/asset/loaders/gltf/gltf_loader.js +7 -3
  9. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  10. package/dist/asset/loaders/image/webimage_loader.js +16 -0
  11. package/dist/asset/loaders/image/webimage_loader.js.map +1 -1
  12. package/dist/asset/model.js +3 -9
  13. package/dist/asset/model.js.map +1 -1
  14. package/dist/blitter/bilateralblur.js +222 -0
  15. package/dist/{render/temporalcache.js.map → blitter/bilateralblur.js.map} +1 -1
  16. package/dist/blitter/blitter.js +7 -1
  17. package/dist/blitter/blitter.js.map +1 -1
  18. package/dist/blitter/depthlimitedgaussion.js +96 -39
  19. package/dist/blitter/depthlimitedgaussion.js.map +1 -1
  20. package/dist/blitter/gaussianblur.js +21 -21
  21. package/dist/camera/camera.js +142 -1
  22. package/dist/camera/camera.js.map +1 -1
  23. package/dist/index.d.ts +1178 -745
  24. package/dist/index.js +11 -6
  25. package/dist/index.js.map +1 -1
  26. package/dist/material/blinn.js +9 -3
  27. package/dist/material/blinn.js.map +1 -1
  28. package/dist/material/lambert.js +6 -2
  29. package/dist/material/lambert.js.map +1 -1
  30. package/dist/material/material.js +3 -1
  31. package/dist/material/material.js.map +1 -1
  32. package/dist/material/meshmaterial.js +73 -33
  33. package/dist/material/meshmaterial.js.map +1 -1
  34. package/dist/material/mixins/albedocolor.js +5 -4
  35. package/dist/material/mixins/albedocolor.js.map +1 -1
  36. package/dist/material/mixins/lightmodel/blinnphong.js +17 -7
  37. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  38. package/dist/material/mixins/lightmodel/lambert.js +5 -5
  39. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +13 -4
  40. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  41. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +13 -4
  42. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  43. package/dist/material/mixins/pbr/common.js +27 -15
  44. package/dist/material/mixins/pbr/common.js.map +1 -1
  45. package/dist/material/pbrmr.js +14 -3
  46. package/dist/material/pbrmr.js.map +1 -1
  47. package/dist/material/pbrsg.js +14 -3
  48. package/dist/material/pbrsg.js.map +1 -1
  49. package/dist/material/shader/helper.js +36 -21
  50. package/dist/material/shader/helper.js.map +1 -1
  51. package/dist/posteffect/bloom.js +1 -10
  52. package/dist/posteffect/bloom.js.map +1 -1
  53. package/dist/posteffect/compositor.js +43 -24
  54. package/dist/posteffect/compositor.js.map +1 -1
  55. package/dist/posteffect/fxaa.js +3 -11
  56. package/dist/posteffect/fxaa.js.map +1 -1
  57. package/dist/posteffect/grayscale.js +3 -11
  58. package/dist/posteffect/grayscale.js.map +1 -1
  59. package/dist/posteffect/posteffect.js +4 -0
  60. package/dist/posteffect/posteffect.js.map +1 -1
  61. package/dist/posteffect/sao.js +44 -24
  62. package/dist/posteffect/sao.js.map +1 -1
  63. package/dist/posteffect/ssr.js +536 -0
  64. package/dist/{material/lit.js.map → posteffect/ssr.js.map} +1 -1
  65. package/dist/posteffect/tonemap.js +3 -11
  66. package/dist/posteffect/tonemap.js.map +1 -1
  67. package/dist/posteffect/water.js +305 -337
  68. package/dist/posteffect/water.js.map +1 -1
  69. package/dist/render/abuffer_oit.js +2 -2
  70. package/dist/render/clipmap.js +16 -19
  71. package/dist/render/clipmap.js.map +1 -1
  72. package/dist/render/cull_visitor.js +5 -3
  73. package/dist/render/cull_visitor.js.map +1 -1
  74. package/dist/render/depthpass.js +17 -1
  75. package/dist/render/depthpass.js.map +1 -1
  76. package/dist/render/drawable_mixin.js +25 -19
  77. package/dist/render/drawable_mixin.js.map +1 -1
  78. package/dist/render/envlight.js +4 -2
  79. package/dist/render/envlight.js.map +1 -1
  80. package/dist/render/fft_wavegenerator.js +989 -0
  81. package/dist/{shaders/framework.js.map → render/fft_wavegenerator.js.map} +1 -1
  82. package/dist/render/gerstner_wavegenerator.js +265 -0
  83. package/dist/{material/standard.js.map → render/gerstner_wavegenerator.js.map} +1 -1
  84. package/dist/render/globalbindgroup_allocator.js +2 -1
  85. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  86. package/dist/render/hzb.js +273 -0
  87. package/dist/{material/terrainlightmodel.js.map → render/hzb.js.map} +1 -1
  88. package/dist/render/lightpass.js +35 -3
  89. package/dist/render/lightpass.js.map +1 -1
  90. package/dist/render/objectcolorpass.js +2 -1
  91. package/dist/render/objectcolorpass.js.map +1 -1
  92. package/dist/render/render_queue.js +72 -52
  93. package/dist/render/render_queue.js.map +1 -1
  94. package/dist/render/renderbundle_wrapper.js +79 -0
  95. package/dist/render/renderbundle_wrapper.js.map +1 -1
  96. package/dist/render/renderer.js +75 -36
  97. package/dist/render/renderer.js.map +1 -1
  98. package/dist/render/renderpass.js +16 -13
  99. package/dist/render/renderpass.js.map +1 -1
  100. package/dist/render/shadowmap_pass.js +6 -0
  101. package/dist/render/shadowmap_pass.js.map +1 -1
  102. package/dist/render/sky.js +12 -13
  103. package/dist/render/sky.js.map +1 -1
  104. package/dist/render/watermesh.js +94 -828
  105. package/dist/render/watermesh.js.map +1 -1
  106. package/dist/render/wavegenerator.js +8 -0
  107. package/dist/render/wavegenerator.js.map +1 -0
  108. package/dist/scene/batchgroup.js +60 -14
  109. package/dist/scene/batchgroup.js.map +1 -1
  110. package/dist/scene/environment.js +2 -2
  111. package/dist/scene/graph_node.js +0 -5
  112. package/dist/scene/graph_node.js.map +1 -1
  113. package/dist/scene/light.js +5 -5
  114. package/dist/scene/mesh.js +34 -18
  115. package/dist/scene/mesh.js.map +1 -1
  116. package/dist/scene/octree.js +5 -2
  117. package/dist/scene/octree.js.map +1 -1
  118. package/dist/scene/raycast_visitor.js +4 -2
  119. package/dist/scene/raycast_visitor.js.map +1 -1
  120. package/dist/scene/scene.js +1 -1
  121. package/dist/scene/scene_node.js +9 -5
  122. package/dist/scene/scene_node.js.map +1 -1
  123. package/dist/scene/terrain/grass.js +3 -4
  124. package/dist/scene/terrain/grass.js.map +1 -1
  125. package/dist/scene/terrain/heightfield.js +135 -53
  126. package/dist/scene/terrain/heightfield.js.map +1 -1
  127. package/dist/scene/terrain/patch.js +3 -4
  128. package/dist/scene/terrain/patch.js.map +1 -1
  129. package/dist/scene/terrain/terrain.js +1 -1
  130. package/dist/scene/xform.js +7 -9
  131. package/dist/scene/xform.js.map +1 -1
  132. package/dist/shaders/misc.js +10 -1
  133. package/dist/shaders/misc.js.map +1 -1
  134. package/dist/shaders/noise.js +81 -16
  135. package/dist/shaders/noise.js.map +1 -1
  136. package/dist/shaders/shadow.js +1 -9
  137. package/dist/shaders/shadow.js.map +1 -1
  138. package/dist/shaders/ssr.js +442 -0
  139. package/dist/{material/terrainmat.js.map → shaders/ssr.js.map} +1 -1
  140. package/dist/shaders/water.js +377 -250
  141. package/dist/shaders/water.js.map +1 -1
  142. package/dist/shadow/shadowmapper.js +11 -11
  143. package/dist/shapes/cylinder.js +6 -5
  144. package/dist/shapes/cylinder.js.map +1 -1
  145. package/dist/utility/bounding_volume.js +1 -53
  146. package/dist/utility/bounding_volume.js.map +1 -1
  147. package/dist/utility/misc.js +93 -0
  148. package/dist/utility/misc.js.map +1 -0
  149. package/dist/utility/shprojection.js +2 -7
  150. package/dist/utility/shprojection.js.map +1 -1
  151. package/dist/utility/textures/ggxlut.js +213 -0
  152. package/dist/utility/textures/ggxlut.js.map +1 -0
  153. package/dist/utility/textures/gradientnoise.js +61 -0
  154. package/dist/utility/textures/gradientnoise.js.map +1 -0
  155. package/dist/utility/textures/randomnoise.js +41 -0
  156. package/dist/utility/textures/randomnoise.js.map +1 -0
  157. package/dist/values.js +8 -1
  158. package/dist/values.js.map +1 -1
  159. package/package.json +4 -8
  160. package/dist/animation/usertrack.js +0 -47
  161. package/dist/animation/usertrack.js.map +0 -1
  162. package/dist/material/grassmat.js +0 -127
  163. package/dist/material/grassmat.js.map +0 -1
  164. package/dist/material/lightmodel.js +0 -2074
  165. package/dist/material/lightmodel.js.map +0 -1
  166. package/dist/material/lit.js +0 -578
  167. package/dist/material/mixins/pbr/metallicroughness.js +0 -126
  168. package/dist/material/mixins/pbr/metallicroughness.js.map +0 -1
  169. package/dist/material/mixins/pbr/specularglossness.js +0 -104
  170. package/dist/material/mixins/pbr/specularglossness.js.map +0 -1
  171. package/dist/material/pbr.js +0 -27
  172. package/dist/material/pbr.js.map +0 -1
  173. package/dist/material/standard.js +0 -282
  174. package/dist/material/terrainlightmodel.js +0 -259
  175. package/dist/material/terrainmat.js +0 -357
  176. package/dist/render/depth_pass.js +0 -47
  177. package/dist/render/depth_pass.js.map +0 -1
  178. package/dist/render/forward.js +0 -186
  179. package/dist/render/forward.js.map +0 -1
  180. package/dist/render/forward_pass.js +0 -137
  181. package/dist/render/forward_pass.js.map +0 -1
  182. package/dist/render/helper.js +0 -38
  183. package/dist/render/helper.js.map +0 -1
  184. package/dist/render/objectpool.js +0 -295
  185. package/dist/render/objectpool.js.map +0 -1
  186. package/dist/render/renderscheme.js +0 -61
  187. package/dist/render/renderscheme.js.map +0 -1
  188. package/dist/render/temporalcache.js +0 -222
  189. package/dist/scene/model.js +0 -111
  190. package/dist/scene/model.js.map +0 -1
  191. package/dist/scene/octree_update_visitor.js +0 -20
  192. package/dist/scene/octree_update_visitor.js.map +0 -1
  193. package/dist/shaders/builtins.js +0 -110
  194. package/dist/shaders/builtins.js.map +0 -1
  195. package/dist/shaders/framework.js +0 -723
  196. package/dist/shaders/lighting.js +0 -335
  197. package/dist/shaders/lighting.js.map +0 -1
  198. package/dist/utility/sheenlut.js +0 -196
  199. package/dist/utility/sheenlut.js.map +0 -1
@@ -1,154 +1,134 @@
1
1
  import { Application } from '../app.js';
2
2
 
3
3
  // copy from: https://github.com/codeagent/webgl-ocean/
4
- /** @internal */ function createProgramOcean(impl) {
4
+ function getFragCoord(scope, useComputeShader) {
5
+ return useComputeShader ? scope.$builtins.globalInvocationId.xy : scope.$builtins.fragCoord.xy;
6
+ }
7
+ /** @internal */ class WaterShaderImpl {
8
+ _vertexFunc;
9
+ _shadingFunc;
10
+ _setupUniformsFunc;
11
+ constructor(setupUniformsFunc, vertexFunc, shadingFunc){
12
+ this._vertexFunc = vertexFunc;
13
+ this._shadingFunc = shadingFunc;
14
+ this._setupUniformsFunc = setupUniformsFunc;
15
+ }
16
+ setupUniforms(scope) {
17
+ this._setupUniformsFunc?.call(this, scope);
18
+ }
19
+ vertex(scope, pos, xz, waveGenerator) {
20
+ this._vertexFunc?.call(this, scope, pos, xz, waveGenerator);
21
+ }
22
+ getVertexNormal(scope, xz, useComputeShader) {
23
+ const pb = scope.$builder;
24
+ pb.func('getVertexNormal', [
25
+ pb.vec2('xz')
26
+ ], function() {
27
+ this.$l.uv0 = pb.div(this.xz, this.sizes.x);
28
+ this.$l.uv1 = pb.div(this.xz, this.sizes.y);
29
+ this.$l.uv2 = pb.div(this.xz, this.sizes.z);
30
+ if (useComputeShader) {
31
+ this.$l._sx_sz_dxdx_dzdz0 = pb.textureArraySampleLevel(this.dataTexture, this.uv0, 1, 0);
32
+ this.$l._sx_sz_dxdx_dzdz1 = pb.textureArraySampleLevel(this.dataTexture, this.uv1, 3, 0);
33
+ this.$l._sx_sz_dxdx_dzdz2 = pb.textureArraySampleLevel(this.dataTexture, this.uv2, 5, 0);
34
+ } else {
35
+ this.$l._sx_sz_dxdx_dzdz0 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz0, this.uv0, 0);
36
+ this.$l._sx_sz_dxdx_dzdz1 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz1, this.uv1, 0);
37
+ this.$l._sx_sz_dxdx_dzdz2 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz2, this.uv2, 0);
38
+ }
39
+ this.$l.sx = pb.add(this._sx_sz_dxdx_dzdz0.x, this._sx_sz_dxdx_dzdz1.x, this._sx_sz_dxdx_dzdz2.x);
40
+ this.$l.sz = pb.add(this._sx_sz_dxdx_dzdz0.y, this._sx_sz_dxdx_dzdz1.y, this._sx_sz_dxdx_dzdz2.y);
41
+ 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));
42
+ 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)));
43
+ this.$l.normal = pb.normalize(pb.vec3(pb.neg(this.slope.x), 1.0, pb.neg(this.slope.y)));
44
+ this.$return(this.normal);
45
+ });
46
+ return scope.getVertexNormal(xz);
47
+ }
48
+ shading(scope, worldPos, worldNormal, foamFactor, discardable, waveGenerator) {
49
+ return this._shadingFunc?.call(this, scope, worldPos, worldNormal, foamFactor, discardable, waveGenerator);
50
+ }
51
+ }
52
+ /** @internal */ function createProgramOcean(waveGenerator, shadingImpl) {
5
53
  return Application.instance.device.buildRenderProgram({
6
54
  vertex (pb) {
7
55
  this.$inputs.position = pb.vec3().attrib('position');
8
56
  this.$outputs.outPos = pb.vec3();
57
+ this.$outputs.outNormal = pb.vec3();
9
58
  this.$outputs.outXZ = pb.vec2();
10
- this.$outputs.uv0 = pb.vec2();
11
- this.$outputs.uv1 = pb.vec2();
12
- this.$outputs.uv2 = pb.vec2();
13
59
  this.flip = pb.int().uniform(0);
14
60
  this.viewProjMatrix = pb.mat4().uniform(0);
15
61
  this.modelMatrix = pb.mat4().uniform(1);
16
62
  this.gridScale = pb.float().uniform(1);
17
63
  this.level = pb.float().uniform(0);
18
- this.sizes = pb.vec4().uniform(0);
19
- this.croppinesses = pb.vec4().uniform(0);
20
64
  this.offset = pb.vec2().uniform(1);
21
65
  this.scale = pb.float().uniform(1);
22
- this.dx_hy_dz_dxdz0 = pb.tex2D().uniform(0);
23
- this.sx_sz_dxdx_dzdz0 = pb.tex2D().uniform(0);
24
- this.dx_hy_dz_dxdz1 = pb.tex2D().uniform(0);
25
- this.sx_sz_dxdx_dzdz1 = pb.tex2D().uniform(0);
26
- this.dx_hy_dz_dxdz2 = pb.tex2D().uniform(0);
27
- this.sx_sz_dxdx_dzdz2 = pb.tex2D().uniform(0);
28
- impl?.setupUniforms(this);
66
+ shadingImpl.setupUniforms(this);
67
+ waveGenerator.setupUniforms(this);
29
68
  pb.main(function() {
30
69
  this.$l.xz = pb.mul(pb.add(this.offset, pb.mul(pb.mul(this.modelMatrix, pb.vec4(this.$inputs.position, 1)).xy, this.scale)), this.gridScale);
31
- this.$outputs.uv0 = pb.div(this.xz, this.sizes.x);
32
- this.$outputs.uv1 = pb.div(this.xz, this.sizes.y);
33
- this.$outputs.uv2 = pb.div(this.xz, this.sizes.z);
34
- this.$l.a = pb.mul(pb.textureSampleLevel(this.dx_hy_dz_dxdz0, this.$outputs.uv0, 0).rgb, pb.vec3(this.croppinesses.x, 1, this.croppinesses.x));
35
- this.$l.b = pb.mul(pb.textureSampleLevel(this.dx_hy_dz_dxdz1, this.$outputs.uv1, 0).rgb, pb.vec3(this.croppinesses.y, 1, this.croppinesses.y));
36
- this.$l.c = pb.mul(pb.textureSampleLevel(this.dx_hy_dz_dxdz2, this.$outputs.uv2, 0).rgb, pb.vec3(this.croppinesses.z, 1, this.croppinesses.z));
37
- this.$l.displacement = pb.add(this.a, this.b, this.c);
38
- this.$outputs.outPos = pb.add(pb.vec3(this.xz.x, this.level, this.xz.y), this.displacement);
70
+ this.$l.outPos = pb.vec3();
71
+ this.$l.outNormal = pb.vec3();
72
+ waveGenerator.calcVertexPositionAndNormal(this, pb.vec3(this.xz.x, this.level, this.xz.y), this.outPos, this.outNormal);
73
+ this.$outputs.outPos = this.outPos;
74
+ this.$outputs.outNormal = this.outNormal;
39
75
  this.$outputs.outXZ = this.xz;
40
76
  this.$builtins.position = pb.mul(this.viewProjMatrix, pb.vec4(this.$outputs.outPos, 1));
41
77
  this.$if(pb.notEqual(this.flip, 0), function() {
42
78
  this.$builtins.position.y = pb.neg(this.$builtins.position.y);
43
79
  });
80
+ shadingImpl.vertex(this, this.$outputs.outPos, this.$outputs.outXZ, waveGenerator);
44
81
  });
45
82
  },
46
83
  fragment (pb) {
47
84
  this.$outputs.outColor = pb.vec4();
48
85
  this.pos = pb.vec3().uniform(0);
49
- this.regionMin = pb.vec2().uniform(0);
50
- this.regionMax = pb.vec2().uniform(0);
51
- this.foamParams = pb.vec2().uniform(0);
52
- this.sizes = pb.vec4().uniform(0);
53
- this.croppinesses = pb.vec4().uniform(0);
54
- this.dx_hy_dz_dxdz0 = pb.tex2D().uniform(0);
55
- this.sx_sz_dxdx_dzdz0 = pb.tex2D().uniform(0);
56
- this.dx_hy_dz_dxdz1 = pb.tex2D().uniform(0);
57
- this.sx_sz_dxdx_dzdz1 = pb.tex2D().uniform(0);
58
- this.dx_hy_dz_dxdz2 = pb.tex2D().uniform(0);
59
- this.sx_sz_dxdx_dzdz2 = pb.tex2D().uniform(0);
60
- impl?.setupUniforms(this);
61
- pb.func('jacobian', [
62
- pb.float('dxdx'),
63
- pb.float('dxdz'),
64
- pb.float('dzdz')
65
- ], function() {
66
- this.$l.Jxx = pb.add(this.dxdx, 1);
67
- this.$l.Jxz = this.dxdz;
68
- this.$l.Jzz = pb.add(this.dzdz, 1);
69
- this.$return(pb.vec4(this.Jxx, this.Jxz, this.Jxz, this.Jzz));
70
- });
71
- pb.func('det', [
72
- pb.vec4('jacobian')
73
- ], function() {
74
- this.$return(pb.sub(pb.mul(this.jacobian.x, this.jacobian.w), pb.mul(this.jacobian.y, this.jacobian.z)));
75
- });
76
- pb.func('getNormalAndFoam', [
77
- pb.vec2('xz')
78
- ], function() {
79
- this.$l.uv0 = pb.div(this.xz, this.sizes.x);
80
- this.$l.uv1 = pb.div(this.xz, this.sizes.y);
81
- this.$l.uv2 = pb.div(this.xz, this.sizes.z);
82
- this.$l._sx_sz_dxdx_dzdz0 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz0, this.uv0, 0);
83
- this.$l._sx_sz_dxdx_dzdz1 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz1, this.uv1, 0);
84
- this.$l._sx_sz_dxdx_dzdz2 = pb.textureSampleLevel(this.sx_sz_dxdx_dzdz2, this.uv2, 0);
85
- this.$l.sx = pb.add(this._sx_sz_dxdx_dzdz0.x, this._sx_sz_dxdx_dzdz1.x, this._sx_sz_dxdx_dzdz2.x);
86
- this.$l.sz = pb.add(this._sx_sz_dxdx_dzdz0.y, this._sx_sz_dxdx_dzdz1.y, this._sx_sz_dxdx_dzdz2.y);
87
- 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));
88
- 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)));
89
- this.$l.normal = pb.normalize(pb.vec3(pb.neg(this.slope.x), 1.0, pb.neg(this.slope.y)));
90
- // foam
91
- this.$l.dxdx_dzdz0 = this._sx_sz_dxdx_dzdz0.zw;
92
- this.$l.dxdx_dzdz1 = this._sx_sz_dxdx_dzdz1.zw;
93
- this.$l.dxdx_dzdz2 = this._sx_sz_dxdx_dzdz2.zw;
94
- this.$l.dxdz0 = pb.textureSampleLevel(this.dx_hy_dz_dxdz0, this.uv0, 0).w;
95
- this.$l.dxdz1 = pb.textureSampleLevel(this.dx_hy_dz_dxdz1, this.uv1, 0).w;
96
- this.$l.dxdz2 = pb.textureSampleLevel(this.dx_hy_dz_dxdz2, this.uv2, 0).w;
97
- 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));
98
- this.$l.val = this.det(this.jacobian(this.dxdx_dzdz.x, this.dxdz, this.dxdx_dzdz.y));
99
- this.$l.foam = pb.abs(pb.pow(pb.neg(pb.min(0, pb.sub(this.val, this.foamParams.x))), this.foamParams.y));
100
- this.$return(pb.vec4(this.normal, this.foam));
101
- });
86
+ this.region = pb.vec4().uniform(0);
87
+ shadingImpl.setupUniforms(this);
88
+ waveGenerator.setupUniforms(this);
102
89
  pb.main(function() {
103
- this.$if(pb.or(pb.any(pb.lessThan(this.$inputs.outXZ, this.regionMin)), pb.any(pb.greaterThan(this.$inputs.outXZ, this.regionMax))), function() {
104
- pb.discard();
105
- });
106
- this.$l.n = this.getNormalAndFoam(this.$inputs.outXZ);
107
- this.$outputs.outColor = impl?.shading(this, this.$inputs.outPos, this.n.xyz, this.n.w) ?? pb.vec4(pb.add(pb.mul(this.n.xyz, 0.5), pb.vec3(0.5)), 1);
108
- //this.$outputs.outColor = pb.vec4(pb.fract(this.$inputs.uv0), 0, 1);
90
+ this.$l.discardable = pb.or(pb.any(pb.lessThan(this.$inputs.outXZ, this.region.xy)), pb.any(pb.greaterThan(this.$inputs.outXZ, this.region.zw)));
91
+ this.$l.n = waveGenerator.calcFragmentNormalAndFoam(this, this.$inputs.outXZ, this.$inputs.outNormal);
92
+ this.$outputs.outColor = shadingImpl.shading(this, this.$inputs.outPos, this.n.xyz, this.n.w, this.discardable, waveGenerator) ?? pb.vec4(pb.add(pb.mul(this.n.xyz, 0.5), pb.vec3(0.5)), 1);
109
93
  });
110
94
  }
111
95
  });
112
96
  }
113
- /** @internal */ function createProgramPostFFT2(limit) {
114
- return Application.instance.device.buildRenderProgram({
115
- vertex (pb) {
116
- this.$inputs.position = pb.vec3().attrib('position');
117
- pb.main(function() {
118
- this.$builtins.position = pb.vec4(this.$inputs.position, 1);
119
- });
120
- },
121
- fragment (pb) {
122
- if (!limit || limit === 4) {
123
- this.$outputs.dx_hy_dz_dxdz0 = pb.vec4();
124
- this.$outputs.sx_sz_dxdx_dzdz0 = pb.vec4();
125
- this.$outputs.dx_hy_dz_dxdz1 = pb.vec4();
126
- this.$outputs.sx_sz_dxdx_dzdz1 = pb.vec4();
127
- }
128
- if (!limit || limit === 2) {
129
- this.$outputs.dx_hy_dz_dxdz2 = pb.vec4();
130
- this.$outputs.sx_sz_dxdx_dzdz2 = pb.vec4();
131
- }
97
+ /** @internal */ function createProgramPostFFT2(useComputeShader = false, threadGroupSize, targetFormat = 'rgba32f', limit) {
98
+ function getComputeFunc(useComputeShader, fmt) {
99
+ return function(pb) {
132
100
  this.N2 = pb.float().uniform(0);
133
- if (!limit || limit === 4) {
134
- this.ifft0 = pb.tex2D().uniform(0);
135
- this.ifft1 = pb.tex2D().uniform(0);
136
- this.ifft2 = pb.tex2D().uniform(0);
137
- this.ifft3 = pb.tex2D().uniform(0);
138
- }
139
- if (!limit || limit === 2) {
140
- this.ifft4 = pb.tex2D().uniform(0);
141
- this.ifft5 = pb.tex2D().uniform(0);
101
+ if (useComputeShader) {
102
+ this.output = fmt === 'rgba32f' ? pb.texStorage2DArray.rgba32float().storage(0) : pb.texStorage2DArray.rgba16float().storage(0);
103
+ this.ifft = pb.tex2DArray().uniform(0);
104
+ } else {
105
+ if (!limit || limit === 4) {
106
+ this.$outputs.dx_hy_dz_dxdz0 = pb.vec4();
107
+ this.$outputs.sx_sz_dxdx_dzdz0 = pb.vec4();
108
+ this.$outputs.dx_hy_dz_dxdz1 = pb.vec4();
109
+ this.$outputs.sx_sz_dxdx_dzdz1 = pb.vec4();
110
+ this.ifft0 = pb.tex2D().uniform(0);
111
+ this.ifft1 = pb.tex2D().uniform(0);
112
+ this.ifft2 = pb.tex2D().uniform(0);
113
+ this.ifft3 = pb.tex2D().uniform(0);
114
+ }
115
+ if (!limit || limit === 2) {
116
+ this.$outputs.dx_hy_dz_dxdz2 = pb.vec4();
117
+ this.$outputs.sx_sz_dxdx_dzdz2 = pb.vec4();
118
+ this.ifft4 = pb.tex2D().uniform(0);
119
+ this.ifft5 = pb.tex2D().uniform(0);
120
+ }
142
121
  }
143
122
  if (pb.getDevice().type === 'webgl') {
144
123
  this.ifftTexSize = pb.vec2().uniform(0);
145
124
  }
146
125
  pb.main(function() {
147
- this.$l.p = pb.float(pb.add(this.$builtins.fragCoord.x, this.$builtins.fragCoord.y));
126
+ this.$l.fragPos = getFragCoord(this, useComputeShader);
127
+ this.$l.p = pb.float(pb.add(this.fragPos.x, this.fragPos.y));
148
128
  this.$l.s = pb.sub(pb.mul(pb.sub(1, pb.mod(this.p, 2)), 2), 1);
149
129
  this.$l.m = pb.mul(this.s, this.N2);
150
130
  if (pb.getDevice().type === 'webgl') {
151
- this.$l.uv = pb.div(pb.vec2(this.$builtins.fragCoord.xy), this.ifftTexSize);
131
+ this.$l.uv = pb.div(pb.vec2(this.fragPos), this.ifftTexSize);
152
132
  if (!limit || limit === 4) {
153
133
  this.$outputs.dx_hy_dz_dxdz0 = pb.mul(pb.textureSampleLevel(this.ifft0, this.uv, 0), this.m);
154
134
  this.$outputs.sx_sz_dxdx_dzdz0 = pb.mul(pb.textureSampleLevel(this.ifft1, this.uv, 0), this.m);
@@ -159,8 +139,13 @@ import { Application } from '../app.js';
159
139
  this.$outputs.dx_hy_dz_dxdz2 = pb.mul(pb.textureSampleLevel(this.ifft4, this.uv, 0), this.m);
160
140
  this.$outputs.sx_sz_dxdx_dzdz2 = pb.mul(pb.textureSampleLevel(this.ifft5, this.uv, 0), this.m);
161
141
  }
142
+ } else if (useComputeShader) {
143
+ this.$l.uv = pb.ivec2(this.fragPos);
144
+ for(let i = 0; i < 6; i++){
145
+ pb.textureArrayStore(this.output, this.$builtins.globalInvocationId.xy, i, pb.mul(pb.textureArrayLoad(this.ifft, this.uv, i, 0), this.m));
146
+ }
162
147
  } else {
163
- this.$l.uv = pb.ivec2(this.$builtins.fragCoord.xy);
148
+ this.$l.uv = pb.ivec2(this.fragPos);
164
149
  if (!limit || limit === 4) {
165
150
  this.$outputs.dx_hy_dz_dxdz0 = pb.mul(pb.textureLoad(this.ifft0, this.uv, 0), this.m);
166
151
  this.$outputs.sx_sz_dxdx_dzdz0 = pb.mul(pb.textureLoad(this.ifft1, this.uv, 0), this.m);
@@ -173,37 +158,59 @@ import { Application } from '../app.js';
173
158
  }
174
159
  }
175
160
  });
176
- }
177
- });
161
+ };
162
+ }
163
+ if (useComputeShader) {
164
+ return Application.instance.device.buildComputeProgram({
165
+ workgroupSize: [
166
+ threadGroupSize,
167
+ threadGroupSize,
168
+ 1
169
+ ],
170
+ compute: getComputeFunc(useComputeShader, targetFormat)
171
+ });
172
+ } else {
173
+ return Application.instance.device.buildRenderProgram({
174
+ vertex (pb) {
175
+ this.$inputs.position = pb.vec3().attrib('position');
176
+ pb.main(function() {
177
+ this.$builtins.position = pb.vec4(this.$inputs.position, 1);
178
+ });
179
+ },
180
+ fragment: getComputeFunc(useComputeShader, targetFormat)
181
+ });
182
+ }
178
183
  }
179
- /** @internal */ function createProgramHk(limit) {
180
- return Application.instance.device.buildRenderProgram({
181
- vertex (pb) {
182
- this.$inputs.position = pb.vec3().attrib('position');
183
- pb.main(function() {
184
- this.$builtins.position = pb.vec4(this.$inputs.position, 1);
185
- });
186
- },
187
- fragment (pb) {
188
- if (!limit || limit === 4) {
189
- this.$outputs.spectrum0 = pb.vec4();
190
- this.$outputs.spectrum1 = pb.vec4();
191
- this.$outputs.spectrum2 = pb.vec4();
192
- this.$outputs.spectrum3 = pb.vec4();
193
- }
194
- if (!limit || limit === 2) {
195
- this.$outputs.spectrum4 = pb.vec4();
196
- this.$outputs.spectrum5 = pb.vec4();
184
+ /** @internal */ function createProgramHk(useComputeShader = false, threadGroupSize = 8, targetFormat = 'rgba32f', limit) {
185
+ function getComputeFunc(useComputeShader = false, fmt) {
186
+ return function(pb) {
187
+ if (useComputeShader) {
188
+ this.spectrum = fmt === 'rgba32f' ? pb.texStorage2DArray.rgba32float().storage(0) : pb.texStorage2DArray.rgba16float().storage(0);
189
+ } else {
190
+ if (!limit || limit === 4) {
191
+ this.$outputs.spectrum0 = pb.vec4();
192
+ this.$outputs.spectrum1 = pb.vec4();
193
+ this.$outputs.spectrum2 = pb.vec4();
194
+ this.$outputs.spectrum3 = pb.vec4();
195
+ }
196
+ if (!limit || limit === 2) {
197
+ this.$outputs.spectrum4 = pb.vec4();
198
+ this.$outputs.spectrum5 = pb.vec4();
199
+ }
197
200
  }
198
201
  this.resolution = pb.int().uniform(0);
199
202
  this.sizes = pb.vec4().uniform(0);
200
203
  this.t = pb.float().uniform(0);
201
- if (!limit || limit === 4) {
202
- this.h0Texture0 = pb.tex2D().uniform(0);
203
- this.h0Texture1 = pb.tex2D().uniform(0);
204
- }
205
- if (!limit || limit === 2) {
206
- this.h0Texture2 = pb.tex2D().uniform(0);
204
+ if (useComputeShader) {
205
+ this.h0Texture = pb.tex2DArray().uniform(0);
206
+ } else {
207
+ if (!limit || limit === 4) {
208
+ this.h0Texture0 = pb.tex2D().uniform(0);
209
+ this.h0Texture1 = pb.tex2D().uniform(0);
210
+ }
211
+ if (!limit || limit === 2) {
212
+ this.h0Texture2 = pb.tex2D().uniform(0);
213
+ }
207
214
  }
208
215
  if (pb.getDevice().type === 'webgl') {
209
216
  this.h0TexSize = pb.vec2().uniform(0);
@@ -286,6 +293,8 @@ import { Application } from '../app.js';
286
293
  this.$l.w = pb.sqrt(pb.mul(this.kLen, this.g));
287
294
  if (pb.getDevice().type === 'webgl') {
288
295
  this.$l.h0Texel = pb.textureSampleLevel(this[`h0Texture${x}`], pb.div(pb.vec2(this.fragCoord), this.h0TexSize), 0);
296
+ } else if (useComputeShader) {
297
+ this.$l.h0Texel = pb.textureArrayLoad(this.h0Texture, this.fragCoord, x, 0);
289
298
  } else {
290
299
  this.$l.h0Texel = pb.textureLoad(this[`h0Texture${x}`], this.fragCoord, 0);
291
300
  }
@@ -324,46 +333,76 @@ import { Application } from '../app.js';
324
333
  this.part1 = pb.vec4(this.sx_sz.re, this.sx_sz.im, this.dxdx_dzdz.re, this.dxdx_dzdz.im);
325
334
  });
326
335
  pb.main(function() {
327
- this.fragXY = pb.ivec2(this.$builtins.fragCoord.xy);
336
+ this.fragXY = pb.ivec2(getFragCoord(this, useComputeShader));
328
337
  this.$l.x = pb.vec2(pb.sub(this.fragXY, pb.ivec2(pb.div(this.resolution, 2))));
329
- if (!limit || limit === 4) {
330
- this.$l.spectrum0 = pb.vec4();
331
- this.$l.spectrum1 = pb.vec4();
332
- this.$l.spectrum2 = pb.vec4();
333
- this.$l.spectrum3 = pb.vec4();
338
+ if (useComputeShader || !limit || limit === 4) {
339
+ this.$l.s0 = pb.vec4();
340
+ this.$l.s1 = pb.vec4();
341
+ this.$l.s2 = pb.vec4();
342
+ this.$l.s3 = pb.vec4();
334
343
  this.$l.spec0 = this.getSpectrum0(this.x, this.sizes.x, this.fragXY);
335
344
  this.$l.spec1 = this.getSpectrum1(this.x, this.sizes.y, this.fragXY);
336
- this.compressSpectrum(this.spec0, this.spectrum0, this.spectrum1);
337
- this.compressSpectrum(this.spec1, this.spectrum2, this.spectrum3);
338
- this.$outputs.spectrum0 = this.spectrum0;
339
- this.$outputs.spectrum1 = this.spectrum1;
340
- this.$outputs.spectrum2 = this.spectrum2;
341
- this.$outputs.spectrum3 = this.spectrum3;
345
+ this.compressSpectrum(this.spec0, this.s0, this.s1);
346
+ this.compressSpectrum(this.spec1, this.s2, this.s3);
347
+ if (useComputeShader) {
348
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 0, this.s0);
349
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 1, this.s1);
350
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 2, this.s2);
351
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 3, this.s3);
352
+ } else {
353
+ this.$outputs.spectrum0 = this.s0;
354
+ this.$outputs.spectrum1 = this.s1;
355
+ this.$outputs.spectrum2 = this.s2;
356
+ this.$outputs.spectrum3 = this.s3;
357
+ }
342
358
  }
343
- if (!limit || limit === 2) {
344
- this.$l.spectrum4 = pb.vec4();
345
- this.$l.spectrum5 = pb.vec4();
359
+ if (useComputeShader || !limit || limit === 2) {
360
+ this.$l.s4 = pb.vec4();
361
+ this.$l.s5 = pb.vec4();
346
362
  this.$l.spec2 = this.getSpectrum2(this.x, this.sizes.z, this.fragXY);
347
- this.compressSpectrum(this.spec2, this.spectrum4, this.spectrum5);
348
- this.$outputs.spectrum4 = this.spectrum4;
349
- this.$outputs.spectrum5 = this.spectrum5;
363
+ this.compressSpectrum(this.spec2, this.s4, this.s5);
364
+ if (useComputeShader) {
365
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 4, this.s4);
366
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 5, this.s5);
367
+ } else {
368
+ this.$outputs.spectrum4 = this.s4;
369
+ this.$outputs.spectrum5 = this.s5;
370
+ }
350
371
  }
351
372
  });
352
- }
353
- });
373
+ };
374
+ }
375
+ if (useComputeShader) {
376
+ return Application.instance.device.buildComputeProgram({
377
+ workgroupSize: [
378
+ threadGroupSize,
379
+ threadGroupSize,
380
+ 1
381
+ ],
382
+ compute: getComputeFunc(useComputeShader, targetFormat)
383
+ });
384
+ } else {
385
+ return Application.instance.device.buildRenderProgram({
386
+ vertex (pb) {
387
+ this.$inputs.position = pb.vec3().attrib('position');
388
+ pb.main(function() {
389
+ this.$builtins.position = pb.vec4(this.$inputs.position, 1);
390
+ });
391
+ },
392
+ fragment: getComputeFunc(useComputeShader, targetFormat)
393
+ });
394
+ }
354
395
  }
355
- /** @internal */ function createProgramH0() {
356
- return Application.instance.device.buildRenderProgram({
357
- vertex (pb) {
358
- this.$inputs.position = pb.vec3().attrib('position');
359
- pb.main(function() {
360
- this.$builtins.position = pb.vec4(this.$inputs.position, 1);
361
- });
362
- },
363
- fragment (pb) {
364
- this.$outputs.spectrum0 = pb.vec4();
365
- this.$outputs.spectrum1 = pb.vec4();
366
- this.$outputs.spectrum2 = pb.vec4();
396
+ /** @internal */ function createProgramH0(useComputeShader = false, threadGroupSize = 8, targetFormat = 'rgba32f') {
397
+ function getComputeFunc(useComputeShader = false, fmt) {
398
+ return function(pb) {
399
+ if (useComputeShader) {
400
+ this.spectrum = fmt === 'rgba32f' ? pb.texStorage2DArray.rgba32float().storage(0) : pb.texStorage2DArray.rgba16float().storage(0);
401
+ } else {
402
+ this.$outputs.spectrum0 = pb.vec4();
403
+ this.$outputs.spectrum1 = pb.vec4();
404
+ this.$outputs.spectrum2 = pb.vec4();
405
+ }
367
406
  this.noise = pb.tex2D().uniform(0);
368
407
  this.resolution = pb.int().uniform(0);
369
408
  this.wind = pb.vec2().uniform(0);
@@ -405,40 +444,65 @@ import { Application } from '../app.js';
405
444
  this.$return(pb.sqrt(pb.vec4(this.h0k, this.h0k, this.h0mk, this.h0mk)));
406
445
  });
407
446
  pb.main(function() {
408
- this.$l.x = pb.vec2(pb.sub(pb.ivec2(this.$builtins.fragCoord.xy), pb.ivec2(pb.div(this.resolution, 2))));
447
+ this.$l.x = pb.vec2(pb.sub(pb.ivec2(getFragCoord(this, useComputeShader)), pb.ivec2(pb.div(this.resolution, 2))));
409
448
  this.$l.k = pb.mul(pb.vec2(Math.PI * 2), this.x);
410
- this.$l.rnd = this.gauss(pb.ivec2(this.$builtins.fragCoord.xy));
411
- this.$outputs.spectrum0 = pb.mul(this.phillips(pb.div(this.k, this.cascade0.x), this.cascade0.y, this.cascade0.z, this.cascade0.w), this.rnd);
412
- this.$outputs.spectrum1 = pb.mul(this.phillips(pb.div(this.k, this.cascade1.x), this.cascade1.y, this.cascade1.z, this.cascade1.w), this.rnd);
413
- this.$outputs.spectrum2 = pb.mul(this.phillips(pb.div(this.k, this.cascade2.x), this.cascade2.y, this.cascade2.z, this.cascade2.w), this.rnd);
449
+ this.$l.rnd = this.gauss(pb.ivec2(getFragCoord(this, useComputeShader)));
450
+ if (useComputeShader) {
451
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 0, pb.mul(this.phillips(pb.div(this.k, this.cascade0.x), this.cascade0.y, this.cascade0.z, this.cascade0.w), this.rnd));
452
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 1, pb.mul(this.phillips(pb.div(this.k, this.cascade1.x), this.cascade1.y, this.cascade1.z, this.cascade1.w), this.rnd));
453
+ pb.textureArrayStore(this.spectrum, this.$builtins.globalInvocationId.xy, 2, pb.mul(this.phillips(pb.div(this.k, this.cascade2.x), this.cascade2.y, this.cascade2.z, this.cascade2.w), this.rnd));
454
+ } else {
455
+ this.$outputs.spectrum0 = pb.mul(this.phillips(pb.div(this.k, this.cascade0.x), this.cascade0.y, this.cascade0.z, this.cascade0.w), this.rnd);
456
+ this.$outputs.spectrum1 = pb.mul(this.phillips(pb.div(this.k, this.cascade1.x), this.cascade1.y, this.cascade1.z, this.cascade1.w), this.rnd);
457
+ this.$outputs.spectrum2 = pb.mul(this.phillips(pb.div(this.k, this.cascade2.x), this.cascade2.y, this.cascade2.z, this.cascade2.w), this.rnd);
458
+ }
414
459
  });
415
- }
416
- });
460
+ };
461
+ }
462
+ if (useComputeShader) {
463
+ return Application.instance.device.buildComputeProgram({
464
+ workgroupSize: [
465
+ threadGroupSize,
466
+ threadGroupSize,
467
+ 1
468
+ ],
469
+ compute: getComputeFunc(useComputeShader, targetFormat)
470
+ });
471
+ } else {
472
+ return Application.instance.device.buildRenderProgram({
473
+ vertex (pb) {
474
+ this.$inputs.position = pb.vec3().attrib('position');
475
+ pb.main(function() {
476
+ this.$builtins.position = pb.vec4(this.$inputs.position, 1);
477
+ });
478
+ },
479
+ fragment: getComputeFunc(useComputeShader, targetFormat)
480
+ });
481
+ }
417
482
  }
418
- /** @internal */ function createProgramFFT2V(limit) {
419
- return Application.instance.device.buildRenderProgram({
420
- vertex (pb) {
421
- this.$inputs.position = pb.vec3().attrib('position');
422
- pb.main(function() {
423
- this.$builtins.position = pb.vec4(this.$inputs.position, 1);
424
- });
425
- },
426
- fragment (pb) {
427
- if (!limit || limit === 4) {
428
- this.$outputs.ifft0 = pb.vec4();
429
- this.$outputs.ifft1 = pb.vec4();
430
- this.$outputs.ifft2 = pb.vec4();
431
- this.$outputs.ifft3 = pb.vec4();
432
- this.spectrum0 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
433
- this.spectrum1 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
434
- this.spectrum2 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
435
- this.spectrum3 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
436
- }
437
- if (!limit || limit === 2) {
438
- this.$outputs.ifft4 = pb.vec4();
439
- this.$outputs.ifft5 = pb.vec4();
440
- this.spectrum4 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
441
- this.spectrum5 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
483
+ /** @internal */ function createProgramFFT2V(useComputeShader = false, threadGroupSize, targetFormat = 'rgba32f', limit) {
484
+ function getComputeFunc(useComputeShader, fmt) {
485
+ return function(pb) {
486
+ if (useComputeShader) {
487
+ this.spectrum = pb.tex2DArray().sampleType('unfilterable-float').uniform(0);
488
+ this.ifft = fmt === 'rgba32f' ? pb.texStorage2DArray.rgba32float().storage(0) : pb.texStorage2DArray.rgba16float().storage(0);
489
+ } else {
490
+ if (!limit || limit === 4) {
491
+ this.$outputs.ifft0 = pb.vec4();
492
+ this.$outputs.ifft1 = pb.vec4();
493
+ this.$outputs.ifft2 = pb.vec4();
494
+ this.$outputs.ifft3 = pb.vec4();
495
+ this.spectrum0 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
496
+ this.spectrum1 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
497
+ this.spectrum2 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
498
+ this.spectrum3 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
499
+ }
500
+ if (!limit || limit === 2) {
501
+ this.$outputs.ifft4 = pb.vec4();
502
+ this.$outputs.ifft5 = pb.vec4();
503
+ this.spectrum4 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
504
+ this.spectrum5 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
505
+ }
442
506
  }
443
507
  this.butterfly = pb.tex2D().sampleType('unfilterable-float').uniform(0);
444
508
  if (pb.getDevice().type === 'webgl') {
@@ -481,6 +545,9 @@ import { Application } from '../app.js';
481
545
  if (pb.getDevice().type === 'webgl') {
482
546
  this.$l.texelA = pb.textureSampleLevel(this[`spectrum${x}`], pb.div(pb.vec2(pb.float(this.x), this.texelButt.b), this.texSize.xy), 0);
483
547
  this.$l.texelB = pb.textureSampleLevel(this[`spectrum${x}`], pb.div(pb.vec2(pb.float(this.x), this.texelButt.a), this.texSize.xy), 0);
548
+ } else if (useComputeShader) {
549
+ this.$l.texelA = pb.textureArrayLoad(this.spectrum, pb.ivec2(this.x, pb.int(this.texelButt.b)), x, 0);
550
+ this.$l.texelB = pb.textureArrayLoad(this.spectrum, pb.ivec2(this.x, pb.int(this.texelButt.a)), x, 0);
484
551
  } else {
485
552
  this.$l.texelA = pb.textureLoad(this[`spectrum${x}`], pb.ivec2(this.x, pb.int(this.texelButt.b)), 0);
486
553
  this.$l.texelB = pb.textureLoad(this[`spectrum${x}`], pb.ivec2(this.x, pb.int(this.texelButt.a)), 0);
@@ -496,51 +563,79 @@ import { Application } from '../app.js';
496
563
  });
497
564
  }
498
565
  pb.main(function() {
499
- this.$l.x = pb.int(this.$builtins.fragCoord.x);
500
- this.$l.y = pb.int(this.$builtins.fragCoord.y);
566
+ this.$l.x = pb.int(getFragCoord(this, useComputeShader).x);
567
+ this.$l.y = pb.int(getFragCoord(this, useComputeShader).y);
501
568
  if (pb.getDevice().type === 'webgl') {
502
569
  this.$l.texelButt = pb.textureSampleLevel(this.butterfly, pb.div(pb.vec2(pb.float(this.phase), pb.float(this.y)), this.texSize.zw), 0);
503
570
  } else {
504
571
  this.$l.texelButt = pb.textureLoad(this.butterfly, pb.ivec2(this.phase, this.y), 0);
505
572
  }
573
+ if (useComputeShader) {
574
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 0, this.twiddle0(this.texelButt, this.x));
575
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 1, this.twiddle1(this.texelButt, this.x));
576
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 2, this.twiddle2(this.texelButt, this.x));
577
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 3, this.twiddle3(this.texelButt, this.x));
578
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 4, this.twiddle4(this.texelButt, this.x));
579
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 5, this.twiddle5(this.texelButt, this.x));
580
+ } else {
581
+ if (!limit || limit === 4) {
582
+ this.$outputs.ifft0 = this.twiddle0(this.texelButt, this.x);
583
+ this.$outputs.ifft1 = this.twiddle1(this.texelButt, this.x);
584
+ this.$outputs.ifft2 = this.twiddle2(this.texelButt, this.x);
585
+ this.$outputs.ifft3 = this.twiddle3(this.texelButt, this.x);
586
+ }
587
+ if (!limit || limit === 2) {
588
+ this.$outputs.ifft4 = this.twiddle4(this.texelButt, this.x);
589
+ this.$outputs.ifft5 = this.twiddle5(this.texelButt, this.x);
590
+ }
591
+ }
592
+ });
593
+ };
594
+ }
595
+ if (useComputeShader) {
596
+ return Application.instance.device.buildComputeProgram({
597
+ workgroupSize: [
598
+ threadGroupSize,
599
+ threadGroupSize,
600
+ 1
601
+ ],
602
+ compute: getComputeFunc(useComputeShader, targetFormat)
603
+ });
604
+ } else {
605
+ return Application.instance.device.buildRenderProgram({
606
+ vertex (pb) {
607
+ this.$inputs.position = pb.vec3().attrib('position');
608
+ pb.main(function() {
609
+ this.$builtins.position = pb.vec4(this.$inputs.position, 1);
610
+ });
611
+ },
612
+ fragment: getComputeFunc(useComputeShader, targetFormat)
613
+ });
614
+ }
615
+ }
616
+ /** @internal */ function createProgramFFT2H(useComputeShader = false, threadGroupSize, targetFormat = 'rgba32f', limit) {
617
+ function getComputeFunc(useComputeShader, fmt) {
618
+ return function(pb) {
619
+ if (useComputeShader) {
620
+ this.spectrum = pb.tex2DArray().sampleType('unfilterable-float').uniform(0);
621
+ this.ifft = fmt === 'rgba32f' ? pb.texStorage2DArray.rgba32float().storage(0) : pb.texStorage2DArray.rgba16float().storage(0);
622
+ } else {
506
623
  if (!limit || limit === 4) {
507
- this.$outputs.ifft0 = this.twiddle0(this.texelButt, this.x);
508
- this.$outputs.ifft1 = this.twiddle1(this.texelButt, this.x);
509
- this.$outputs.ifft2 = this.twiddle2(this.texelButt, this.x);
510
- this.$outputs.ifft3 = this.twiddle3(this.texelButt, this.x);
624
+ this.$outputs.ifft0 = pb.vec4();
625
+ this.$outputs.ifft1 = pb.vec4();
626
+ this.$outputs.ifft2 = pb.vec4();
627
+ this.$outputs.ifft3 = pb.vec4();
628
+ this.spectrum0 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
629
+ this.spectrum1 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
630
+ this.spectrum2 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
631
+ this.spectrum3 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
511
632
  }
512
633
  if (!limit || limit === 2) {
513
- this.$outputs.ifft4 = this.twiddle4(this.texelButt, this.x);
514
- this.$outputs.ifft5 = this.twiddle5(this.texelButt, this.x);
634
+ this.$outputs.ifft4 = pb.vec4();
635
+ this.$outputs.ifft5 = pb.vec4();
636
+ this.spectrum4 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
637
+ this.spectrum5 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
515
638
  }
516
- });
517
- }
518
- });
519
- }
520
- /** @internal */ function createProgramFFT2H(limit) {
521
- return Application.instance.device.buildRenderProgram({
522
- vertex (pb) {
523
- this.$inputs.position = pb.vec3().attrib('position');
524
- pb.main(function() {
525
- this.$builtins.position = pb.vec4(this.$inputs.position, 1);
526
- });
527
- },
528
- fragment (pb) {
529
- if (!limit || limit === 4) {
530
- this.$outputs.ifft0 = pb.vec4();
531
- this.$outputs.ifft1 = pb.vec4();
532
- this.$outputs.ifft2 = pb.vec4();
533
- this.$outputs.ifft3 = pb.vec4();
534
- this.spectrum0 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
535
- this.spectrum1 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
536
- this.spectrum2 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
537
- this.spectrum3 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
538
- }
539
- if (!limit || limit === 2) {
540
- this.$outputs.ifft4 = pb.vec4();
541
- this.$outputs.ifft5 = pb.vec4();
542
- this.spectrum4 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
543
- this.spectrum5 = pb.tex2D().sampleType('unfilterable-float').uniform(0);
544
639
  }
545
640
  this.butterfly = pb.tex2D().sampleType('unfilterable-float').uniform(0);
546
641
  this.phase = pb.int().uniform(0);
@@ -583,6 +678,9 @@ import { Application } from '../app.js';
583
678
  if (pb.getDevice().type === 'webgl') {
584
679
  this.$l.texelA = pb.textureSampleLevel(this[`spectrum${x}`], pb.div(pb.vec2(this.texelButt.b, pb.float(this.y)), this.texSize.xy), 0);
585
680
  this.$l.texelB = pb.textureSampleLevel(this[`spectrum${x}`], pb.div(pb.vec2(this.texelButt.a, pb.float(this.y)), this.texSize.xy), 0);
681
+ } else if (useComputeShader) {
682
+ this.$l.texelA = pb.textureArrayLoad(this.spectrum, pb.ivec2(pb.int(this.texelButt.b), this.y), x, 0);
683
+ this.$l.texelB = pb.textureArrayLoad(this.spectrum, pb.ivec2(pb.int(this.texelButt.a), this.y), x, 0);
586
684
  } else {
587
685
  this.$l.texelA = pb.textureLoad(this[`spectrum${x}`], pb.ivec2(pb.int(this.texelButt.b), this.y), 0);
588
686
  this.$l.texelB = pb.textureLoad(this[`spectrum${x}`], pb.ivec2(pb.int(this.texelButt.a), this.y), 0);
@@ -598,27 +696,56 @@ import { Application } from '../app.js';
598
696
  });
599
697
  }
600
698
  pb.main(function() {
601
- this.$l.x = pb.int(this.$builtins.fragCoord.x);
602
- this.$l.y = pb.int(this.$builtins.fragCoord.y);
699
+ this.$l.x = pb.int(getFragCoord(this, useComputeShader).x);
700
+ this.$l.y = pb.int(getFragCoord(this, useComputeShader).y);
603
701
  if (pb.getDevice().type === 'webgl') {
604
702
  this.$l.texelButt = pb.textureSampleLevel(this.butterfly, pb.div(pb.vec2(pb.float(this.phase), pb.float(this.x)), this.texSize.zw), 0);
605
703
  } else {
606
704
  this.$l.texelButt = pb.textureLoad(this.butterfly, pb.ivec2(this.phase, this.x), 0);
607
705
  }
608
- if (!limit || limit === 4) {
609
- this.$outputs.ifft0 = this.twiddle0(this.texelButt, this.y);
610
- this.$outputs.ifft1 = this.twiddle1(this.texelButt, this.y);
611
- this.$outputs.ifft2 = this.twiddle2(this.texelButt, this.y);
612
- this.$outputs.ifft3 = this.twiddle3(this.texelButt, this.y);
613
- }
614
- if (!limit || limit === 2) {
615
- this.$outputs.ifft4 = this.twiddle4(this.texelButt, this.y);
616
- this.$outputs.ifft5 = this.twiddle5(this.texelButt, this.y);
706
+ if (useComputeShader) {
707
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 0, this.twiddle0(this.texelButt, this.y));
708
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 1, this.twiddle1(this.texelButt, this.y));
709
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 2, this.twiddle2(this.texelButt, this.y));
710
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 3, this.twiddle3(this.texelButt, this.y));
711
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 4, this.twiddle4(this.texelButt, this.y));
712
+ pb.textureArrayStore(this.ifft, this.$builtins.globalInvocationId.xy, 5, this.twiddle5(this.texelButt, this.y));
713
+ } else {
714
+ if (!limit || limit === 4) {
715
+ this.$outputs.ifft0 = this.twiddle0(this.texelButt, this.y);
716
+ this.$outputs.ifft1 = this.twiddle1(this.texelButt, this.y);
717
+ this.$outputs.ifft2 = this.twiddle2(this.texelButt, this.y);
718
+ this.$outputs.ifft3 = this.twiddle3(this.texelButt, this.y);
719
+ }
720
+ if (!limit || limit === 2) {
721
+ this.$outputs.ifft4 = this.twiddle4(this.texelButt, this.y);
722
+ this.$outputs.ifft5 = this.twiddle5(this.texelButt, this.y);
723
+ }
617
724
  }
618
725
  });
619
- }
620
- });
726
+ };
727
+ }
728
+ if (useComputeShader) {
729
+ return Application.instance.device.buildComputeProgram({
730
+ workgroupSize: [
731
+ threadGroupSize,
732
+ threadGroupSize,
733
+ 1
734
+ ],
735
+ compute: getComputeFunc(useComputeShader, targetFormat)
736
+ });
737
+ } else {
738
+ return Application.instance.device.buildRenderProgram({
739
+ vertex (pb) {
740
+ this.$inputs.position = pb.vec3().attrib('position');
741
+ pb.main(function() {
742
+ this.$builtins.position = pb.vec4(this.$inputs.position, 1);
743
+ });
744
+ },
745
+ fragment: getComputeFunc(useComputeShader, targetFormat)
746
+ });
747
+ }
621
748
  }
622
749
 
623
- export { createProgramFFT2H, createProgramFFT2V, createProgramH0, createProgramHk, createProgramOcean, createProgramPostFFT2 };
750
+ export { WaterShaderImpl, createProgramFFT2H, createProgramFFT2V, createProgramH0, createProgramHk, createProgramOcean, createProgramPostFFT2 };
624
751
  //# sourceMappingURL=water.js.map