@zephyr3d/scene 0.3.0 → 0.4.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 (100) hide show
  1. package/dist/asset/assetmanager.js +1 -1
  2. package/dist/asset/loaders/gltf/gltf_loader.js +4 -8
  3. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  4. package/dist/camera/camera.js +25 -2
  5. package/dist/camera/camera.js.map +1 -1
  6. package/dist/index.d.ts +4641 -4371
  7. package/dist/index.js +4 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/material/grassmaterial.js +15 -0
  10. package/dist/material/grassmaterial.js.map +1 -1
  11. package/dist/material/material.js +79 -347
  12. package/dist/material/material.js.map +1 -1
  13. package/dist/material/meshmaterial.js +88 -100
  14. package/dist/material/meshmaterial.js.map +1 -1
  15. package/dist/material/mixins/albedocolor.js +11 -3
  16. package/dist/material/mixins/albedocolor.js.map +1 -1
  17. package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
  18. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +8 -1
  19. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  20. package/dist/material/mixins/pbr/common.js +2 -0
  21. package/dist/material/mixins/pbr/common.js.map +1 -1
  22. package/dist/material/mixins/vertexcolor.js +2 -0
  23. package/dist/material/mixins/vertexcolor.js.map +1 -1
  24. package/dist/material/pbrmr.js +1 -1
  25. package/dist/material/pbrsg.js +9 -4
  26. package/dist/material/pbrsg.js.map +1 -1
  27. package/dist/material/shader/helper.js +94 -115
  28. package/dist/material/shader/helper.js.map +1 -1
  29. package/dist/material/terrainmaterial.js +16 -0
  30. package/dist/material/terrainmaterial.js.map +1 -1
  31. package/dist/posteffect/bloom.js +3 -4
  32. package/dist/posteffect/bloom.js.map +1 -1
  33. package/dist/posteffect/compositor.js +5 -6
  34. package/dist/posteffect/compositor.js.map +1 -1
  35. package/dist/posteffect/fxaa.js +1 -2
  36. package/dist/posteffect/fxaa.js.map +1 -1
  37. package/dist/posteffect/grayscale.js +1 -2
  38. package/dist/posteffect/grayscale.js.map +1 -1
  39. package/dist/posteffect/posteffect.js +0 -74
  40. package/dist/posteffect/posteffect.js.map +1 -1
  41. package/dist/posteffect/sao.js +2 -5
  42. package/dist/posteffect/sao.js.map +1 -1
  43. package/dist/posteffect/tonemap.js +1 -2
  44. package/dist/posteffect/tonemap.js.map +1 -1
  45. package/dist/posteffect/water.js +18 -14
  46. package/dist/posteffect/water.js.map +1 -1
  47. package/dist/render/abuffer_oit.js +352 -0
  48. package/dist/render/abuffer_oit.js.map +1 -0
  49. package/dist/render/depthpass.js +10 -13
  50. package/dist/render/depthpass.js.map +1 -1
  51. package/dist/render/drawable_mixin.js +110 -0
  52. package/dist/render/drawable_mixin.js.map +1 -0
  53. package/dist/render/globalbindgroup_allocator.js +58 -0
  54. package/dist/render/globalbindgroup_allocator.js.map +1 -0
  55. package/dist/render/lightpass.js +69 -43
  56. package/dist/render/lightpass.js.map +1 -1
  57. package/dist/render/oit.js +16 -0
  58. package/dist/render/oit.js.map +1 -0
  59. package/dist/render/render_queue.js +250 -96
  60. package/dist/render/render_queue.js.map +1 -1
  61. package/dist/render/renderbundle_wrapper.js +20 -0
  62. package/dist/render/renderbundle_wrapper.js.map +1 -0
  63. package/dist/render/renderer.js +12 -9
  64. package/dist/render/renderer.js.map +1 -1
  65. package/dist/render/renderpass.js +92 -34
  66. package/dist/render/renderpass.js.map +1 -1
  67. package/dist/render/shadowmap_pass.js +12 -31
  68. package/dist/render/shadowmap_pass.js.map +1 -1
  69. package/dist/render/sky.js +2 -2
  70. package/dist/render/watermesh.js +140 -48
  71. package/dist/render/watermesh.js.map +1 -1
  72. package/dist/render/weightedblended_oit.js +188 -0
  73. package/dist/render/weightedblended_oit.js.map +1 -0
  74. package/dist/scene/batchgroup.js +8 -35
  75. package/dist/scene/batchgroup.js.map +1 -1
  76. package/dist/scene/environment.js +2 -3
  77. package/dist/scene/environment.js.map +1 -1
  78. package/dist/scene/graph_node.js +1 -1
  79. package/dist/scene/mesh.js +11 -32
  80. package/dist/scene/mesh.js.map +1 -1
  81. package/dist/scene/octree.js +3 -3
  82. package/dist/scene/scene.js +2 -29
  83. package/dist/scene/scene.js.map +1 -1
  84. package/dist/scene/scene_node.js +6 -1
  85. package/dist/scene/scene_node.js.map +1 -1
  86. package/dist/scene/terrain/grass.js +17 -11
  87. package/dist/scene/terrain/grass.js.map +1 -1
  88. package/dist/scene/terrain/patch.js +18 -15
  89. package/dist/scene/terrain/patch.js.map +1 -1
  90. package/dist/scene/terrain/quadtree.js +1 -1
  91. package/dist/scene/terrain/terrain.js +0 -8
  92. package/dist/scene/terrain/terrain.js.map +1 -1
  93. package/dist/shaders/water.js +4 -4
  94. package/dist/shadow/esm.js +0 -1
  95. package/dist/shadow/esm.js.map +1 -1
  96. package/dist/shadow/shadowmapper.js +1 -2
  97. package/dist/shadow/shadowmapper.js.map +1 -1
  98. package/dist/shadow/vsm.js +1 -2
  99. package/dist/shadow/vsm.js.map +1 -1
  100. package/package.json +4 -4
