@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
package/dist/index.js CHANGED
@@ -9,7 +9,6 @@ export { CylinderShape } from './shapes/cylinder.js';
9
9
  export { TorusShape } from './shapes/torus.js';
10
10
  export { PlaneShape } from './shapes/plane.js';
11
11
  export { SphereShape } from './shapes/sphere.js';
12
- export { RenderScheme } from './render/renderscheme.js';
13
12
  export { RenderPass } from './render/renderpass.js';
14
13
  export { SceneRenderer } from './render/renderer.js';
15
14
  export { LightPass } from './render/lightpass.js';
@@ -23,6 +22,9 @@ export { Primitive } from './render/primitive.js';
23
22
  export { CullVisitor } from './render/cull_visitor.js';
24
23
  export { TemporalCache } from './render/temporalcache.js';
25
24
  export { WaterMesh, defaultBuildParams } from './render/watermesh.js';
25
+ export { OIT } from './render/oit.js';
26
+ export { WeightedBlendedOIT } from './render/weightedblended_oit.js';
27
+ export { ABufferOIT } from './render/abuffer_oit.js';
26
28
  export { ShaderHelper } from './material/shader/helper.js';
27
29
  export { LambertMaterial } from './material/lambert.js';
28
30
  export { BlinnMaterial } from './material/blinn.js';
@@ -54,7 +56,7 @@ export { SceneNode } from './scene/scene_node.js';
54
56
  export { BatchGroup } from './scene/batchgroup.js';
55
57
  export { Terrain } from './scene/terrain/terrain.js';
56
58
  export { HeightField, HeightfieldBBoxTree } from './scene/terrain/heightfield.js';
57
- export { TerrainPatch } from './scene/terrain/patch.js';
59
+ export { TerrainPatch, TerrainPatchBase } from './scene/terrain/patch.js';
58
60
  export { Quadtree, QuadtreeNode } from './scene/terrain/quadtree.js';
59
61
  export { XForm } from './scene/xform.js';
60
62
  export { AnimationClip } from './animation/animation.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -43,6 +43,12 @@ import { mixinFoliage } from './mixins/foliage.js';
43
43
  */ supportLighting() {
44
44
  return true;
45
45
  }
46
+ /**
47
+ * {@inheritDoc Material.supportInstancing}
48
+ * @override
49
+ */ supportInstancing() {
50
+ return false;
51
+ }
46
52
  applyUniformValues(bindGroup, ctx, pass) {
47
53
  super.applyUniformValues(bindGroup, ctx, pass);
48
54
  bindGroup.setTexture('terrainNormalMap', this._terrainNormalMap);
@@ -87,6 +93,15 @@ import { mixinFoliage } from './mixins/foliage.js';
87
93
  this.outputFragmentColor(scope, scope.$inputs.worldPos, null);
88
94
  }
89
95
  }
96
+ apply(ctx) {
97
+ this.alphaToCoverage = ctx.device.getFrameBufferSampleCount() > 1;
98
+ this.alphaCutoff = this.alphaToCoverage ? 1 : 0.8;
99
+ return super.apply(ctx);
100
+ }
101
+ updateRenderStates(pass, stateSet, ctx) {
102
+ super.updateRenderStates(pass, stateSet, ctx);
103
+ stateSet.useRasterizerState().setCullMode('none');
104
+ }
90
105
  }
91
106
 
92
107
  export { GrassMaterial };
