@zephyr3d/scene 0.3.1 → 0.5.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 (174) hide show
  1. package/dist/animation/animation.js +25 -117
  2. package/dist/animation/animation.js.map +1 -1
  3. package/dist/animation/animationset.js +164 -24
  4. package/dist/animation/animationset.js.map +1 -1
  5. package/dist/animation/animationtrack.js +6 -18
  6. package/dist/animation/animationtrack.js.map +1 -1
  7. package/dist/animation/eulerrotationtrack.js +16 -6
  8. package/dist/animation/eulerrotationtrack.js.map +1 -1
  9. package/dist/animation/morphtarget.js +104 -0
  10. package/dist/animation/morphtarget.js.map +1 -0
  11. package/dist/animation/morphtrack.js +68 -0
  12. package/dist/animation/morphtrack.js.map +1 -0
  13. package/dist/animation/rotationtrack.js +15 -7
  14. package/dist/animation/rotationtrack.js.map +1 -1
  15. package/dist/animation/scaletrack.js +15 -7
  16. package/dist/animation/scaletrack.js.map +1 -1
  17. package/dist/animation/skeleton.js +101 -1
  18. package/dist/animation/skeleton.js.map +1 -1
  19. package/dist/animation/translationtrack.js +15 -7
  20. package/dist/animation/translationtrack.js.map +1 -1
  21. package/dist/animation/usertrack.js +2 -2
  22. package/dist/app.js +4 -26
  23. package/dist/app.js.map +1 -1
  24. package/dist/asset/assetmanager.js +58 -107
  25. package/dist/asset/assetmanager.js.map +1 -1
  26. package/dist/asset/loaders/dds/dds.js +77 -3
  27. package/dist/asset/loaders/dds/dds.js.map +1 -1
  28. package/dist/asset/loaders/dds/dds_loader.js +1 -1
  29. package/dist/asset/loaders/gltf/gltf_loader.js +284 -45
  30. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  31. package/dist/asset/loaders/image/tga_Loader.js +1 -1
  32. package/dist/asset/model.js +13 -0
  33. package/dist/asset/model.js.map +1 -1
  34. package/dist/blitter/blitter.js +2 -2
  35. package/dist/camera/camera.js +83 -5
  36. package/dist/camera/camera.js.map +1 -1
  37. package/dist/index.d.ts +5212 -4785
  38. package/dist/index.js +6 -7
  39. package/dist/index.js.map +1 -1
  40. package/dist/material/blinn.js +9 -4
  41. package/dist/material/blinn.js.map +1 -1
  42. package/dist/material/grassmat.js +127 -0
  43. package/dist/material/grassmat.js.map +1 -0
  44. package/dist/material/grassmaterial.js +15 -0
  45. package/dist/material/grassmaterial.js.map +1 -1
  46. package/dist/material/lambert.js +22 -17
  47. package/dist/material/lambert.js.map +1 -1
  48. package/dist/material/lightmodel.js +7 -6
  49. package/dist/material/lightmodel.js.map +1 -1
  50. package/dist/material/lit.js +99 -5
  51. package/dist/material/lit.js.map +1 -1
  52. package/dist/material/material.js +88 -347
  53. package/dist/material/material.js.map +1 -1
  54. package/dist/material/meshmaterial.js +122 -102
  55. package/dist/material/meshmaterial.js.map +1 -1
  56. package/dist/material/mixins/albedocolor.js +11 -3
  57. package/dist/material/mixins/albedocolor.js.map +1 -1
  58. package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
  59. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +3 -3
  60. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  61. package/dist/material/mixins/lit.js +2 -2
  62. package/dist/material/mixins/pbr/common.js +433 -10
  63. package/dist/material/mixins/pbr/common.js.map +1 -1
  64. package/dist/material/pbrmr.js +17 -6
  65. package/dist/material/pbrmr.js.map +1 -1
  66. package/dist/material/pbrsg.js +16 -9
  67. package/dist/material/pbrsg.js.map +1 -1
  68. package/dist/material/shader/helper.js +186 -117
  69. package/dist/material/shader/helper.js.map +1 -1
  70. package/dist/material/terrainlightmodel.js +3 -1
  71. package/dist/material/terrainlightmodel.js.map +1 -1
  72. package/dist/material/terrainmat.js +357 -0
  73. package/dist/material/terrainmat.js.map +1 -0
  74. package/dist/material/terrainmaterial.js +16 -0
  75. package/dist/material/terrainmaterial.js.map +1 -1
  76. package/dist/material/unlit.js +8 -4
  77. package/dist/material/unlit.js.map +1 -1
  78. package/dist/posteffect/bloom.js +34 -45
  79. package/dist/posteffect/bloom.js.map +1 -1
  80. package/dist/posteffect/compositor.js +11 -41
  81. package/dist/posteffect/compositor.js.map +1 -1
  82. package/dist/posteffect/fxaa.js +1 -2
  83. package/dist/posteffect/fxaa.js.map +1 -1
  84. package/dist/posteffect/grayscale.js +1 -2
  85. package/dist/posteffect/grayscale.js.map +1 -1
  86. package/dist/posteffect/posteffect.js +0 -74
  87. package/dist/posteffect/posteffect.js.map +1 -1
  88. package/dist/posteffect/sao.js +13 -29
  89. package/dist/posteffect/sao.js.map +1 -1
  90. package/dist/posteffect/tonemap.js +1 -2
  91. package/dist/posteffect/tonemap.js.map +1 -1
  92. package/dist/posteffect/water.js +20 -18
  93. package/dist/posteffect/water.js.map +1 -1
  94. package/dist/render/abuffer_oit.js +352 -0
  95. package/dist/render/abuffer_oit.js.map +1 -0
  96. package/dist/render/cull_visitor.js +3 -3
  97. package/dist/render/depth_pass.js +3 -2
  98. package/dist/render/depth_pass.js.map +1 -1
  99. package/dist/render/depthpass.js +16 -19
  100. package/dist/render/depthpass.js.map +1 -1
  101. package/dist/render/drawable_mixin.js +152 -0
  102. package/dist/render/drawable_mixin.js.map +1 -0
  103. package/dist/render/envlight.js +165 -31
  104. package/dist/render/envlight.js.map +1 -1
  105. package/dist/render/forward.js +3 -6
  106. package/dist/render/forward.js.map +1 -1
  107. package/dist/render/forward_pass.js +6 -5
  108. package/dist/render/forward_pass.js.map +1 -1
  109. package/dist/render/globalbindgroup_allocator.js +58 -0
  110. package/dist/render/globalbindgroup_allocator.js.map +1 -0
  111. package/dist/render/lightpass.js +83 -49
  112. package/dist/render/lightpass.js.map +1 -1
  113. package/dist/render/objectcolorpass.js +50 -0
  114. package/dist/render/objectcolorpass.js.map +1 -0
  115. package/dist/render/objectpool.js +295 -0
  116. package/dist/render/objectpool.js.map +1 -0
  117. package/dist/render/oit.js +16 -0
  118. package/dist/render/oit.js.map +1 -0
  119. package/dist/render/render_queue.js +294 -107
  120. package/dist/render/render_queue.js.map +1 -1
  121. package/dist/render/renderbundle_wrapper.js +20 -0
  122. package/dist/render/renderbundle_wrapper.js.map +1 -0
  123. package/dist/render/renderer.js +108 -28
  124. package/dist/render/renderer.js.map +1 -1
  125. package/dist/render/renderpass.js +96 -34
  126. package/dist/render/renderpass.js.map +1 -1
  127. package/dist/render/shadowmap_pass.js +18 -37
  128. package/dist/render/shadowmap_pass.js.map +1 -1
  129. package/dist/render/sky.js +2 -2
  130. package/dist/render/watermesh.js +140 -48
  131. package/dist/render/watermesh.js.map +1 -1
  132. package/dist/render/weightedblended_oit.js +171 -0
  133. package/dist/render/weightedblended_oit.js.map +1 -0
  134. package/dist/scene/batchgroup.js +8 -35
  135. package/dist/scene/batchgroup.js.map +1 -1
  136. package/dist/scene/environment.js +24 -4
  137. package/dist/scene/environment.js.map +1 -1
  138. package/dist/scene/graph_node.js +1 -10
  139. package/dist/scene/graph_node.js.map +1 -1
  140. package/dist/scene/mesh.js +42 -32
  141. package/dist/scene/mesh.js.map +1 -1
  142. package/dist/scene/scene.js +7 -37
  143. package/dist/scene/scene.js.map +1 -1
  144. package/dist/scene/scene_node.js +6 -2
  145. package/dist/scene/scene_node.js.map +1 -1
  146. package/dist/scene/terrain/grass.js +26 -11
  147. package/dist/scene/terrain/grass.js.map +1 -1
  148. package/dist/scene/terrain/patch.js +27 -15
  149. package/dist/scene/terrain/patch.js.map +1 -1
  150. package/dist/scene/terrain/quadtree.js +3 -3
  151. package/dist/scene/terrain/terrain.js +0 -8
  152. package/dist/scene/terrain/terrain.js.map +1 -1
  153. package/dist/shaders/lighting.js +14 -10
  154. package/dist/shaders/lighting.js.map +1 -1
  155. package/dist/shaders/water.js +4 -4
  156. package/dist/shadow/esm.js +4 -23
  157. package/dist/shadow/esm.js.map +1 -1
  158. package/dist/shadow/shadowmapper.js +45 -21
  159. package/dist/shadow/shadowmapper.js.map +1 -1
  160. package/dist/shadow/vsm.js +4 -25
  161. package/dist/shadow/vsm.js.map +1 -1
  162. package/dist/utility/draco/decoder.js +116 -0
  163. package/dist/utility/draco/decoder.js.map +1 -0
  164. package/dist/utility/sheenlut.js +196 -0
  165. package/dist/utility/sheenlut.js.map +1 -0
  166. package/dist/values.js +18 -1
  167. package/dist/values.js.map +1 -1
  168. package/package.json +7 -6
  169. package/dist/utility/noisetexture.js +0 -66
  170. package/dist/utility/noisetexture.js.map +0 -1
  171. package/dist/utility/textures/gradientnoise.js +0 -66
  172. package/dist/utility/textures/gradientnoise.js.map +0 -1
  173. package/dist/utility/textures/randomnoise.js +0 -41
  174. package/dist/utility/textures/randomnoise.js.map +0 -1