@@ -1,17 +1,8 @@
1
1
  import { Vector4 } from '@zephyr3d/base';
2
2
  import { CullVisitor } from './cull_visitor.js';
3
- import { ShaderHelper } from '../material/shader/helper.js';
4
- import '../material/lambert.js';
5
- import '../material/blinn.js';
6
- import '../material/unlit.js';
7
- import { Material } from '../material/material.js';
8
- import '../material/meshmaterial.js';
9
- import '../material/grassmaterial.js';
10
- import '../material/terrainmaterial.js';
11
- import '../material/pbrmr.js';
12
- import '../material/pbrsg.js';
13
3
  import { Application } from '../app.js';
14
4
  import { RenderQueue } from './render_queue.js';
5
+ import { ShaderHelper } from '../material/shader/helper.js';
15
6
 
16
7
  /**
17
8
  * Base class for any kind of render passes
@@ -55,8 +46,8 @@ import { RenderQueue } from './render_queue.js';
55
46
  */ get type() {
56
47
  return this._type;
57
48
  }
58
- /** @internal */ isAutoFlip() {
59
- return !!(Application.instance.device.getFramebuffer() && Application.instance.device.type === 'webgpu');
49
+ /** @internal */ isAutoFlip(ctx) {
50
+ return !!(ctx.device.getFramebuffer() && ctx.device.type === 'webgpu');
60
51
  }
61
52
  /**
62
53
  * Renders a scene
@@ -65,15 +56,11 @@ import { RenderQueue } from './render_queue.js';
65
56
  ctx.renderPass = this;
66
57
  this.drawScene(ctx, cullCamera ?? ctx.camera, renderQueue);
67
58
  }
68
- /** @internal */ applyRenderStates(device, stateSet, ctx) {
69
- device.setRenderStates(stateSet);
70
- }
71
- /** @internal */ getGlobalBindGroupInfo(ctx) {
59
+ /** @internal */ getGlobalBindGroup(ctx) {
72
60
  const hash = this.getGlobalBindGroupHash(ctx);
73
61
  let bindGroup = this._globalBindGroups[hash];
74
62
  if (!bindGroup) {
75
- //const programBuilder = new ProgramBuilder(Application.instance.device);
76
- const ret = Application.instance.device.programBuilder.buildRender({
63
+ const ret = ctx.device.programBuilder.buildRender({
77
64
  vertex (pb) {
78
65
  ShaderHelper.prepareVertexShader(pb, ctx);
79
66
  pb.main(function() {});
@@ -83,37 +70,31 @@ import { RenderQueue } from './render_queue.js';
83
70
  pb.main(function() {});
84
71
  }
85
72
  });
86
- bindGroup = {
87
- bindGroup: Application.instance.device.createBindGroup(ret[2][0]),
88
- layout: ret[2][0]
89
- };
73
+ bindGroup = ctx.device.createBindGroup(ret[2][0]);
90
74
  this._globalBindGroups[hash] = bindGroup;
91
75
  }
92
- if (bindGroup.bindGroup.disposed) {
93
- bindGroup.bindGroup.reload();
94
- }
95
76
  return bindGroup;
96
77
  }
97
78
  /**
98
79
  * Disposes the render pass
99
80
  */ dispose() {
100
- for(const k in this._globalBindGroups){
101
- Material.bindGroupGarbageCollect(this._globalBindGroups[k].bindGroup);
102
- }
103
81
  this._globalBindGroups = {};
104
82
  }
105
83
  /** @internal */ getGlobalBindGroupHash(ctx) {
106
84
  return `${this.constructor.name}:${this._getGlobalBindGroupHash(ctx)}`;
107
85
  }
108
86
  /** @internal */ drawScene(ctx, cullCamera, renderQueue) {
109
- const device = Application.instance.device;
87
+ const device = ctx.device;
110
88
  this.clearFramebuffer();
111
- renderQueue = renderQueue ?? this.cullScene(ctx, cullCamera);
112
- if (renderQueue) {
89
+ const rq = renderQueue ?? this.cullScene(ctx, cullCamera);
90
+ if (rq) {
113
91
  const windingReversed = device.isWindingOrderReversed();
114
- device.reverseVertexWindingOrder(this.isAutoFlip() ? !windingReversed : windingReversed);
115
- this.renderItems(ctx, renderQueue);
92
+ device.reverseVertexWindingOrder(this.isAutoFlip(ctx) ? !windingReversed : windingReversed);
93
+ this.renderItems(ctx, rq);
116
94
  device.reverseVertexWindingOrder(windingReversed);
95
+ if (rq !== renderQueue) {
96
+ rq.dispose();
97
+ }
117
98
  }
118
99
  }
119
100
  /**
@@ -130,7 +111,7 @@ import { RenderQueue } from './render_queue.js';
130
111
  } else {
131
112
  ctx.scene.rootNode.traverse(cullVisitor);
132
113
  }
133
- return renderQueue;
114
+ return renderQueue.end(cullCamera);
134
115
  }
135
116
  return null;
136
117
  }
@@ -144,6 +125,83 @@ import { RenderQueue } from './render_queue.js';
144
125
  device.reverseVertexWindingOrder(!device.isWindingOrderReversed());
145
126
  }
146
127
  }
128
+ /** @internal */ internalDrawItemList(ctx, items, renderBundle, reverseWinding, hash) {
129
+ if (renderBundle && ctx.primaryCamera.commandBufferReuse) {
130
+ const bundle = renderBundle.getRenderBundle(hash);
131
+ if (bundle) {
132
+ ctx.device.executeRenderBundle(bundle);
133
+ return;
134
+ }
135
+ renderBundle.beginRenderBundle();
136
+ }
137
+ for (const item of items){
138
+ ctx.instanceData = item.instanceData;
139
+ const reverse = reverseWinding !== item.drawable.getXForm().worldMatrixDet < 0;
140
+ if (reverse) {
141
+ ctx.device.reverseVertexWindingOrder(!ctx.device.isWindingOrderReversed());
142
+ }
143
+ item.drawable.draw(ctx);
144
+ if (reverse) {
145
+ ctx.device.reverseVertexWindingOrder(!ctx.device.isWindingOrderReversed());
146
+ }
147
+ }
148
+ if (renderBundle && ctx.primaryCamera.commandBufferReuse) {
149
+ renderBundle.endRenderBundle(hash);
150
+ }
151
+ }
152
+ /** @internal */ drawItemList(itemList, ctx, reverseWinding) {
153
+ ctx.renderQueue = itemList.renderQueue;
154
+ ctx.instanceData = null;
155
+ const windingHash = reverseWinding ? '1' : '0';
156
+ const bindGroupHash = ctx.device.getBindGroup(0)[0].getGPUId();
157
+ const framebufferHash = ctx.device.getFramebuffer()?.getHash() ?? '';
158
+ const hash = `${windingHash}-${bindGroupHash}-${framebufferHash}-${ctx.renderPassHash}`;
159
+ if (itemList) {
160
+ if (itemList.itemList.length > 0) {
161
+ ctx.skinAnimation = false;
162
+ ctx.instancing = false;
163
+ itemList.materialList.forEach((mat)=>mat.apply(ctx));
164
+ this.internalDrawItemList(ctx, itemList.itemList, itemList.renderBundle, reverseWinding, hash);
165
+ }
166
+ if (itemList.skinItemList.length > 0) {
167
+ ctx.skinAnimation = true;
168
+ ctx.instancing = false;
169
+ itemList.materialList.forEach((mat)=>mat.apply(ctx));
170
+ this.internalDrawItemList(ctx, itemList.skinItemList, itemList.skinRenderBundle, reverseWinding, hash);
171
+ /*
172
+ for (const item of itemList.skinItemList) {
173
+ ctx.instanceData = item.instanceData;
174
+ const reverse = reverseWinding !== item.drawable.getXForm().worldMatrixDet < 0;
175
+ if (reverse) {
176
+ device.reverseVertexWindingOrder(!device.isWindingOrderReversed());
177
+ }
178
+ item.drawable.draw(ctx);
179
+ if (reverse) {
180
+ device.reverseVertexWindingOrder(!device.isWindingOrderReversed());
181
+ }
182
+ }
183
+ */ }
184
+ if (itemList.instanceItemList.length > 0) {
185
+ ctx.skinAnimation = false;
186
+ ctx.instancing = true;
187
+ itemList.materialList.forEach((mat)=>mat.apply(ctx));
188
+ this.internalDrawItemList(ctx, itemList.instanceItemList, itemList.instanceRenderBundle, reverseWinding, hash);
189
+ /*
190
+ for (const item of itemList.instanceItemList) {
191
+ ctx.instanceData = item.instanceData;
192
+ const reverse = reverseWinding !== item.drawable.getXForm().worldMatrixDet < 0;
193
+ if (reverse) {
194
+ device.reverseVertexWindingOrder(!device.isWindingOrderReversed());
195
+ }
196
+ item.drawable.draw(ctx);
197
+ if (reverse) {
198
+ device.reverseVertexWindingOrder(!device.isWindingOrderReversed());
199
+ }
200
+ }
201
+ */ }
202
+ }
203
+ ctx.renderQueue = null;
204
+ }
147
205
  /** @internal */ clearFramebuffer() {
148
206
  Application.instance.device.clearFrameBuffer(this._clearColor, this._clearDepth, this._clearStencil);
149
207
  }
@@ -1 +1 @@
1
- {"version":3,"file":"renderpass.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"renderpass.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,6 +1,5 @@
1
1
  import { RenderPass } from './renderpass.js';
2
2
  import { RENDER_PASS_TYPE_SHADOWMAP } from '../values.js';
3
- import { Application } from '../app.js';
4
3
  import { ShaderHelper } from '../material/shader/helper.js';
5
4
 
6
5
  /**
@@ -9,13 +8,11 @@ import { ShaderHelper } from '../material/shader/helper.js';
9
8
  * @public
10
9
  */ class ShadowMapPass extends RenderPass {
11
10
  /** @internal */ _currentLight;
12
- /** @internal */ _stateOverriden;
13
11
  /**
14
12
  * Creates an instance of ShadowMapPass
15
13
  */ constructor(){
16
14
  super(RENDER_PASS_TYPE_SHADOWMAP);
17
15
  this._currentLight = null;
18
- this._stateOverriden = null;
19
16
  }
20
17
  /** The light that will be used to render shadow map */ get light() {
21
18
  return this._currentLight;
@@ -23,43 +20,27 @@ import { ShaderHelper } from '../material/shader/helper.js';
23
20
  set light(light) {
24
21
  this._currentLight = light;
25
22
  }
26
- /** @internal */ get stateOverriden() {
27
- if (!this._stateOverriden) {
28
- this._stateOverriden = Application.instance.device.createRenderStateSet();
29
- this._stateOverriden.useRasterizerState().setCullMode('none');
30
- }
31
- return this._stateOverriden;
32
- }
33
- /** @internal */ applyRenderStates(device, stateSet, ctx) {
34
- const stateOverriden = this.stateOverriden;
35
- const state = stateOverriden.rasterizerState;
36
- stateOverriden.copyFrom(stateSet);
37
- stateOverriden.useRasterizerState(state);
38
- device.setRenderStates(stateOverriden);
39
- }
40
23
  /** @internal */ _getGlobalBindGroupHash(ctx) {
41
- return ctx.shadowMapInfo.get(this.light).shaderHash;
24
+ return `sm:${ctx.shadowMapInfo.get(this.light).shaderHash}`;
42
25
  }
43
26
  /** @internal */ renderItems(ctx, renderQueue) {
44
- ctx.target = null;
45
27
  ctx.drawEnvLight = false;
46
28
  ctx.env = null;
47
- ctx.applyFog = false;
48
- ctx.renderPassHash = null;
49
- ctx.flip = this.isAutoFlip();
50
- const device = Application.instance.device;
51
- const bindGroup = this.getGlobalBindGroupInfo(ctx).bindGroup;
52
- device.setBindGroup(0, bindGroup);
53
- ShaderHelper.setLightUniformsShadowMap(bindGroup, ctx, this._currentLight);
54
- ShaderHelper.setCameraUniforms(bindGroup, ctx, true);
29
+ ctx.applyFog = null;
30
+ ctx.flip = this.isAutoFlip(ctx);
55
31
  ctx.renderPassHash = this.getGlobalBindGroupHash(ctx);
32
+ const bindGroup = ctx.globalBindGroupAllocator.getGlobalBindGroup(ctx);
33
+ ctx.device.setBindGroup(0, bindGroup);
34
+ ShaderHelper.setLightUniformsShadowMap(bindGroup, ctx, this._currentLight);
35
+ ShaderHelper.setCameraUniforms(bindGroup, ctx.camera, ctx.flip, true);
56
36
  const reverseWinding = ctx.camera.worldMatrixDet < 0;
57
37
  for (const order of Object.keys(renderQueue.items).map((val)=>Number(val)).sort((a, b)=>a - b)){
58
38
  const renderItems = renderQueue.items[order];
59
- for (const item of renderItems.opaqueList){
60
- ctx.instanceData = item.instanceData;
61
- ctx.target = item.drawable;
62
- this.drawItem(device, item, ctx, reverseWinding);
39
+ for (const lit of renderItems.opaque.lit){
40
+ this.drawItemList(lit, ctx, reverseWinding);
41
+ }
42
+ for (const unlit of renderItems.opaque.unlit){
43
+ this.drawItemList(unlit, ctx, reverseWinding);
63
44
  }
64
45
  }
65
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shadowmap_pass.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"shadowmap_pass.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -96,7 +96,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
96
96
  this._lastSunDir = Vector3.zero();
97
97
  }
98
98
  /** @internal */ getHash(ctx) {
99
- return ctx.applyFog ? this._fogType === 'none' ? '0' : this.drawScatteredFog(ctx) ? '1' : '2' : '';
99
+ return ctx.applyFog === 'scatter' ? '1' : ctx.applyFog ? '2' : '0';
100
100
  }
101
101
  /** Which type of the sky should be rendered */ get skyType() {
102
102
  return this._skyType;
@@ -339,7 +339,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
339
339
  /** @internal */ renderFog(ctx) {
340
340
  const camera = ctx.camera;
341
341
  const sceneDepthTexture = ctx.linearDepthTexture;
342
- const device = Application.instance.device;
342
+ const device = ctx.device;
343
343
  const savedRenderStates = device.getRenderStates();
344
344
  this._prepareSkyBox(device);
345
345
  const sunLight = ctx.sunLight;
@@ -44,15 +44,21 @@ const RENDER_TWO_PASS = 2;
44
44
  _hkBindGroup2;
45
45
  _hkBindGroup4;
46
46
  _fft2hBindGroup;
47
- _fft2hBindGroup2;
48
- _fft2hBindGroup4;
49
47
  _fft2vBindGroup;
50
- _fft2vBindGroup2;
51
- _fft2vBindGroup4;
48
+ _fft2hBindGroup2Used;
49
+ _fft2hBindGroup2Free;
50
+ _fft2hBindGroup4Used;
51
+ _fft2hBindGroup4Free;
52
+ _fft2vBindGroup2Used;
53
+ _fft2vBindGroup2Free;
54
+ _fft2vBindGroup4Used;
55
+ _fft2vBindGroup4Free;
52
56
  _postfft2BindGroup;
53
57
  _postfft2BindGroup2;
54
58
  _postfft2BindGroup4;
55
59
  _waterBindGroup;
60
+ _usedClipmapBindGroups;
61
+ _freeClipmapBindGroups;
56
62
  _nearestRepeatSampler;
57
63
  _linearRepeatSampler;
58
64
  _updateRenderStates;
@@ -78,7 +84,7 @@ const RENDER_TWO_PASS = 2;
78
84
  _dataTextureFormat;
79
85
  _renderMode;
80
86
  _updateFrameStamp;
81
- // private _impl: WaterShaderImpl;
87
+ _waterProgram;
82
88
  constructor(device, impl){
83
89
  const renderTargetFloat32 = device.getDeviceCaps().textureCaps.supportFloatColorBuffer;
84
90
  const linearFloat32 = renderTargetFloat32 && device.getDeviceCaps().textureCaps.supportLinearFloatTexture;
@@ -126,13 +132,13 @@ const RENDER_TWO_PASS = 2;
126
132
  fft2vProgram4: this._renderMode === RENDER_TWO_PASS ? createProgramFFT2V(4) : null,
127
133
  postfft2Program: this._renderMode === RENDER_NORMAL ? createProgramPostFFT2() : null,
128
134
  postfft2Program2: this._renderMode === RENDER_TWO_PASS ? createProgramPostFFT2(2) : null,
129
- postfft2Program4: this._renderMode === RENDER_TWO_PASS ? createProgramPostFFT2(4) : null,
130
- waterProgram: createProgramOcean(impl)
135
+ postfft2Program4: this._renderMode === RENDER_TWO_PASS ? createProgramPostFFT2(4) : null
131
136
  },
132
137
  quad: WaterMesh.createQuad(device),
133
138
  noiseTextures: new Map(),
134
139
  butterflyTextures: new Map()
135
140
  };
141
+ this._waterProgram = createProgramOcean(impl);
136
142
  this._params = defaultBuildParams;
137
143
  const programs = WaterMesh._globals.programs;
138
144
  this._h0BindGroup = device.createBindGroup(programs.h0Program.bindGroupLayouts[0]);
@@ -140,15 +146,43 @@ const RENDER_TWO_PASS = 2;
140
146
  this._hkBindGroup2 = programs.hkProgram2 ? device.createBindGroup(WaterMesh._globals.programs.hkProgram2.bindGroupLayouts[0]) : null;
141
147
  this._hkBindGroup4 = programs.hkProgram4 ? device.createBindGroup(WaterMesh._globals.programs.hkProgram4.bindGroupLayouts[0]) : null;
142
148
  this._fft2hBindGroup = programs.fft2hProgram ? device.createBindGroup(WaterMesh._globals.programs.fft2hProgram.bindGroupLayouts[0]) : null;
143
- this._fft2hBindGroup2 = programs.fft2hProgram2 ? device.createBindGroup(WaterMesh._globals.programs.fft2hProgram2.bindGroupLayouts[0]) : null;
144
- this._fft2hBindGroup4 = programs.fft2hProgram4 ? device.createBindGroup(WaterMesh._globals.programs.fft2hProgram4.bindGroupLayouts[0]) : null;
145
149
  this._fft2vBindGroup = programs.fft2vProgram ? device.createBindGroup(WaterMesh._globals.programs.fft2vProgram.bindGroupLayouts[0]) : null;
146
- this._fft2vBindGroup2 = programs.fft2vProgram2 ? device.createBindGroup(WaterMesh._globals.programs.fft2vProgram2.bindGroupLayouts[0]) : null;
147
- this._fft2vBindGroup4 = programs.fft2vProgram4 ? device.createBindGroup(WaterMesh._globals.programs.fft2vProgram4.bindGroupLayouts[0]) : null;
150
+ this._fft2hBindGroup2Used = [
151
+ [],
152
+ []
153
+ ];
154
+ this._fft2hBindGroup2Free = [
155
+ [],
156
+ []
157
+ ];
158
+ this._fft2hBindGroup4Used = [
159
+ [],
160
+ []
161
+ ];
162
+ this._fft2hBindGroup4Free = [
163
+ [],
164
+ []
165
+ ];
166
+ this._fft2vBindGroup2Used = [
167
+ [],
168
+ []
169
+ ];
170
+ this._fft2vBindGroup2Free = [
171
+ [],
172
+ []
173
+ ];
174
+ this._fft2vBindGroup4Used = [
175
+ [],
176
+ []
177
+ ];
178
+ this._fft2vBindGroup4Free = [
179
+ [],
180
+ []
181
+ ];
148
182
  this._postfft2BindGroup = programs.postfft2Program ? device.createBindGroup(WaterMesh._globals.programs.postfft2Program.bindGroupLayouts[0]) : null;
149
183
  this._postfft2BindGroup2 = programs.postfft2Program2 ? device.createBindGroup(WaterMesh._globals.programs.postfft2Program2.bindGroupLayouts[0]) : null;
150
184
  this._postfft2BindGroup4 = programs.postfft2Program4 ? device.createBindGroup(WaterMesh._globals.programs.postfft2Program4.bindGroupLayouts[0]) : null;
151
- this._waterBindGroup = device.createBindGroup(WaterMesh._globals.programs.waterProgram.bindGroupLayouts[0]);
185
+ this._waterBindGroup = device.createBindGroup(this._waterProgram.bindGroupLayouts[0]);
152
186
  this._instanceData = null;
153
187
  this._ifftTextures = null;
154
188
  this._wireframe = false;
@@ -190,7 +224,8 @@ const RENDER_TWO_PASS = 2;
190
224
  this._paramsChanged = true;
191
225
  this._resolutionChanged = true;
192
226
  this._updateFrameStamp = -1;
193
- // this._impl = impl;
227
+ this._usedClipmapBindGroups = [];
228
+ this._freeClipmapBindGroups = [];
194
229
  }
195
230
  }
196
231
  get params() {
@@ -308,6 +343,14 @@ const RENDER_TWO_PASS = 2;
308
343
  set regionMax(val) {
309
344
  this._regionMax.set(val);
310
345
  }
346
+ getClipmapBindGroup(device) {
347
+ let bindGroup = this._usedClipmapBindGroups.pop();
348
+ if (!bindGroup) {
349
+ bindGroup = device.createBindGroup(this._waterProgram.bindGroupLayouts[1]);
350
+ }
351
+ this._freeClipmapBindGroups.push(bindGroup);
352
+ return bindGroup;
353
+ }
311
354
  render(camera, flip) {
312
355
  if (this._renderMode === RENDER_NONE) {
313
356
  return;
@@ -321,7 +364,7 @@ const RENDER_TWO_PASS = 2;
321
364
  device.popDeviceStates();
322
365
  const cameraPos = camera.getWorldPosition();
323
366
  const instanceData = this.getInstanceData();
324
- device.setProgram(WaterMesh._globals.programs.waterProgram);
367
+ device.setProgram(this._waterProgram);
325
368
  device.setBindGroup(0, this._waterBindGroup);
326
369
  device.setRenderStates(this._waterRenderStates);
327
370
  const sampler = this._linearRepeatSampler;
@@ -339,7 +382,6 @@ const RENDER_TWO_PASS = 2;
339
382
  this._waterBindGroup.setValue('viewProjMatrix', camera.viewProjectionMatrix);
340
383
  this._waterBindGroup.setValue('level', this._level);
341
384
  this._waterBindGroup.setValue('pos', cameraPos);
342
- this._waterBindGroup.setValue('scale', 1);
343
385
  this._waterBindGroup.setValue('flip', flip ? 1 : 0);
344
386
  const that = this;
345
387
  const position = new Vector3(cameraPos.x, cameraPos.z, 0);
@@ -358,14 +400,18 @@ const RENDER_TWO_PASS = 2;
358
400
  gridScale: gridScale,
359
401
  AABBExtents: this._aabbExtents,
360
402
  drawPrimitive (prim, modelMatrix, offset, scale, gridScale) {
361
- that._waterBindGroup.setValue('modelMatrix', modelMatrix);
362
- that._waterBindGroup.setValue('offset', offset);
363
- that._waterBindGroup.setValue('scale', scale);
364
- that._waterBindGroup.setValue('gridScale', gridScale);
403
+ const clipmapBindGroup = that.getClipmapBindGroup(device);
404
+ clipmapBindGroup.setValue('modelMatrix', modelMatrix);
405
+ clipmapBindGroup.setValue('offset', offset);
406
+ clipmapBindGroup.setValue('scale', scale);
407
+ clipmapBindGroup.setValue('gridScale', gridScale);
408
+ device.setBindGroup(1, clipmapBindGroup);
365
409
  prim.primitiveType = that._wireframe ? 'line-strip' : 'triangle-list';
366
410
  prim.draw();
367
411
  }
368
412
  }, mipLevels);
413
+ this._usedClipmapBindGroups.push(...this._freeClipmapBindGroups);
414
+ this._freeClipmapBindGroups.length = 0;
369
415
  }
370
416
  update(device, time) {
371
417
  device.setRenderStates(this._updateRenderStates);
@@ -489,7 +535,7 @@ const RENDER_TWO_PASS = 2;
489
535
  this._fft2hBindGroup.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
490
536
  }
491
537
  WaterMesh._globals.quad.draw();
492
- pingPong = (pingPong + 1) % 2;
538
+ pingPong = 1 - pingPong; //(pingPong + 1) % 2;
493
539
  }
494
540
  // vertical ifft
495
541
  device.setProgram(WaterMesh._globals.programs.fft2vProgram);
@@ -512,6 +558,38 @@ const RENDER_TWO_PASS = 2;
512
558
  }
513
559
  this._ifftTextures = pingPongTextures[pingPong];
514
560
  }
561
+ getFFT2hBindGroup2(device, pingpong) {
562
+ let bindGroup = this._fft2hBindGroup2Used[pingpong].pop();
563
+ if (!bindGroup) {
564
+ bindGroup = device.createBindGroup(WaterMesh._globals.programs.fft2hProgram2.bindGroupLayouts[0]);
565
+ }
566
+ this._fft2hBindGroup2Free[pingpong].push(bindGroup);
567
+ return bindGroup;
568
+ }
569
+ getFFT2hBindGroup4(device, pingpong) {
570
+ let bindGroup = this._fft2hBindGroup4Used[pingpong].pop();
571
+ if (!bindGroup) {
572
+ bindGroup = device.createBindGroup(WaterMesh._globals.programs.fft2hProgram4.bindGroupLayouts[0]);
573
+ }
574
+ this._fft2hBindGroup4Free[pingpong].push(bindGroup);
575
+ return bindGroup;
576
+ }
577
+ getFFT2vBindGroup2(device, pingpong) {
578
+ let bindGroup = this._fft2vBindGroup2Used[pingpong].pop();
579
+ if (!bindGroup) {
580
+ bindGroup = device.createBindGroup(WaterMesh._globals.programs.fft2vProgram2.bindGroupLayouts[0]);
581
+ }
582
+ this._fft2vBindGroup2Free[pingpong].push(bindGroup);
583
+ return bindGroup;
584
+ }
585
+ getFFT2vBindGroup4(device, pingpong) {
586
+ let bindGroup = this._fft2vBindGroup4Used[pingpong].pop();
587
+ if (!bindGroup) {
588
+ bindGroup = device.createBindGroup(WaterMesh._globals.programs.fft2vProgram4.bindGroupLayouts[0]);
589
+ }
590
+ this._fft2vBindGroup4Free[pingpong].push(bindGroup);
591
+ return bindGroup;
592
+ }
515
593
  ifft2TwoPass() {
516
594
  const device = Application.instance.device;
517
595
  const instanceData = this.getInstanceData();
@@ -534,26 +612,28 @@ const RENDER_TWO_PASS = 2;
534
612
  for(let phase = 0; phase < phases; phase++){
535
613
  device.setFramebuffer(pingPongFramebuffers4[pingPong]);
536
614
  device.setProgram(WaterMesh._globals.programs.fft2hProgram4);
537
- device.setBindGroup(0, this._fft2hBindGroup4);
538
- this._fft2hBindGroup4.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
539
- this._fft2hBindGroup4.setValue('phase', phase);
540
- this._fft2hBindGroup4.setTexture('spectrum0', pingPongTextures[pingPong][0], this._nearestRepeatSampler);
541
- this._fft2hBindGroup4.setTexture('spectrum1', pingPongTextures[pingPong][1], this._nearestRepeatSampler);
542
- this._fft2hBindGroup4.setTexture('spectrum2', pingPongTextures[pingPong][2], this._nearestRepeatSampler);
543
- this._fft2hBindGroup4.setTexture('spectrum3', pingPongTextures[pingPong][3], this._nearestRepeatSampler);
615
+ const fft2hBindGroup4 = this.getFFT2hBindGroup4(device, pingPong);
616
+ device.setBindGroup(0, fft2hBindGroup4);
617
+ fft2hBindGroup4.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
618
+ fft2hBindGroup4.setValue('phase', phase);
619
+ fft2hBindGroup4.setTexture('spectrum0', pingPongTextures[pingPong][0], this._nearestRepeatSampler);
620
+ fft2hBindGroup4.setTexture('spectrum1', pingPongTextures[pingPong][1], this._nearestRepeatSampler);
621
+ fft2hBindGroup4.setTexture('spectrum2', pingPongTextures[pingPong][2], this._nearestRepeatSampler);
622
+ fft2hBindGroup4.setTexture('spectrum3', pingPongTextures[pingPong][3], this._nearestRepeatSampler);
544
623
  if (device.type === 'webgl') {
545
- this._fft2hBindGroup4.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
624
+ fft2hBindGroup4.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
546
625
  }
547
626
  WaterMesh._globals.quad.draw();
548
627
  device.setFramebuffer(pingPongFramebuffers2[pingPong]);
549
628
  device.setProgram(WaterMesh._globals.programs.fft2hProgram2);
550
- device.setBindGroup(0, this._fft2hBindGroup2);
551
- this._fft2hBindGroup2.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
552
- this._fft2hBindGroup2.setValue('phase', phase);
553
- this._fft2hBindGroup2.setTexture('spectrum4', pingPongTextures[pingPong][4], this._nearestRepeatSampler);
554
- this._fft2hBindGroup2.setTexture('spectrum5', pingPongTextures[pingPong][5], this._nearestRepeatSampler);
629
+ const fft2hBindGroup2 = this.getFFT2hBindGroup2(device, pingPong);
630
+ device.setBindGroup(0, fft2hBindGroup2);
631
+ fft2hBindGroup2.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
632
+ fft2hBindGroup2.setValue('phase', phase);
633
+ fft2hBindGroup2.setTexture('spectrum4', pingPongTextures[pingPong][4], this._nearestRepeatSampler);
634
+ fft2hBindGroup2.setTexture('spectrum5', pingPongTextures[pingPong][5], this._nearestRepeatSampler);
555
635
  if (device.type === 'webgl') {
556
- this._fft2hBindGroup2.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
636
+ fft2hBindGroup2.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
557
637
  }
558
638
  WaterMesh._globals.quad.draw();
559
639
  pingPong = (pingPong + 1) % 2;
@@ -562,31 +642,43 @@ const RENDER_TWO_PASS = 2;
562
642
  for(let phase = 0; phase < phases; phase++){
563
643
  device.setFramebuffer(pingPongFramebuffers4[pingPong]);
564
644
  device.setProgram(WaterMesh._globals.programs.fft2vProgram4);
565
- device.setBindGroup(0, this._fft2vBindGroup4);
566
- this._fft2vBindGroup4.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
567
- this._fft2vBindGroup4.setValue('phase', phase);
568
- this._fft2vBindGroup4.setTexture('spectrum0', pingPongTextures[pingPong][0], this._nearestRepeatSampler);
569
- this._fft2vBindGroup4.setTexture('spectrum1', pingPongTextures[pingPong][1], this._nearestRepeatSampler);
570
- this._fft2vBindGroup4.setTexture('spectrum2', pingPongTextures[pingPong][2], this._nearestRepeatSampler);
571
- this._fft2vBindGroup4.setTexture('spectrum3', pingPongTextures[pingPong][3], this._nearestRepeatSampler);
645
+ const fft2vBindGroup4 = this.getFFT2vBindGroup4(device, pingPong);
646
+ device.setBindGroup(0, fft2vBindGroup4);
647
+ fft2vBindGroup4.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
648
+ fft2vBindGroup4.setValue('phase', phase);
649
+ fft2vBindGroup4.setTexture('spectrum0', pingPongTextures[pingPong][0], this._nearestRepeatSampler);
650
+ fft2vBindGroup4.setTexture('spectrum1', pingPongTextures[pingPong][1], this._nearestRepeatSampler);
651
+ fft2vBindGroup4.setTexture('spectrum2', pingPongTextures[pingPong][2], this._nearestRepeatSampler);
652
+ fft2vBindGroup4.setTexture('spectrum3', pingPongTextures[pingPong][3], this._nearestRepeatSampler);
572
653
  if (device.type === 'webgl') {
573
- this._fft2vBindGroup4.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
654
+ fft2vBindGroup4.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
574
655
  }
575
656
  WaterMesh._globals.quad.draw();
576
657
  device.setFramebuffer(pingPongFramebuffers2[pingPong]);
577
658
  device.setProgram(WaterMesh._globals.programs.fft2vProgram2);
578
- device.setBindGroup(0, this._fft2vBindGroup2);
579
- this._fft2vBindGroup2.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
580
- this._fft2vBindGroup2.setValue('phase', phase);
581
- this._fft2vBindGroup2.setTexture('spectrum4', pingPongTextures[pingPong][4], this._nearestRepeatSampler);
582
- this._fft2vBindGroup2.setTexture('spectrum5', pingPongTextures[pingPong][5], this._nearestRepeatSampler);
659
+ const fft2vBindGroup2 = this.getFFT2vBindGroup2(device, pingPong);
660
+ device.setBindGroup(0, fft2vBindGroup2);
661
+ fft2vBindGroup2.setTexture('butterfly', butterflyTex, this._nearestRepeatSampler);
662
+ fft2vBindGroup2.setValue('phase', phase);
663
+ fft2vBindGroup2.setTexture('spectrum4', pingPongTextures[pingPong][4], this._nearestRepeatSampler);
664
+ fft2vBindGroup2.setTexture('spectrum5', pingPongTextures[pingPong][5], this._nearestRepeatSampler);
583
665
  if (device.type === 'webgl') {
584
- this._fft2vBindGroup2.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
666
+ fft2vBindGroup2.setValue('texSize', new Vector4(pingPongTextures[pingPong][0].width, pingPongTextures[pingPong][0].height, butterflyTex.width, butterflyTex.height));
585
667
  }
586
668
  WaterMesh._globals.quad.draw();
587
669
  pingPong = (pingPong + 1) % 2;
588
670
  }
589
671
  this._ifftTextures = pingPongTextures[pingPong];
672
+ for(let i = 0; i < 2; i++){
673
+ this._fft2hBindGroup2Used[i].push(...this._fft2hBindGroup2Free[i]);
674
+ this._fft2hBindGroup2Free[i].length = 0;
675
+ this._fft2hBindGroup4Used[i].push(...this._fft2hBindGroup4Free[i]);
676
+ this._fft2hBindGroup4Free[i].length = 0;
677
+ this._fft2vBindGroup2Used[i].push(...this._fft2vBindGroup2Free[i]);
678
+ this._fft2vBindGroup2Free[i].length = 0;
679
+ this._fft2vBindGroup4Used[i].push(...this._fft2vBindGroup4Free[i]);
680
+ this._fft2vBindGroup4Free[i].length = 0;
681
+ }
590
682
  }
591
683
  postIfft2() {
592
684
  const device = Application.instance.device;
@@ -1 +1 @@
1
- {"version":3,"file":"watermesh.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"watermesh.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}