@@ -1 +1 @@
1
- {"version":3,"file":"grassmaterial.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"grassmaterial.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,8 +1,5 @@
1
- import { List } from '@zephyr3d/base';
2
1
  import { ProgramBuilder } from '@zephyr3d/device';
3
- import { Application } from '../app.js';
4
- import { QUEUE_OPAQUE, RENDER_PASS_TYPE_LIGHT, RENDER_PASS_TYPE_SHADOWMAP, RENDER_PASS_TYPE_DEPTH } from '../values.js';
5
- import { ShaderHelper } from './shader/helper.js';
2
+ import { QUEUE_OPAQUE } from '../values.js';
6
3
 
7
4
  /**
8
5
  * Base class for any kind of materials
@@ -10,41 +7,23 @@ import { ShaderHelper } from './shader/helper.js';
10
7
  * @public
11
8
  */ class Material {
12
9
  /** @internal */ static _nextId = 0;
13
- /** @internal */ static _programMap = {};
14
- /** @internal */ static _drawableTimestamps = new WeakMap();
15
- /** @internal */ static _drawableIterators = new WeakMap();
16
- /** @internal */ static _drawableLRU = new List();
17
- /** @internal */ static _materialTimestamps = new WeakMap();
18
- /** @internal */ static _materialIterators = new WeakMap();
19
- /** @internal */ static _materialLRU = new List();
20
- /** @internal */ static _gcOptions = {
21
- disabled: true,
22
- drawableCountThreshold: 500,
23
- materialCountThreshold: 200,
24
- inactiveTimeDuration: 30000
25
- };
26
- /** @internal */ static _boneMatrixTextureSampler = null;
27
- /** @internal */ //private static _instanceBindGroupPool: InstanceBindGroupPool = new InstanceBindGroupPool();
28
- /** @internal */ static _drawableBindGroupMap = new WeakMap();
10
+ /** @internal */ _states;
29
11
  /** @internal */ _numPasses;
30
12
  /** @internal */ _hash;
31
- /** @internal */ _renderStateSet;
32
- /** @internal */ _bindGroupMap;
33
13
  /** @internal */ _optionTag;
34
- /** @internal */ _materialBindGroup;
35
14
  /** @internal */ _id;
15
+ /** @internal */ _currentHash;
36
16
  /**
37
17
  * Creates an instance of material
38
18
  */ constructor(){
39
19
  this._id = ++Material._nextId;
20
+ this._states = {};
40
21
  this._numPasses = 1;
41
22
  this._hash = [
42
- []
23
+ null
43
24
  ];
44
- this._renderStateSet = null;
45
- this._bindGroupMap = {};
46
25
  this._optionTag = 0;
47
- this._materialBindGroup = null;
26
+ this._currentHash = [];
48
27
  }
49
28
  /** Unique identifier of the material */ get instanceId() {
50
29
  return this._id;
@@ -54,94 +33,91 @@ import { ShaderHelper } from './shader/helper.js';
54
33
  }
55
34
  set numPasses(val) {
56
35
  while(this._hash.length < val){
57
- this._hash.push([]);
36
+ this._hash.push(null);
58
37
  }
59
38
  this._numPasses = val;
60
39
  }
61
- /** @internal */ getHash(renderPassType, pass) {
62
- if (this._hash[pass][renderPassType] === void 0) {
63
- this._hash[pass][renderPassType] = this.createHash(renderPassType, pass);
40
+ /** @internal */ getHash(pass) {
41
+ if (this._hash[pass] === null) {
42
+ this._hash[pass] = this.createHash(pass);
64
43
  }
65
- return this._hash[pass][renderPassType];
66
- }
67
- /** Render states associated to this material */ get stateSet() {
68
- if (!this._renderStateSet) {
69
- this._renderStateSet = this.createRenderStateSet();
70
- }
71
- return this._renderStateSet;
72
- }
73
- set stateSet(stateset) {
74
- this._renderStateSet = stateset;
44
+ return this._hash[pass];
75
45
  }
76
46
  getQueueType() {
77
47
  return QUEUE_OPAQUE;
78
48
  }
79
- /** Returns true if this is a transparency material */ isTransparentPass(pass) {
49
+ /** Returns true if given pass is transparent */ isTransparentPass(pass) {
80
50
  return false;
81
51
  }
82
52
  /** Returns true if shading of the material will be affected by lights */ supportLighting() {
83
53
  return true;
84
54
  }
55
+ /** Returns true if this material supports geometry instancing */ supportInstancing() {
56
+ return true;
57
+ }
85
58
  /** Returns true if this material supports geometry instancing */ isBatchable() {
86
59
  return false;
87
60
  }
88
- /**
89
- * Draws a primitive using this material
90
- *
91
- * @param primitive - The prmitive to be drawn
92
- * @param ctx - The context of current drawing task
93
- * @param numInstances - How many instances should be drawn. if zero, the instance count will be automatically detected.
94
- */ draw(primitive, ctx, numInstances = 0) {
95
- for(let i = 0; i < this._numPasses; i++){
96
- if (this.beginDraw(i, ctx)) {
97
- this.drawPrimitive(i, primitive, ctx, numInstances);
98
- this.endDraw(i);
99
- }
100
- }
61
+ /** @internal */ get coreMaterial() {
62
+ return this;
101
63
  }
102
64
  /**
103
- * Prepares for drawing
104
- * @param ctx - The context of current drawing task
105
- * @returns true if succeeded, otherwise false
106
- */ beginDraw(pass, ctx) {
107
- const device = Application.instance.device;
108
- const programInfo = this.getOrCreateProgram(ctx, pass);
109
- if (programInfo) {
110
- const hash = programInfo.hash;
111
- if (!programInfo.programs[ctx.renderPass.type]) {
112
- return false;
113
- }
114
- if (pass > 0) {
115
- this.optionChanged(false);
65
+ * Apply material
66
+ * @param ctx - Draw context
67
+ * @returns true if no error, otherwise false
68
+ */ apply(ctx) {
69
+ for(let pass = 0; pass < this._numPasses; pass++){
70
+ const hash = this.calcGlobalHash(ctx, pass);
71
+ let state = this._states[hash];
72
+ if (!state) {
73
+ const program = this.createProgram(ctx, pass) ?? null;
74
+ const bindGroup = program.bindGroupLayouts.length > 2 ? ctx.device.createBindGroup(program.bindGroupLayouts[2]) : null;
75
+ state = {
76
+ program,
77
+ bindGroup,
78
+ renderStateSet: ctx.device.createRenderStateSet(),
79
+ materialTag: -1
80
+ };
81
+ this._states[hash] = state;
116
82
  }
117
- this._materialBindGroup = this.applyMaterialBindGroups(ctx, hash, pass);
118
- if (pass === 0) {
119
- if (ctx.instanceData) {
120
- this.applyInstanceBindGroups(ctx, hash);
121
- } else {
122
- this.applyDrawableBindGroups(ctx, hash);
123
- }
83
+ if (!state.program) {
84
+ return false;
124
85
  }
125
- ctx.renderPass.applyRenderStates(device, this.stateSet, ctx);
126
- device.setProgram(programInfo.programs[ctx.renderPass.type]);
127
- Material._drawableTimestamps.set(ctx.target, ctx.timestamp);
128
- Material.lruPutDrawable(ctx.target);
129
- Material._materialTimestamps.set(this, ctx.timestamp);
130
- Material.lruPutMaterial(this);
131
- return true;
86
+ this.applyUniforms(state.bindGroup, ctx, state.materialTag !== this._optionTag, pass);
87
+ state.materialTag = this._optionTag;
88
+ this.updateRenderStates(pass, state.renderStateSet, ctx);
89
+ this._currentHash[pass] = hash;
132
90
  }
133
- return false;
134
91
  }
135
- /**
136
- * Ends drawing a primitive
137
- */ endDraw(pass) {
138
- this._materialBindGroup = null;
92
+ /** @internal */ bind(device, pass) {
93
+ const hash = this._currentHash[pass];
94
+ const state = this._states[hash];
95
+ if (!state) {
96
+ console.error('Material.bind() failed: state not found');
97
+ return false;
98
+ }
99
+ if (!state.program) {
100
+ return false;
101
+ }
102
+ device.setProgram(state.program);
103
+ device.setBindGroup(2, state.bindGroup);
104
+ device.setRenderStates(state.renderStateSet);
105
+ }
106
+ /** @internal */ calcGlobalHash(ctx, pass) {
107
+ return `${this.getHash(pass)}:${Number(!!ctx.skinAnimation)}:${Number(!!ctx.instancing)}:${ctx.renderPassHash}`;
139
108
  }
140
109
  /**
141
- * Gets the bind group of this material
142
- * @returns The bind group of this material
143
- */ getMaterialBindGroup() {
144
- return this._materialBindGroup;
110
+ * Draws a primitive using this material
111
+ * @internal
112
+ *
113
+ * @param primitive - The prmitive to be drawn
114
+ * @param ctx - The context of current drawing task
115
+ * @param numInstances - How many instances should be drawn. if zero, the instance count will be automatically detected.
116
+ */ draw(primitive, ctx, numInstances = 0) {
117
+ for(let pass = 0; pass < this._numPasses; pass++){
118
+ this.bind(ctx.device, pass);
119
+ this.drawPrimitive(pass, primitive, ctx, numInstances);
120
+ }
145
121
  }
146
122
  /**
147
123
  * Sets all uniform values to the bind group of the material if needed
@@ -153,222 +129,14 @@ import { ShaderHelper } from './shader/helper.js';
153
129
  this._applyUniforms(bindGroup, ctx, pass);
154
130
  }
155
131
  }
156
- /**
157
- * Fetch the gpu program of the material for drawing
158
- * @param ctx - The context for current drawing task
159
- * @returns Information of the gpu program
160
- */ getOrCreateProgram(ctx, pass) {
161
- const programMap = Material._programMap;
162
- const renderPassType = ctx.renderPass.type;
163
- const hash = `${this.getHash(renderPassType, pass)}:${!!ctx.target.getBoneMatrices()}:${Number(!!ctx.instanceData)}:${ctx.renderPassHash}`;
164
- let programInfo = programMap[hash];
165
- if (!programInfo || programInfo.programs[renderPassType] === undefined) {
166
- const program = this.createProgram(ctx, pass) ?? null;
167
- if (!programInfo) {
168
- programInfo = {
169
- programs: [
170
- null,
171
- null,
172
- null
173
- ],
174
- hash
175
- };
176
- programMap[hash] = programInfo;
177
- }
178
- programInfo.programs[renderPassType] = program;
179
- }
180
- return programInfo;
181
- }
182
- dispose() {
183
- this.clearBindGroupCache();
184
- }
185
- /**
186
- * Sets the options of garbage collection
187
- * @param opt - The options to set
188
- */ static setGCOptions(opt) {
189
- this._gcOptions = Object.assign({}, this._gcOptions, opt || {});
190
- }
191
- /**
192
- * Gets the options of garbage collection
193
- * @returns The options of garbage collection
194
- */ static getGCOptions() {
195
- return this._gcOptions;
196
- }
197
- /**
198
- * Performs a garbage collection for this material
199
- * @param ts - Current time stamp
200
- * @returns How many bind groups have been garbage collected
201
- */ static garbageCollect(ts) {
202
- let n = 0;
203
- ts -= this._gcOptions.inactiveTimeDuration;
204
- while(this._drawableLRU.length > this._gcOptions.drawableCountThreshold){
205
- const iter = this._drawableLRU.begin();
206
- if (this._drawableTimestamps.get(iter.data) < ts) {
207
- const bindGroups = this._drawableBindGroupMap.get(iter.data);
208
- if (bindGroups) {
209
- for(const k in bindGroups){
210
- for (const bindGroup of bindGroups[k].bindGroup){
211
- if (bindGroup) {
212
- this.bindGroupGarbageCollect(bindGroup);
213
- n++;
214
- }
215
- }
216
- }
217
- }
218
- this._drawableBindGroupMap.delete(iter.data);
219
- this._drawableIterators.delete(iter.data);
220
- this._drawableLRU.remove(iter);
221
- } else {
222
- break;
223
- }
224
- }
225
- while(this._materialLRU.length > this._gcOptions.materialCountThreshold){
226
- const iter = this._materialLRU.begin();
227
- const mat = iter.data;
228
- if (this._materialTimestamps.get(mat) < ts && mat._bindGroupMap) {
229
- n += mat.clearBindGroupCache();
230
- this._materialIterators.delete(mat);
231
- this._materialLRU.remove(iter);
232
- } else {
233
- break;
234
- }
235
- }
236
- if (n > 0 && this._gcOptions.verbose) {
237
- console.log(`INFO: ${n} bind groups have been garbage collected`);
238
- }
239
- return n;
240
- }
241
132
  /** @internal */ optionChanged(changeHash) {
242
133
  this._optionTag++;
243
134
  if (changeHash) {
244
135
  for(let i = 0; i < this._numPasses; i++){
245
- this._hash[i] = [];
136
+ this._hash[i] = null;
246
137
  }
247
138
  }
248
139
  }
249
- /** @internal */ static getProgramByHashIndex(hash, index) {
250
- return this._programMap[hash].programs[index];
251
- }
252
- /** @internal */ applyMaterialBindGroups(ctx, hash, pass) {
253
- const index = ctx.renderPass.type;
254
- let bindGroupInfo = this._bindGroupMap[hash];
255
- if (!bindGroupInfo) {
256
- // bindGroups not created or have been garbage collected
257
- const materialBindGroup = [
258
- RENDER_PASS_TYPE_LIGHT,
259
- RENDER_PASS_TYPE_SHADOWMAP,
260
- RENDER_PASS_TYPE_DEPTH
261
- ].map((k)=>{
262
- const program = Material._programMap[hash].programs[k];
263
- return program?.bindGroupLayouts[2] ? Application.instance.device.createBindGroup(program.bindGroupLayouts[2]) : null;
264
- });
265
- bindGroupInfo = this._bindGroupMap[hash] = {
266
- materialBindGroup,
267
- bindGroupTag: [
268
- 0,
269
- 0,
270
- 0
271
- ],
272
- materialTag: [
273
- -1,
274
- -1,
275
- -1
276
- ]
277
- };
278
- }
279
- const bindGroup = bindGroupInfo.materialBindGroup[index];
280
- if (bindGroup) {
281
- this.applyUniforms(bindGroup, ctx, bindGroupInfo.materialTag[index] < this._optionTag || bindGroupInfo.bindGroupTag[index] !== bindGroup.cid, pass);
282
- bindGroupInfo.materialTag[index] = this._optionTag;
283
- bindGroupInfo.bindGroupTag[index] = bindGroup.cid;
284
- Application.instance.device.setBindGroup(2, bindGroup);
285
- } else {
286
- Application.instance.device.setBindGroup(2, null);
287
- }
288
- return bindGroup;
289
- }
290
- /** @internal */ getDrawableBindGroup(ctx, hash) {
291
- let drawableBindGroups = Material._drawableBindGroupMap.get(ctx.target);
292
- if (!drawableBindGroups) {
293
- drawableBindGroups = {};
294
- Material._drawableBindGroupMap.set(ctx.target, drawableBindGroups);
295
- }
296
- let drawableBindGroup = drawableBindGroups[hash];
297
- if (!drawableBindGroup) {
298
- const bindGroup = [
299
- RENDER_PASS_TYPE_LIGHT,
300
- RENDER_PASS_TYPE_SHADOWMAP,
301
- RENDER_PASS_TYPE_DEPTH
302
- ].map((k)=>{
303
- const program = Material._programMap[hash].programs[k];
304
- return program?.bindGroupLayouts[1] ? Application.instance.device.createBindGroup(program.bindGroupLayouts[1]) : null;
305
- });
306
- drawableBindGroup = drawableBindGroups[hash] = {
307
- bindGroup,
308
- bindGroupTag: [
309
- 0,
310
- 0,
311
- 0
312
- ],
313
- xformTag: [
314
- -1,
315
- -1,
316
- -1
317
- ]
318
- };
319
- }
320
- return drawableBindGroup;
321
- }
322
- /** @internal */ applyInstanceBindGroups(ctx, hash) {
323
- if (ctx.instanceData) {
324
- if (ctx.instanceData.bindGroup.dirty) {
325
- ctx.instanceData.bindGroup.bindGroup.setRawData(ShaderHelper.getWorldMatricesUniformName(), 0, ctx.instanceData.bindGroup.buffer, 0, ctx.instanceData.currentSize * 4);
326
- ctx.instanceData.bindGroup.dirty = false;
327
- }
328
- Application.instance.device.setBindGroup(3, ctx.instanceData.bindGroup.bindGroup ?? null);
329
- } else {
330
- Application.instance.device.setBindGroup(3, null);
331
- }
332
- const bindGroup = this.getDrawableBindGroup(ctx, hash).bindGroup?.[ctx.renderPass.type];
333
- if (bindGroup) {
334
- if (ctx.instanceData) {
335
- bindGroup.setValue(ShaderHelper.getInstanceBufferStrideUniformName(), ctx.instanceData.stride);
336
- }
337
- Application.instance.device.setBindGroup(1, bindGroup);
338
- } else {
339
- Application.instance.device.setBindGroup(1, null);
340
- }
341
- }
342
- /** @internal */ applyDrawableBindGroups(ctx, hash) {
343
- const device = Application.instance.device;
344
- const index = ctx.renderPass.type;
345
- const drawableBindGroup = this.getDrawableBindGroup(ctx, hash);
346
- if (drawableBindGroup.bindGroup) {
347
- const bindGroup = drawableBindGroup.bindGroup[index];
348
- if (drawableBindGroup.xformTag[index] < ctx.target.getXForm().getTag() || drawableBindGroup.bindGroupTag[index] !== bindGroup.cid) {
349
- bindGroup.setValue(ShaderHelper.getWorldMatrixUniformName(), ctx.target.getXForm().worldMatrix);
350
- drawableBindGroup.xformTag[index] = ctx.target.getXForm().getTag();
351
- drawableBindGroup.bindGroupTag[index] = bindGroup.cid;
352
- }
353
- const boneMatrices = ctx.target.getBoneMatrices();
354
- if (boneMatrices) {
355
- if (!Material._boneMatrixTextureSampler) {
356
- Material._boneMatrixTextureSampler = device.createSampler({
357
- magFilter: 'nearest',
358
- minFilter: 'nearest',
359
- mipFilter: 'none'
360
- });
361
- }
362
- bindGroup.setTexture(ShaderHelper.getBoneMatricesUniformName(), boneMatrices);
363
- bindGroup.setValue(ShaderHelper.getBoneTextureSizeUniformName(), boneMatrices.width);
364
- bindGroup.setValue(ShaderHelper.getBoneInvBindMatrixUniformName(), ctx.target.getInvBindMatrix());
365
- }
366
- device.setBindGroup(1, bindGroup);
367
- } else {
368
- device.setBindGroup(1, null);
369
- }
370
- device.setBindGroup(3, null);
371
- }
372
140
  /**
373
141
  * Convert pass to hash
374
142
  * @param pass - pass number
@@ -376,47 +144,8 @@ import { ShaderHelper } from './shader/helper.js';
376
144
  */ passToHash(pass) {
377
145
  return String(pass);
378
146
  }
379
- /** @internal */ createHash(renderPassType, pass) {
380
- return `${this.constructor.name}|${this.passToHash(pass)}|${this._createHash(renderPassType)}`;
381
- }
382
- /** @internal */ clearBindGroupCache() {
383
- let n = 0;
384
- for(const k in this._bindGroupMap){
385
- for (const bindGroup of this._bindGroupMap[k].materialBindGroup){
386
- if (bindGroup) {
387
- Material.bindGroupGarbageCollect(bindGroup);
388
- n++;
389
- }
390
- }
391
- }
392
- this._bindGroupMap = {};
393
- return n;
394
- }
395
- /** @internal */ static bindGroupGarbageCollect(bindGroup) {
396
- const layout = bindGroup.getLayout();
397
- for (const entry of layout.entries){
398
- if (entry.buffer) {
399
- const buffer = bindGroup.getBuffer(entry.name);
400
- if (buffer) {
401
- buffer.dispose();
402
- bindGroup.setBuffer(entry.name, null);
403
- }
404
- }
405
- }
406
- }
407
- /** @internal */ static lruPutDrawable(drawable) {
408
- const iter = this._drawableIterators.get(drawable);
409
- if (iter) {
410
- this._drawableLRU.remove(iter);
411
- }
412
- this._drawableIterators.set(drawable, this._drawableLRU.append(drawable));
413
- }
414
- /** @internal */ static lruPutMaterial(material) {
415
- const iter = this._materialIterators.get(material);
416
- if (iter) {
417
- this._materialLRU.remove(iter);
418
- }
419
- this._materialIterators.set(material, this._materialLRU.append(material));
147
+ /** @internal */ createHash(pass) {
148
+ return `${this.constructor.name}|${pass}|${this._createHash()}`;
420
149
  }
421
150
  /**
422
151
  * Draw primitve
@@ -427,18 +156,15 @@ import { ShaderHelper } from './shader/helper.js';
427
156
  if (numInstances > 0) {
428
157
  primitive.drawInstanced(numInstances);
429
158
  } else if (ctx.instanceData) {
430
- primitive.drawInstanced(ctx.instanceData.currentSize / ctx.instanceData.stride);
159
+ primitive.drawInstanced(ctx.instanceData.numInstances);
431
160
  } else {
432
161
  primitive.draw();
433
162
  }
434
163
  }
435
164
  /** @internal */ createProgram(ctx, pass) {
436
- const pb = new ProgramBuilder(Application.instance.device);
165
+ const pb = new ProgramBuilder(ctx.device);
437
166
  return this._createProgram(pb, ctx, pass);
438
167
  }
439
- /** @internal */ createRenderStateSet() {
440
- return Application.instance.device.createRenderStateSet();
441
- }
442
168
  /**
443
169
  * Creates the shader program
444
170
  * @param pb - The program builder
@@ -454,9 +180,15 @@ import { ShaderHelper } from './shader/helper.js';
454
180
  * @param ctx - The drawing context
455
181
  */ _applyUniforms(bindGroup, ctx, pass) {}
456
182
  /**
183
+ * Update render states according to draw context and current material pass
184
+ * @param pass - Current material pass
185
+ * @param renderStates - Render state set to be updated
186
+ * @param ctx - Draw context
187
+ */ updateRenderStates(pass, renderStates, ctx) {}
188
+ /**
457
189
  * Calculates the hash code of the shader program
458
190
  * @returns The hash code
459
- */ _createHash(renderPassType) {
191
+ */ _createHash() {
460
192
  return '';
461
193
  }
462
194
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"material.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"material.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}