@@ -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,24 @@ 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 */ static _programCache = {};
11
+ /** @internal */ _states;
29
12
  /** @internal */ _numPasses;
30
13
  /** @internal */ _hash;
31
- /** @internal */ _renderStateSet;
32
- /** @internal */ _bindGroupMap;
33
14
  /** @internal */ _optionTag;
34
- /** @internal */ _materialBindGroup;
35
15
  /** @internal */ _id;
16
+ /** @internal */ _currentHash;
36
17
  /**
37
18
  * Creates an instance of material
38
19
  */ constructor(){
39
20
  this._id = ++Material._nextId;
21
+ this._states = {};
40
22
  this._numPasses = 1;
41
23
  this._hash = [
42
- []
24
+ null
43
25
  ];
44
- this._renderStateSet = null;
45
- this._bindGroupMap = {};
46
26
  this._optionTag = 0;
47
- this._materialBindGroup = null;
27
+ this._currentHash = [];
48
28
  }
49
29
  /** Unique identifier of the material */ get instanceId() {
50
30
  return this._id;
@@ -54,94 +34,99 @@ import { ShaderHelper } from './shader/helper.js';
54
34
  }
55
35
  set numPasses(val) {
56
36
  while(this._hash.length < val){
57
- this._hash.push([]);
37
+ this._hash.push(null);
58
38
  }
59
39
  this._numPasses = val;
60
40
  }
