@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.
- package/dist/animation/animation.js +25 -117
- package/dist/animation/animation.js.map +1 -1
- package/dist/animation/animationset.js +164 -24
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/animationtrack.js +6 -18
- package/dist/animation/animationtrack.js.map +1 -1
- package/dist/animation/eulerrotationtrack.js +16 -6
- package/dist/animation/eulerrotationtrack.js.map +1 -1
- package/dist/animation/morphtarget.js +104 -0
- package/dist/animation/morphtarget.js.map +1 -0
- package/dist/animation/morphtrack.js +68 -0
- package/dist/animation/morphtrack.js.map +1 -0
- package/dist/animation/rotationtrack.js +15 -7
- package/dist/animation/rotationtrack.js.map +1 -1
- package/dist/animation/scaletrack.js +15 -7
- package/dist/animation/scaletrack.js.map +1 -1
- package/dist/animation/skeleton.js +101 -1
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/translationtrack.js +15 -7
- package/dist/animation/translationtrack.js.map +1 -1
- package/dist/animation/usertrack.js +2 -2
- package/dist/app.js +4 -26
- package/dist/app.js.map +1 -1
- package/dist/asset/assetmanager.js +58 -107
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/dds/dds.js +77 -3
- package/dist/asset/loaders/dds/dds.js.map +1 -1
- package/dist/asset/loaders/dds/dds_loader.js +1 -1
- package/dist/asset/loaders/gltf/gltf_loader.js +284 -45
- package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
- package/dist/asset/loaders/image/tga_Loader.js +1 -1
- package/dist/asset/model.js +13 -0
- package/dist/asset/model.js.map +1 -1
- package/dist/blitter/blitter.js +2 -2
- package/dist/camera/camera.js +83 -5
- package/dist/camera/camera.js.map +1 -1
- package/dist/index.d.ts +5212 -4785
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +9 -4
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/grassmat.js +127 -0
- package/dist/material/grassmat.js.map +1 -0
- package/dist/material/grassmaterial.js +15 -0
- package/dist/material/grassmaterial.js.map +1 -1
- package/dist/material/lambert.js +22 -17
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/lightmodel.js +7 -6
- package/dist/material/lightmodel.js.map +1 -1
- package/dist/material/lit.js +99 -5
- package/dist/material/lit.js.map +1 -1
- package/dist/material/material.js +88 -347
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +122 -102
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +11 -3
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +3 -3
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
- package/dist/material/mixins/lit.js +2 -2
- package/dist/material/mixins/pbr/common.js +433 -10
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/pbrmr.js +17 -6
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +16 -9
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +186 -117
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/terrainlightmodel.js +3 -1
- package/dist/material/terrainlightmodel.js.map +1 -1
- package/dist/material/terrainmat.js +357 -0
- package/dist/material/terrainmat.js.map +1 -0
- package/dist/material/terrainmaterial.js +16 -0
- package/dist/material/terrainmaterial.js.map +1 -1
- package/dist/material/unlit.js +8 -4
- package/dist/material/unlit.js.map +1 -1
- package/dist/posteffect/bloom.js +34 -45
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js +11 -41
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/fxaa.js +1 -2
- package/dist/posteffect/fxaa.js.map +1 -1
- package/dist/posteffect/grayscale.js +1 -2
- package/dist/posteffect/grayscale.js.map +1 -1
- package/dist/posteffect/posteffect.js +0 -74
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/sao.js +13 -29
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/tonemap.js +1 -2
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/posteffect/water.js +20 -18
- package/dist/posteffect/water.js.map +1 -1
- package/dist/render/abuffer_oit.js +352 -0
- package/dist/render/abuffer_oit.js.map +1 -0
- package/dist/render/cull_visitor.js +3 -3
- package/dist/render/depth_pass.js +3 -2
- package/dist/render/depth_pass.js.map +1 -1
- package/dist/render/depthpass.js +16 -19
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +152 -0
- package/dist/render/drawable_mixin.js.map +1 -0
- package/dist/render/envlight.js +165 -31
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/forward.js +3 -6
- package/dist/render/forward.js.map +1 -1
- package/dist/render/forward_pass.js +6 -5
- package/dist/render/forward_pass.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +58 -0
- package/dist/render/globalbindgroup_allocator.js.map +1 -0
- package/dist/render/lightpass.js +83 -49
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/objectcolorpass.js +50 -0
- package/dist/render/objectcolorpass.js.map +1 -0
- package/dist/render/objectpool.js +295 -0
- package/dist/render/objectpool.js.map +1 -0
- package/dist/render/oit.js +16 -0
- package/dist/render/oit.js.map +1 -0
- package/dist/render/render_queue.js +294 -107
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderbundle_wrapper.js +20 -0
- package/dist/render/renderbundle_wrapper.js.map +1 -0
- package/dist/render/renderer.js +108 -28
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/renderpass.js +96 -34
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/shadowmap_pass.js +18 -37
- package/dist/render/shadowmap_pass.js.map +1 -1
- package/dist/render/sky.js +2 -2
- package/dist/render/watermesh.js +140 -48
- package/dist/render/watermesh.js.map +1 -1
- package/dist/render/weightedblended_oit.js +171 -0
- package/dist/render/weightedblended_oit.js.map +1 -0
- package/dist/scene/batchgroup.js +8 -35
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +24 -4
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/graph_node.js +1 -10
- package/dist/scene/graph_node.js.map +1 -1
- package/dist/scene/mesh.js +42 -32
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/scene.js +7 -37
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +6 -2
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain/grass.js +26 -11
- package/dist/scene/terrain/grass.js.map +1 -1
- package/dist/scene/terrain/patch.js +27 -15
- package/dist/scene/terrain/patch.js.map +1 -1
- package/dist/scene/terrain/quadtree.js +3 -3
- package/dist/scene/terrain/terrain.js +0 -8
- package/dist/scene/terrain/terrain.js.map +1 -1
- package/dist/shaders/lighting.js +14 -10
- package/dist/shaders/lighting.js.map +1 -1
- package/dist/shaders/water.js +4 -4
- package/dist/shadow/esm.js +4 -23
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/shadowmapper.js +45 -21
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/vsm.js +4 -25
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/utility/draco/decoder.js +116 -0
- package/dist/utility/draco/decoder.js.map +1 -0
- package/dist/utility/sheenlut.js +196 -0
- package/dist/utility/sheenlut.js.map +1 -0
- package/dist/values.js +18 -1
- package/dist/values.js.map +1 -1
- package/package.json +7 -6
- package/dist/utility/noisetexture.js +0 -66
- package/dist/utility/noisetexture.js.map +0 -1
- package/dist/utility/textures/gradientnoise.js +0 -66
- package/dist/utility/textures/gradientnoise.js.map +0 -1
- package/dist/utility/textures/randomnoise.js +0 -41
- 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 {
|
|
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
|
|
14
|
-
/** @internal */
|
|
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.
|
|
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(
|
|
62
|
-
if (this._hash[pass]
|
|
63
|
-
this._hash[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]
|
|
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
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
*
|
|
104
|
-
* @param ctx -
|
|
105
|
-
* @returns true if
|
|
106
|
-
*/
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
*
|
|
142
|
-
* @
|
|
143
|
-
|
|
144
|
-
|
|
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(
|
|
380
|
-
return `${this.constructor.name}|${
|
|
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.
|
|
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(
|
|
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(
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|