@zephyr3d/scene 0.1.1 → 0.2.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/asset/assetmanager.js +124 -67
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/builtin.js +2 -2
- package/dist/asset/loaders/gltf/gltf_loader.js +105 -59
- package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
- package/dist/asset/loaders/hdr/hdr.js +1 -1
- package/dist/blitter/blitter.js +0 -1
- package/dist/blitter/blitter.js.map +1 -1
- package/dist/blitter/depthlimitedgaussion.js +0 -1
- package/dist/blitter/depthlimitedgaussion.js.map +1 -1
- package/dist/blitter/gaussianblur.js +0 -1
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/camera.js +10 -8
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/orbit.js +24 -7
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +1842 -2484
- package/dist/index.js +21 -10
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +47 -57
- 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 +66 -194
- package/dist/material/grassmaterial.js.map +1 -1
- package/dist/material/lambert.js +48 -22
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/lightmodel.js +4 -4
- package/dist/material/material.js +100 -59
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +227 -186
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +29 -100
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/foliage.js +47 -0
- package/dist/material/mixins/foliage.js.map +1 -0
- package/dist/material/mixins/ggxlut.js +213 -0
- package/dist/material/mixins/ggxlut.js.map +1 -0
- package/dist/material/mixins/lightmodel/blinnphong.js +89 -0
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -0
- package/dist/material/mixins/lightmodel/lambert.js +58 -0
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -0
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +132 -0
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -0
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +105 -0
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -0
- package/dist/material/mixins/lit.js +464 -0
- package/dist/material/mixins/lit.js.map +1 -0
- package/dist/material/mixins/pbr/common.js +451 -0
- package/dist/material/mixins/pbr/common.js.map +1 -0
- package/dist/material/mixins/pbr/metallicroughness.js +126 -0
- package/dist/material/mixins/pbr/metallicroughness.js.map +1 -0
- package/dist/material/mixins/pbr/specularglossness.js +104 -0
- package/dist/material/mixins/pbr/specularglossness.js.map +1 -0
- package/dist/material/mixins/texture.js +157 -0
- package/dist/material/mixins/texture.js.map +1 -0
- package/dist/material/mixins/vertexcolor.js +16 -11
- package/dist/material/mixins/vertexcolor.js.map +1 -1
- package/dist/material/pbrmr.js +65 -0
- package/dist/material/pbrmr.js.map +1 -0
- package/dist/material/pbrsg.js +64 -0
- package/dist/material/pbrsg.js.map +1 -0
- package/dist/material/shader/helper.js +903 -0
- package/dist/material/shader/helper.js.map +1 -0
- package/dist/material/terrainmat.js +357 -0
- package/dist/material/terrainmat.js.map +1 -0
- package/dist/material/terrainmaterial.js +311 -103
- package/dist/material/terrainmaterial.js.map +1 -1
- package/dist/material/unlit.js +12 -9
- package/dist/material/unlit.js.map +1 -1
- package/dist/posteffect/bloom.js +8 -6
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js +14 -6
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/posteffect.js +1 -1
- package/dist/posteffect/sao.js +8 -5
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/tonemap.js +2 -2
- package/dist/posteffect/water.js +10 -8
- package/dist/posteffect/water.js.map +1 -1
- package/dist/render/cluster_light.js +6 -5
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/depthpass.js +46 -0
- package/dist/render/depthpass.js.map +1 -0
- package/dist/render/envlight.js +26 -24
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fullscreenquad.js +38 -0
- package/dist/render/fullscreenquad.js.map +1 -0
- package/dist/render/lightpass.js +98 -0
- package/dist/render/lightpass.js.map +1 -0
- package/dist/render/render_queue.js +2 -1
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +191 -0
- package/dist/render/renderer.js.map +1 -0
- package/dist/render/renderpass.js +10 -8
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/shadowmap_pass.js +3 -4
- package/dist/render/shadowmap_pass.js.map +1 -1
- package/dist/render/sky.js +31 -15
- package/dist/render/sky.js.map +1 -1
- package/dist/scene/environment.js +8 -6
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/graph_node.js +3 -0
- package/dist/scene/graph_node.js.map +1 -1
- package/dist/scene/mesh.js +13 -12
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/scene.js +11 -15
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +10 -16
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain/grass.js +4 -14
- package/dist/scene/terrain/grass.js.map +1 -1
- package/dist/scene/terrain/patch.js +3 -3
- package/dist/scene/terrain/terrain.js +4 -9
- package/dist/scene/terrain/terrain.js.map +1 -1
- package/dist/shaders/framework.js +17 -3
- package/dist/shaders/framework.js.map +1 -1
- package/dist/shaders/misc.js +13 -161
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js +7 -7
- package/dist/shaders/pbr.js +1 -82
- package/dist/shaders/pbr.js.map +1 -1
- package/dist/shaders/shadow.js +33 -31
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/water.js +3 -9
- package/dist/shaders/water.js.map +1 -1
- package/dist/shadow/esm.js +11 -9
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -15
- package/dist/shadow/pcf_pd.js +15 -15
- package/dist/shadow/shadowmapper.js +13 -15
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +21 -55
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +15 -13
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/torus.js +2 -2
- package/dist/utility/bounding_volume.js +27 -27
- package/dist/utility/pmrem.js +4 -4
- package/dist/utility/sheenlut.js +196 -0
- package/dist/utility/sheenlut.js.map +1 -0
- package/dist/utility/shprojection.js +0 -1
- package/dist/utility/shprojection.js.map +1 -1
- package/dist/values.js +11 -8
- package/dist/values.js.map +1 -1
- package/package.json +9 -9
package/dist/material/lambert.js
CHANGED
|
@@ -1,49 +1,75 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { mixinAlbedoColor } from './mixins/albedocolor.js';
|
|
1
|
+
import { mixinLight } from './mixins/lit.js';
|
|
3
2
|
import { mixinVertexColor } from './mixins/vertexcolor.js';
|
|
4
|
-
import { applyMaterialMixins } from './meshmaterial.js';
|
|
3
|
+
import { applyMaterialMixins, MeshMaterial } from './meshmaterial.js';
|
|
4
|
+
import { ShaderHelper } from './shader/helper.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Lambert material
|
|
8
8
|
* @public
|
|
9
|
-
*/ class LambertMaterial extends applyMaterialMixins(
|
|
9
|
+
*/ class LambertMaterial extends applyMaterialMixins(MeshMaterial, mixinLight, mixinVertexColor) {
|
|
10
|
+
static FEATURE_VERTEX_NORMAL = this.defineFeature();
|
|
11
|
+
static FEATURE_VERTEX_TANGENT = this.defineFeature();
|
|
10
12
|
constructor(){
|
|
11
13
|
super();
|
|
14
|
+
this.useFeature(LambertMaterial.FEATURE_VERTEX_NORMAL, true);
|
|
12
15
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
scope.$inputs.zPos = scope.$builder.vec3().attrib('position');
|
|
16
|
-
this.transformVertexAndNormal(scope);
|
|
16
|
+
/** true if vertex normal attribute presents */ get vertexNormal() {
|
|
17
|
+
return this.featureUsed(LambertMaterial.FEATURE_VERTEX_NORMAL);
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
set vertexNormal(val) {
|
|
20
|
+
this.useFeature(LambertMaterial.FEATURE_VERTEX_NORMAL, !!val);
|
|
21
|
+
}
|
|
22
|
+
/** true if vertex normal attribute presents */ get vertexTangent() {
|
|
23
|
+
return this.featureUsed(LambertMaterial.FEATURE_VERTEX_TANGENT);
|
|
24
|
+
}
|
|
25
|
+
set vertexTangent(val) {
|
|
26
|
+
this.useFeature(LambertMaterial.FEATURE_VERTEX_TANGENT, !!val);
|
|
27
|
+
}
|
|
28
|
+
vertexShader(scope) {
|
|
29
|
+
super.vertexShader(scope);
|
|
30
|
+
const pb = scope.$builder;
|
|
31
|
+
scope.$l.oPos = ShaderHelper.resolveVertexPosition(scope);
|
|
32
|
+
scope.$outputs.worldPos = pb.mul(ShaderHelper.getWorldMatrix(scope), pb.vec4(scope.oPos, 1)).xyz;
|
|
33
|
+
ShaderHelper.setClipSpacePosition(scope, pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.worldPos, 1)));
|
|
34
|
+
if (this.vertexNormal) {
|
|
35
|
+
scope.$l.oNorm = ShaderHelper.resolveVertexNormal(scope);
|
|
36
|
+
scope.$outputs.wNorm = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oNorm, 0)).xyz;
|
|
37
|
+
if (this.vertexTangent) {
|
|
38
|
+
scope.$l.oTangent = ShaderHelper.resolveVertexTangent(scope);
|
|
39
|
+
scope.$outputs.wTangent = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oTangent.xyz, 0)).xyz;
|
|
40
|
+
scope.$outputs.wBinormal = pb.mul(pb.cross(scope.$outputs.wNorm, scope.$outputs.wTangent), scope.oTangent.w);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
fragmentShader(scope) {
|
|
45
|
+
super.fragmentShader(scope);
|
|
20
46
|
const pb = scope.$builder;
|
|
21
47
|
const that = this;
|
|
22
|
-
if (this.needFragmentColor(
|
|
23
|
-
scope.$l.albedo = this.calculateAlbedoColor(scope
|
|
48
|
+
if (this.needFragmentColor()) {
|
|
49
|
+
scope.$l.albedo = this.calculateAlbedoColor(scope);
|
|
24
50
|
if (this.vertexColor) {
|
|
25
|
-
scope.albedo = pb.mul(scope.albedo, this.getVertexColor(scope
|
|
51
|
+
scope.albedo = pb.mul(scope.albedo, this.getVertexColor(scope));
|
|
26
52
|
}
|
|
27
53
|
scope.$l.color = pb.vec3(0);
|
|
28
|
-
scope.$l.normal = this.calculateNormal(scope,
|
|
29
|
-
if (this.needCalculateEnvLight(
|
|
30
|
-
scope.color = pb.add(scope.color, this.getEnvLightIrradiance(scope, scope.normal
|
|
54
|
+
scope.$l.normal = this.calculateNormal(scope, scope.$inputs.worldPos, scope.$inputs.wNorm, scope.$inputs.wTangent, scope.$inputs.wBinormal);
|
|
55
|
+
if (this.needCalculateEnvLight()) {
|
|
56
|
+
scope.color = pb.add(scope.color, this.getEnvLightIrradiance(scope, scope.normal));
|
|
31
57
|
}
|
|
32
|
-
this.forEachLight(scope,
|
|
33
|
-
this.$l.lightAtten = that.calculateLightAttenuation(this, type, posRange, dirCutoff);
|
|
34
|
-
this.$l.lightDir = that.calculateLightDirection(this, type, posRange, dirCutoff);
|
|
58
|
+
this.forEachLight(scope, function(type, posRange, dirCutoff, colorIntensity, shadow) {
|
|
59
|
+
this.$l.lightAtten = that.calculateLightAttenuation(this, type, scope.$inputs.worldPos, posRange, dirCutoff);
|
|
60
|
+
this.$l.lightDir = that.calculateLightDirection(this, type, scope.$inputs.worldPos, posRange, dirCutoff);
|
|
35
61
|
this.$l.NoL = pb.clamp(pb.dot(this.normal, this.lightDir), 0, 1);
|
|
36
62
|
this.$l.lightContrib = pb.mul(colorIntensity.rgb, colorIntensity.a, this.NoL, this.lightAtten);
|
|
37
63
|
if (shadow) {
|
|
38
|
-
this.$l.shadow = pb.vec3(that.calculateShadow(this, this.NoL
|
|
64
|
+
this.$l.shadow = pb.vec3(that.calculateShadow(this, scope.$inputs.worldPos, this.NoL));
|
|
39
65
|
this.lightContrib = pb.mul(this.lightContrib, this.shadow);
|
|
40
66
|
}
|
|
41
67
|
this.color = pb.add(this.color, this.lightContrib);
|
|
42
68
|
});
|
|
43
69
|
scope.$l.litColor = pb.mul(scope.albedo, pb.vec4(scope.color, 1));
|
|
44
|
-
this.outputFragmentColor(scope, scope.
|
|
70
|
+
this.outputFragmentColor(scope, scope.$inputs.worldPos, scope.litColor);
|
|
45
71
|
} else {
|
|
46
|
-
this.outputFragmentColor(scope,
|
|
72
|
+
this.outputFragmentColor(scope, scope.$inputs.worldPos, null);
|
|
47
73
|
}
|
|
48
74
|
}
|
|
49
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lambert.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lambert.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -906,10 +906,10 @@ const TEX_NAME_CLEARCOAT_NORMAL = 'clearcoatNormal';
|
|
|
906
906
|
], function() {
|
|
907
907
|
this.$l.n = this.bits;
|
|
908
908
|
this.n = pb.compOr(pb.sal(this.n, 16), pb.sar(this.n, 16));
|
|
909
|
-
this.n = pb.compOr(pb.sal(pb.compAnd(this.n, 0x55555555), 1), pb.sar(pb.compAnd(this.n,
|
|
910
|
-
this.n = pb.compOr(pb.sal(pb.compAnd(this.n, 0x33333333), 2), pb.sar(pb.compAnd(this.n,
|
|
911
|
-
this.n = pb.compOr(pb.sal(pb.compAnd(this.n,
|
|
912
|
-
this.n = pb.compOr(pb.sal(pb.compAnd(this.n,
|
|
909
|
+
this.n = pb.compOr(pb.sal(pb.compAnd(this.n, 0x55555555), 1), pb.sar(pb.compAnd(this.n, 0xaaaaaaaa), 1));
|
|
910
|
+
this.n = pb.compOr(pb.sal(pb.compAnd(this.n, 0x33333333), 2), pb.sar(pb.compAnd(this.n, 0xcccccccc), 2));
|
|
911
|
+
this.n = pb.compOr(pb.sal(pb.compAnd(this.n, 0x0f0f0f0f), 4), pb.sar(pb.compAnd(this.n, 0xf0f0f0f0), 4));
|
|
912
|
+
this.n = pb.compOr(pb.sal(pb.compAnd(this.n, 0x00ff00ff), 8), pb.sar(pb.compAnd(this.n, 0xff00ff00), 8));
|
|
913
913
|
this.$return(pb.mul(pb.float(this.n), 2.3283064365386963e-10));
|
|
914
914
|
});
|
|
915
915
|
pb.func('hammersley2d', [
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { List } from '@zephyr3d/base';
|
|
2
2
|
import { ProgramBuilder } from '@zephyr3d/device';
|
|
3
3
|
import { Application } from '../app.js';
|
|
4
|
-
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';
|
|
5
6
|
|
|
6
7
|
class InstanceBindGroupPool {
|
|
7
8
|
_bindGroups;
|
|
@@ -38,7 +39,7 @@ class InstanceBindGroupPool {
|
|
|
38
39
|
const bindGroup = this._bindGroups[bindGroupIndex];
|
|
39
40
|
const offset = (maxSize - bindGroup.freeSize) / 64;
|
|
40
41
|
for (const matrix of worldMatrices){
|
|
41
|
-
bindGroup.bindGroup.setRawData(
|
|
42
|
+
bindGroup.bindGroup.setRawData(ShaderHelper.getWorldMatricesUniformName(), maxSize - bindGroup.freeSize, matrix);
|
|
42
43
|
bindGroup.freeSize -= 64;
|
|
43
44
|
}
|
|
44
45
|
device.setBindGroup(3, bindGroup.bindGroup);
|
|
@@ -47,9 +48,9 @@ class InstanceBindGroupPool {
|
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
49
50
|
* Base class for any kind of materials
|
|
51
|
+
*
|
|
50
52
|
* @public
|
|
51
53
|
*/ class Material {
|
|
52
|
-
/** @internal */ static _debugChannel = '';
|
|
53
54
|
/** @internal */ static _nextId = 0;
|
|
54
55
|
/** @internal */ static _programMap = {};
|
|
55
56
|
/** @internal */ static _drawableTimestamps = new WeakMap();
|
|
@@ -59,7 +60,7 @@ class InstanceBindGroupPool {
|
|
|
59
60
|
/** @internal */ static _materialIterators = new WeakMap();
|
|
60
61
|
/** @internal */ static _materialLRU = new List();
|
|
61
62
|
/** @internal */ static _gcOptions = {
|
|
62
|
-
disabled:
|
|
63
|
+
disabled: true,
|
|
63
64
|
drawableCountThreshold: 500,
|
|
64
65
|
materialCountThreshold: 200,
|
|
65
66
|
inactiveTimeDuration: 30000
|
|
@@ -67,6 +68,7 @@ class InstanceBindGroupPool {
|
|
|
67
68
|
/** @internal */ static _boneMatrixTextureSampler = null;
|
|
68
69
|
/** @internal */ static _instanceBindGroupPool = new InstanceBindGroupPool();
|
|
69
70
|
/** @internal */ static _drawableBindGroupMap = new WeakMap();
|
|
71
|
+
/** @internal */ _numPasses;
|
|
70
72
|
/** @internal */ _hash;
|
|
71
73
|
/** @internal */ _renderStateSet;
|
|
72
74
|
/** @internal */ _bindGroupMap;
|
|
@@ -77,26 +79,32 @@ class InstanceBindGroupPool {
|
|
|
77
79
|
* Creates an instance of material
|
|
78
80
|
*/ constructor(){
|
|
79
81
|
this._id = ++Material._nextId;
|
|
80
|
-
this.
|
|
82
|
+
this._numPasses = 1;
|
|
83
|
+
this._hash = [
|
|
84
|
+
[]
|
|
85
|
+
];
|
|
81
86
|
this._renderStateSet = null;
|
|
82
87
|
this._bindGroupMap = {};
|
|
83
88
|
this._optionTag = 0;
|
|
84
89
|
this._materialBindGroup = null;
|
|
85
90
|
}
|
|
86
|
-
/** Debug channel */ static get debugChannel() {
|
|
87
|
-
return this._debugChannel;
|
|
88
|
-
}
|
|
89
|
-
static set debugChannel(val) {
|
|
90
|
-
this._debugChannel = val;
|
|
91
|
-
}
|
|
92
91
|
/** Unique identifier of the material */ get id() {
|
|
93
92
|
return this._id;
|
|
94
93
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
get numPasses() {
|
|
95
|
+
return this._numPasses;
|
|
96
|
+
}
|
|
97
|
+
set numPasses(val) {
|
|
98
|
+
while(this._hash.length < val){
|
|
99
|
+
this._hash.push([]);
|
|
100
|
+
}
|
|
101
|
+
this._numPasses = val;
|
|
102
|
+
}
|
|
103
|
+
/** @internal */ getHash(renderPassType, pass) {
|
|
104
|
+
if (this._hash[pass][renderPassType] === void 0) {
|
|
105
|
+
this._hash[pass][renderPassType] = this.createHash(renderPassType, pass);
|
|
98
106
|
}
|
|
99
|
-
return this._hash[renderPassType];
|
|
107
|
+
return this._hash[pass][renderPassType];
|
|
100
108
|
}
|
|
101
109
|
/** Render states associated to this material */ get stateSet() {
|
|
102
110
|
if (!this._renderStateSet) {
|
|
@@ -107,44 +115,55 @@ class InstanceBindGroupPool {
|
|
|
107
115
|
set stateSet(stateset) {
|
|
108
116
|
this._renderStateSet = stateset;
|
|
109
117
|
}
|
|
110
|
-
|
|
118
|
+
getQueueType() {
|
|
119
|
+
return QUEUE_OPAQUE;
|
|
120
|
+
}
|
|
121
|
+
/** Returns true if this is a transparency material */ isTransparentPass(pass) {
|
|
111
122
|
return false;
|
|
112
123
|
}
|
|
113
124
|
/** Returns true if shading of the material will be affected by lights */ supportLighting() {
|
|
114
125
|
return true;
|
|
115
126
|
}
|
|
127
|
+
/** Returns true if this material supports geometry instancing */ isBatchable() {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
116
130
|
/**
|
|
117
131
|
* Draws a primitive using this material
|
|
132
|
+
*
|
|
118
133
|
* @param primitive - The prmitive to be drawn
|
|
119
134
|
* @param ctx - The context of current drawing task
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
135
|
+
* @param numInstances - How many instances should be drawn. if zero, the instance count will be automatically detected.
|
|
136
|
+
*/ draw(primitive, ctx, numInstances = 0) {
|
|
137
|
+
for(let i = 0; i < this._numPasses; i++){
|
|
138
|
+
if (this.beginDraw(i, ctx)) {
|
|
139
|
+
this.drawPrimitive(i, primitive, ctx, numInstances);
|
|
140
|
+
this.endDraw(i);
|
|
126
141
|
}
|
|
127
|
-
this.endDraw();
|
|
128
142
|
}
|
|
129
143
|
}
|
|
130
144
|
/**
|
|
131
145
|
* Prepares for drawing
|
|
132
146
|
* @param ctx - The context of current drawing task
|
|
133
147
|
* @returns true if succeeded, otherwise false
|
|
134
|
-
*/ beginDraw(ctx) {
|
|
148
|
+
*/ beginDraw(pass, ctx) {
|
|
135
149
|
const numInstances = ctx.instanceData?.worldMatrices?.length || 1;
|
|
136
150
|
const device = Application.instance.device;
|
|
137
|
-
const programInfo = this.getOrCreateProgram(ctx);
|
|
151
|
+
const programInfo = this.getOrCreateProgram(ctx, pass);
|
|
138
152
|
if (programInfo) {
|
|
139
153
|
const hash = programInfo.hash;
|
|
140
154
|
if (!programInfo.programs[ctx.renderPass.type]) {
|
|
141
|
-
return
|
|
155
|
+
return false;
|
|
142
156
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
157
|
+
if (pass > 0) {
|
|
158
|
+
this.optionChanged(false);
|
|
159
|
+
}
|
|
160
|
+
this._materialBindGroup = this.applyMaterialBindGroups(ctx, hash, pass);
|
|
161
|
+
if (pass === 0) {
|
|
162
|
+
if (numInstances > 1) {
|
|
163
|
+
this.applyInstanceBindGroups(ctx, hash);
|
|
164
|
+
} else {
|
|
165
|
+
this.applyDrawableBindGroups(ctx, hash);
|
|
166
|
+
}
|
|
148
167
|
}
|
|
149
168
|
ctx.renderPass.applyRenderStates(device, this.stateSet, ctx);
|
|
150
169
|
device.setProgram(programInfo.programs[ctx.renderPass.type]);
|
|
@@ -158,7 +177,7 @@ class InstanceBindGroupPool {
|
|
|
158
177
|
}
|
|
159
178
|
/**
|
|
160
179
|
* Ends drawing a primitive
|
|
161
|
-
*/ endDraw() {
|
|
180
|
+
*/ endDraw(pass) {
|
|
162
181
|
this._materialBindGroup = null;
|
|
163
182
|
}
|
|
164
183
|
/**
|
|
@@ -172,24 +191,22 @@ class InstanceBindGroupPool {
|
|
|
172
191
|
* @param bindGroup - The bind group of the material
|
|
173
192
|
* @param ctx - The context of current drawing task
|
|
174
193
|
* @param needUpdate - true if the uniform values needs to update
|
|
175
|
-
*/ applyUniforms(bindGroup, ctx, needUpdate) {
|
|
194
|
+
*/ applyUniforms(bindGroup, ctx, needUpdate, pass) {
|
|
176
195
|
if (needUpdate) {
|
|
177
|
-
this._applyUniforms(bindGroup, ctx);
|
|
196
|
+
this._applyUniforms(bindGroup, ctx, pass);
|
|
178
197
|
}
|
|
179
198
|
}
|
|
180
199
|
/**
|
|
181
200
|
* Fetch the gpu program of the material for drawing
|
|
182
201
|
* @param ctx - The context for current drawing task
|
|
183
202
|
* @returns Information of the gpu program
|
|
184
|
-
*/ getOrCreateProgram(ctx) {
|
|
203
|
+
*/ getOrCreateProgram(ctx, pass) {
|
|
185
204
|
const programMap = Material._programMap;
|
|
186
205
|
const renderPassType = ctx.renderPass.type;
|
|
187
|
-
const hash = `${
|
|
206
|
+
const hash = `${this.getHash(renderPassType, pass)}:${!!ctx.target.getBoneMatrices()}:${Number(!!(ctx.instanceData?.worldMatrices.length > 1))}:${ctx.renderPassHash}`;
|
|
188
207
|
let programInfo = programMap[hash];
|
|
189
|
-
if (!programInfo ||
|
|
190
|
-
|
|
191
|
-
const program = this.createProgram(ctx);
|
|
192
|
-
console.timeEnd(hash);
|
|
208
|
+
if (!programInfo || programInfo.programs[renderPassType] === undefined) {
|
|
209
|
+
const program = this.createProgram(ctx, pass) ?? null;
|
|
193
210
|
if (!programInfo) {
|
|
194
211
|
programInfo = {
|
|
195
212
|
programs: [
|
|
@@ -203,7 +220,7 @@ class InstanceBindGroupPool {
|
|
|
203
220
|
}
|
|
204
221
|
programInfo.programs[renderPassType] = program;
|
|
205
222
|
}
|
|
206
|
-
return programInfo
|
|
223
|
+
return programInfo;
|
|
207
224
|
}
|
|
208
225
|
dispose() {
|
|
209
226
|
this.clearBindGroupCache();
|
|
@@ -267,21 +284,23 @@ class InstanceBindGroupPool {
|
|
|
267
284
|
/** @internal */ optionChanged(changeHash) {
|
|
268
285
|
this._optionTag++;
|
|
269
286
|
if (changeHash) {
|
|
270
|
-
|
|
287
|
+
for(let i = 0; i < this._numPasses; i++){
|
|
288
|
+
this._hash[i] = [];
|
|
289
|
+
}
|
|
271
290
|
}
|
|
272
291
|
}
|
|
273
292
|
/** @internal */ static getProgramByHashIndex(hash, index) {
|
|
274
293
|
return this._programMap[hash].programs[index];
|
|
275
294
|
}
|
|
276
|
-
/** @internal */ applyMaterialBindGroups(ctx, hash) {
|
|
295
|
+
/** @internal */ applyMaterialBindGroups(ctx, hash, pass) {
|
|
277
296
|
const index = ctx.renderPass.type;
|
|
278
297
|
let bindGroupInfo = this._bindGroupMap[hash];
|
|
279
298
|
if (!bindGroupInfo) {
|
|
280
299
|
// bindGroups not created or have been garbage collected
|
|
281
300
|
const materialBindGroup = [
|
|
282
|
-
|
|
301
|
+
RENDER_PASS_TYPE_LIGHT,
|
|
283
302
|
RENDER_PASS_TYPE_SHADOWMAP,
|
|
284
|
-
|
|
303
|
+
RENDER_PASS_TYPE_DEPTH
|
|
285
304
|
].map((k)=>{
|
|
286
305
|
const program = Material._programMap[hash].programs[k];
|
|
287
306
|
return program?.bindGroupLayouts[2] ? Application.instance.device.createBindGroup(program.bindGroupLayouts[2]) : null;
|
|
@@ -302,7 +321,7 @@ class InstanceBindGroupPool {
|
|
|
302
321
|
}
|
|
303
322
|
const bindGroup = bindGroupInfo.materialBindGroup[index];
|
|
304
323
|
if (bindGroup) {
|
|
305
|
-
this.applyUniforms(bindGroup, ctx, bindGroupInfo.materialTag[index] < this._optionTag || bindGroupInfo.bindGroupTag[index] !== bindGroup.cid);
|
|
324
|
+
this.applyUniforms(bindGroup, ctx, bindGroupInfo.materialTag[index] < this._optionTag || bindGroupInfo.bindGroupTag[index] !== bindGroup.cid, pass);
|
|
306
325
|
bindGroupInfo.materialTag[index] = this._optionTag;
|
|
307
326
|
bindGroupInfo.bindGroupTag[index] = bindGroup.cid;
|
|
308
327
|
Application.instance.device.setBindGroup(2, bindGroup);
|
|
@@ -320,9 +339,9 @@ class InstanceBindGroupPool {
|
|
|
320
339
|
let drawableBindGroup = drawableBindGroups[hash];
|
|
321
340
|
if (!drawableBindGroup) {
|
|
322
341
|
const bindGroup = [
|
|
323
|
-
|
|
342
|
+
RENDER_PASS_TYPE_LIGHT,
|
|
324
343
|
RENDER_PASS_TYPE_SHADOWMAP,
|
|
325
|
-
|
|
344
|
+
RENDER_PASS_TYPE_DEPTH
|
|
326
345
|
].map((k)=>{
|
|
327
346
|
const program = Material._programMap[hash].programs[k];
|
|
328
347
|
return program?.bindGroupLayouts[1] ? Application.instance.device.createBindGroup(program.bindGroupLayouts[1]) : null;
|
|
@@ -348,7 +367,7 @@ class InstanceBindGroupPool {
|
|
|
348
367
|
const offset = Material._instanceBindGroupPool.apply(hash, index, ctx.instanceData.worldMatrices);
|
|
349
368
|
const bindGroup = this.getDrawableBindGroup(ctx, hash).bindGroup?.[index];
|
|
350
369
|
if (bindGroup) {
|
|
351
|
-
bindGroup.setValue(
|
|
370
|
+
bindGroup.setValue(ShaderHelper.getInstanceBufferOffsetUniformName(), offset);
|
|
352
371
|
Application.instance.device.setBindGroup(1, bindGroup);
|
|
353
372
|
} else {
|
|
354
373
|
Application.instance.device.setBindGroup(1, null);
|
|
@@ -361,7 +380,7 @@ class InstanceBindGroupPool {
|
|
|
361
380
|
if (drawableBindGroup.bindGroup) {
|
|
362
381
|
const bindGroup = drawableBindGroup.bindGroup[index];
|
|
363
382
|
if (drawableBindGroup.xformTag[index] < ctx.target.getXForm().getTag() || drawableBindGroup.bindGroupTag[index] !== bindGroup.cid) {
|
|
364
|
-
bindGroup.setValue(
|
|
383
|
+
bindGroup.setValue(ShaderHelper.getWorldMatrixUniformName(), ctx.target.getXForm().worldMatrix);
|
|
365
384
|
drawableBindGroup.xformTag[index] = ctx.target.getXForm().getTag();
|
|
366
385
|
drawableBindGroup.bindGroupTag[index] = bindGroup.cid;
|
|
367
386
|
}
|
|
@@ -374,17 +393,25 @@ class InstanceBindGroupPool {
|
|
|
374
393
|
mipFilter: 'none'
|
|
375
394
|
});
|
|
376
395
|
}
|
|
377
|
-
bindGroup.setTexture(
|
|
378
|
-
bindGroup.setValue(
|
|
379
|
-
bindGroup.setValue(
|
|
396
|
+
bindGroup.setTexture(ShaderHelper.getBoneMatricesUniformName(), boneMatrices);
|
|
397
|
+
bindGroup.setValue(ShaderHelper.getBoneTextureSizeUniformName(), boneMatrices.width);
|
|
398
|
+
bindGroup.setValue(ShaderHelper.getBoneInvBindMatrixUniformName(), ctx.target.getInvBindMatrix());
|
|
380
399
|
}
|
|
381
400
|
device.setBindGroup(1, bindGroup);
|
|
382
401
|
} else {
|
|
383
402
|
device.setBindGroup(1, null);
|
|
384
403
|
}
|
|
404
|
+
device.setBindGroup(3, null);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Convert pass to hash
|
|
408
|
+
* @param pass - pass number
|
|
409
|
+
* @returns String hash
|
|
410
|
+
*/ passToHash(pass) {
|
|
411
|
+
return String(pass);
|
|
385
412
|
}
|
|
386
|
-
/** @internal */ createHash(renderPassType) {
|
|
387
|
-
return `${this.constructor.name}|${this._createHash(renderPassType)}`;
|
|
413
|
+
/** @internal */ createHash(renderPassType, pass) {
|
|
414
|
+
return `${this.constructor.name}|${this.passToHash(pass)}|${this._createHash(renderPassType)}`;
|
|
388
415
|
}
|
|
389
416
|
/** @internal */ clearBindGroupCache() {
|
|
390
417
|
let n = 0;
|
|
@@ -425,9 +452,23 @@ class InstanceBindGroupPool {
|
|
|
425
452
|
}
|
|
426
453
|
this._materialIterators.set(material, this._materialLRU.append(material));
|
|
427
454
|
}
|
|
428
|
-
/**
|
|
455
|
+
/**
|
|
456
|
+
* Draw primitve
|
|
457
|
+
*
|
|
458
|
+
* @param primitive - Primitive to be drawn
|
|
459
|
+
* @param ctx - Draw context
|
|
460
|
+
*/ drawPrimitive(pass, primitive, ctx, numInstances) {
|
|
461
|
+
if (numInstances > 0) {
|
|
462
|
+
primitive.drawInstanced(numInstances);
|
|
463
|
+
} else if (ctx.instanceData?.worldMatrices.length > 1) {
|
|
464
|
+
primitive.drawInstanced(ctx.instanceData.worldMatrices.length);
|
|
465
|
+
} else {
|
|
466
|
+
primitive.draw();
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
/** @internal */ createProgram(ctx, pass) {
|
|
429
470
|
const pb = new ProgramBuilder(Application.instance.device);
|
|
430
|
-
return this._createProgram(pb, ctx);
|
|
471
|
+
return this._createProgram(pb, ctx, pass);
|
|
431
472
|
}
|
|
432
473
|
/** @internal */ createRenderStateSet() {
|
|
433
474
|
return Application.instance.device.createRenderStateSet();
|
|
@@ -438,14 +479,14 @@ class InstanceBindGroupPool {
|
|
|
438
479
|
* @param ctx - The drawing context
|
|
439
480
|
* @param func - The material func
|
|
440
481
|
* @returns The created shader program
|
|
441
|
-
*/ _createProgram(pb, ctx) {
|
|
482
|
+
*/ _createProgram(pb, ctx, pass) {
|
|
442
483
|
return null;
|
|
443
484
|
}
|
|
444
485
|
/**
|
|
445
486
|
* Applies uniform values
|
|
446
487
|
* @param bindGroup - The bind group
|
|
447
488
|
* @param ctx - The drawing context
|
|
448
|
-
*/ _applyUniforms(bindGroup, ctx) {}
|
|
489
|
+
*/ _applyUniforms(bindGroup, ctx, pass) {}
|
|
449
490
|
/**
|
|
450
491
|
* Calculates the hash code of the shader program
|
|
451
492
|
* @returns The hash code
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"material.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|