61
- /** @internal */ getHash(renderPassType, pass) {
62
- if (this._hash[pass][renderPassType] === void 0) {
63
- this._hash[pass][renderPassType] = this.createHash(renderPassType, pass);
41
+ /** @internal */ getHash(pass) {
42
+ if (this._hash[pass] === null) {
43
+ this._hash[pass] = this.createHash(pass);
64
44
  }
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;
45
+ return this._hash[pass];
75
46
  }
76
47
  getQueueType() {
77
48
  return QUEUE_OPAQUE;
78
49
  }
79
- /** Returns true if this is a transparency material */ isTransparentPass(pass) {
50
+ /** Returns true if given pass is transparent */ isTransparentPass(pass) {
80
51
  return false;
81
52
  }
82
53
  /** Returns true if shading of the material will be affected by lights */ supportLighting() {
83
54
  return true;
84
55
  }
56
+ /** Returns true if this material supports geometry instancing */ supportInstancing() {
57
+ return true;
58
+ }
85
59
  /** Returns true if this material supports geometry instancing */ isBatchable() {
86
60
  return false;
87
61
  }
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
- }
62
+ /** Return true if this material requires the scene color texture */ needSceneColor() {
63
+ return false;
64
+ }
65
+ /** @internal */ get coreMaterial() {
66
+ return this;
101
67
  }
102
68
  /**
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);
116
- }
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);
69
+ * Apply material
70
+ * @param ctx - Draw context
71
+ * @returns true if no error, otherwise false
72
+ */ apply(ctx) {
73
+ for(let pass = 0; pass < this._numPasses; pass++){
74
+ const hash = this.calcGlobalHash(ctx, pass);
75
+ let state = this._states[hash];
76
+ if (!state) {
77
+ const programHash = `${this.constructor.name}:${hash}`;
78
+ let program = Material._programCache[programHash];
79
+ if (!program) {
80
+ program = this.createProgram(ctx, pass) ?? null;
81
+ Material._programCache[programHash] = program;
123
82
  }
83
+ const bindGroup = program.bindGroupLayouts.length > 2 ? ctx.device.createBindGroup(program.bindGroupLayouts[2]) : null;
84
+ state = {
85
+ program,
86
+ bindGroup,
87
+ renderStateSet: ctx.device.createRenderStateSet(),
88
+ materialTag: -1
89
+ };
90
+ this._states[hash] = state;
91
+ }
92
+ if (!state.program) {
93
+ return false;
124
94
  }
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;
95
+ this.applyUniforms(state.bindGroup, ctx, state.materialTag !== this._optionTag, pass);
96
+ state.materialTag = this._optionTag;
97
+ this.updateRenderStates(pass, state.renderStateSet, ctx);
98
+ this._currentHash[pass] = hash;
132
99
  }
133
- return false;
134
100
  }
135
- /**
136
- * Ends drawing a primitive
137
- */ endDraw(pass) {
138
- this._materialBindGroup = null;
101
+ /** @internal */ bind(device, pass) {
102
+ const hash = this._currentHash[pass];
103
+ const state = this._states[hash];
104
+ if (!state) {
105
+ console.error('Material.bind() failed: state not found');
106
+ return false;
107
+ }
108
+ if (!state.program) {
109
+ return false;
110
+ }
111
+ device.setProgram(state.program);
112
+ device.setBindGroup(2, state.bindGroup);
113
+ device.setRenderStates(state.renderStateSet);
114
+ }
115
+ /** @internal */ calcGlobalHash(ctx, pass) {
116
+ return `${this.getHash(pass)}:${Number(!!ctx.morphAnimation)}${Number(!!ctx.skinAnimation)}:${Number(!!ctx.instancing)}:${ctx.renderPassHash}`;
139
117
  }
140
118
  /**
141
- * Gets the bind group of this material
142
- * @returns The bind group of this material
143
- */ getMaterialBindGroup() {
144
- return this._materialBindGroup;
119
+ * Draws a primitive using this material
120
+ * @internal
121
+ *
122
+ * @param primitive - The prmitive to be drawn
123
+ * @param ctx - The context of current drawing task
124
+ * @param numInstances - How many instances should be drawn. if zero, the instance count will be automatically detected.
125
+ */ draw(primitive, ctx, numInstances = 0) {
126
+ for(let pass = 0; pass < this._numPasses; pass++){
127
+ this.bind(ctx.device, pass);
128
+ this.drawPrimitive(pass, primitive, ctx, numInstances);
129
+ }
145
130
  }
146
131
  /**
147
132
  * Sets all uniform values to the bind group of the material if needed
@@ -153,222 +138,14 @@ import { ShaderHelper } from './shader/helper.js';
153
138
  this._applyUniforms(bindGroup, ctx, pass);
154
139
  }
155
140
  }
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
141
  /** @internal */ optionChanged(changeHash) {
242
142
  this._optionTag++;
243
143
  if (changeHash) {
244
144
  for(let i = 0; i < this._numPasses; i++){
245
- this._hash[i] = [];
145
+ this._hash[i] = null;
246
146
  }
247
147
  }
248
148
  }
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
149
  /**
373
150
  * Convert pass to hash
374
151
  * @param pass - pass number
@@ -376,47 +153,8 @@ import { ShaderHelper } from './shader/helper.js';
376
153
  */ passToHash(pass) {
377
154
  return String(pass);
378
155
  }
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));
156
+ /** @internal */ createHash(pass) {
157
+ return `${this.constructor.name}|${pass}|${this._createHash()}`;
420
158
  }
421
159
  /**
422
160
  * Draw primitve
@@ -427,18 +165,15 @@ import { ShaderHelper } from './shader/helper.js';
427
165
  if (numInstances > 0) {
428
166
  primitive.drawInstanced(numInstances);
429
167
  } else if (ctx.instanceData) {
430
- primitive.drawInstanced(ctx.instanceData.currentSize / ctx.instanceData.stride);
168
+ primitive.drawInstanced(ctx.instanceData.numInstances);
431
169
  } else {
432
170
  primitive.draw();
433
171
  }
434
172
  }
435
173
  /** @internal */ createProgram(ctx, pass) {
436
- const pb = new ProgramBuilder(Application.instance.device);
174
+ const pb = new ProgramBuilder(ctx.device);
437
175
  return this._createProgram(pb, ctx, pass);
438
176
  }
439
- /** @internal */ createRenderStateSet() {
440
- return Application.instance.device.createRenderStateSet();
441
- }
442
177
  /**
443
178
  * Creates the shader program
444
179
  * @param pb - The program builder
@@ -454,9 +189,15 @@ import { ShaderHelper } from './shader/helper.js';
454
189
  * @param ctx - The drawing context
455
190
  */ _applyUniforms(bindGroup, ctx, pass) {}
456
191
  /**
192
+ * Update render states according to draw context and current material pass
193
+ * @param pass - Current material pass
194
+ * @param renderStates - Render state set to be updated
195
+ * @param ctx - Draw context
196
+ */ updateRenderStates(pass, renderStates, ctx) {}
197
+ /**
457
198
  * Calculates the hash code of the shader program
458
199
  * @returns The hash code
459
- */ _createHash(renderPassType) {
200
+ */ _createHash() {
460
201
  return '';
461
202
  }
462
203
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"material.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"material.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}