@zephyr3d/scene 0.9.6 → 0.9.8
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/animationset.js +52 -55
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +92 -32
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/convex_collider.js +320 -0
- package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +57 -19
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +71 -27
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics_modifier.js +4 -3
- package/dist/animation/joint_dynamics_modifier.js.map +1 -1
- package/dist/animation/skeleton.js +7 -10
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/app/engine.js +3 -9
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptregistry.js +47 -16
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +3 -1
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/model.js +346 -7
- package/dist/asset/model.js.map +1 -1
- package/dist/avatar/wardrobe.js +7 -3
- package/dist/avatar/wardrobe.js.map +1 -1
- package/dist/camera/camera.js +240 -34
- package/dist/camera/camera.js.map +1 -1
- package/dist/index.d.ts +1350 -622
- package/dist/index.js +6 -11
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +1 -1
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/lambert.js +1 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +23 -1
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +178 -23
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +4 -4
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +2 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +2 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +63 -16
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +100 -27
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +16 -6
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +1 -1
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +276 -65
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +3 -3
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mixins/vertexcolor.js +2 -2
- package/dist/material/mixins/vertexcolor.js.map +1 -1
- package/dist/material/mtoon.js +574 -0
- package/dist/material/mtoon.js.map +1 -0
- package/dist/material/pbrblueprint.js +494 -331
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js +118 -100
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +1 -1
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +45 -15
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/subsurfaceprofile.js +812 -0
- package/dist/material/subsurfaceprofile.js.map +1 -0
- package/dist/material/unlit.js +1 -1
- package/dist/material/unlit.js.map +1 -1
- package/dist/posteffect/compositor.js +46 -11
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/ssr.js +413 -87
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +1053 -0
- package/dist/posteffect/sss.js.map +1 -0
- package/dist/posteffect/taa.js +61 -60
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/abuffer_oit.js +63 -12
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js +6 -5
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/drawable.js +1 -5
- package/dist/render/drawable.js.map +1 -1
- package/dist/render/drawable_mixin.js +2 -1
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +2 -1
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +2 -1
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +2 -1
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/lightpass.js +105 -18
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/render_queue.js +51 -8
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +73 -59
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js +8 -0
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +481 -95
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/history_resource_manager.js +55 -0
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +3 -1
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +10 -4
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/sky.js +31 -1
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +23 -5
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +4 -2
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +3 -1
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +11 -1
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/light.js +21 -3
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +29 -14
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +5 -2
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +5 -3
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +3 -1
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +6 -5
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +4 -2
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +2 -1
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +4 -2
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +4 -2
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/shadow.js +26 -393
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shadow/esm.js +112 -12
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +2 -2
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +19 -10
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/shader.js +58 -7
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js +6 -0
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +229 -0
- package/dist/shadow/shadow_region.js.map +1 -0
- package/dist/shadow/shadowmapper.js +67 -59
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/vsm.js +45 -19
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +8 -8
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/material/pbr.js +31 -4
- package/dist/utility/blueprint/material/pbr.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +1 -17
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/serialization/manager.js +66 -98
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +5 -2
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -1
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +249 -54
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +37 -1
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +42 -3
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1112 -646
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +7 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +31 -12
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +4 -1
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +3 -1
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +18 -0
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +6 -3
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +5 -2
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +3 -1
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +4 -1
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/textures/ltcdata.js +6 -0
- package/dist/utility/textures/ltcdata.js.map +1 -0
- package/dist/utility/textures/ltclut.js +61 -0
- package/dist/utility/textures/ltclut.js.map +1 -0
- package/dist/values.js +9 -1
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,61 +1,43 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DRef, Vector4 } from '@zephyr3d/base';
|
|
2
2
|
import { ShaderHelper } from './shader/helper.js';
|
|
3
|
-
import { RENDER_PASS_TYPE_LIGHT, MaterialVaryingFlags } from '../values.js';
|
|
4
|
-
import { Vector3, Vector2, DRef, Vector4 } from '@zephyr3d/base';
|
|
5
|
-
import { mixinPBRBluePrint } from './mixins/lightmodel/pbrblueprintmixin.js';
|
|
6
3
|
import { MaterialBlueprintIR } from '../utility/blueprint/material/ir.js';
|
|
7
4
|
import { PBRBlockNode, VertexBlockNode } from '../utility/blueprint/material/pbr.js';
|
|
5
|
+
import { PBRMetallicRoughnessMaterial } from './pbrmr.js';
|
|
8
6
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
const DEFAULT_OUTPUT_NAMES = [
|
|
8
|
+
'BaseColor',
|
|
9
|
+
'Metallic',
|
|
10
|
+
'Roughness',
|
|
11
|
+
'Specular',
|
|
12
|
+
'Emissive',
|
|
13
|
+
'Normal',
|
|
14
|
+
'Tangent',
|
|
15
|
+
'Opacity',
|
|
16
|
+
'SpecularWeight',
|
|
17
|
+
'AO'
|
|
18
|
+
];
|
|
15
19
|
/**
|
|
16
|
-
* Physically-based rendering material driven by blueprint graphs
|
|
20
|
+
* Physically-based rendering material driven by blueprint graphs, but shaded by the
|
|
21
|
+
* same PBR metallic/roughness backend used by {@link PBRMetallicRoughnessMaterial}.
|
|
17
22
|
*
|
|
18
23
|
* @remarks
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* - The **vertex blueprint IR** (`vertexIR`) controls vertex
|
|
24
|
-
* transformations and per-vertex data.
|
|
25
|
-
* - The **fragment blueprint IR** (`fragmentIR`) produces inputs
|
|
26
|
-
* for the PBR shading model (albedo, roughness, metalness, etc.).
|
|
27
|
-
*
|
|
28
|
-
* Uniform values and textures for the blueprints are provided via
|
|
29
|
-
* {@link PBRBluePrintMaterial.uniformValues} and
|
|
30
|
-
* {@link PBRBluePrintMaterial.uniformTextures}.
|
|
24
|
+
* The blueprint graph only produces surface inputs. Final direct/indirect lighting,
|
|
25
|
+
* transmission, clearcoat, sheen, iridescence and anisotropic reflection still run
|
|
26
|
+
* through the standard PBRM backend so imported GLTF materials and blueprint materials
|
|
27
|
+
* stay on the same shading path.
|
|
31
28
|
*
|
|
32
29
|
* @public
|
|
33
|
-
*/ class PBRBluePrintMaterial extends
|
|
34
|
-
/** @internal */ static
|
|
35
|
-
/** @internal */ static
|
|
36
|
-
/** @internal */ static FEATURE_SUBSURFACE_SCATTERING = this.defineFeature();
|
|
30
|
+
*/ class PBRBluePrintMaterial extends PBRMetallicRoughnessMaterial {
|
|
31
|
+
/** @internal */ static FEATURE_BLUEPRINT_VERTEX_COLOR = this.defineFeature();
|
|
32
|
+
/** @internal */ static FEATURE_BLUEPRINT_VERTEX_UV = this.defineFeature();
|
|
37
33
|
/** @internal */ _irFrag;
|
|
38
34
|
/** @internal */ _irVertex;
|
|
39
35
|
/** @internal */ _uniformValues;
|
|
40
36
|
/** @internal */ _uniformTextures;
|
|
41
|
-
/** @internal */
|
|
42
|
-
/** @internal */
|
|
43
|
-
/** @internal */
|
|
44
|
-
|
|
45
|
-
/** @internal */ _subsurfaceIntensity;
|
|
46
|
-
/** @internal */ _anisotropy;
|
|
47
|
-
/** @internal */ _anisotropyDirection;
|
|
48
|
-
/** @internal */ _anisotropyDirectionScaleBias;
|
|
49
|
-
/**
|
|
50
|
-
* Creates a new {@link PBRBluePrintMaterial} instance.
|
|
51
|
-
*
|
|
52
|
-
* @param irFrag - Optional fragment blueprint IR. If omitted, a default
|
|
53
|
-
* IR containing a single {@link PBRBlockNode} is created.
|
|
54
|
-
* @param irVertex - Optional vertex blueprint IR. If omitted, a default
|
|
55
|
-
* IR containing a single {@link VertexBlockNode} is created.
|
|
56
|
-
* @param uniformValues - Optional initial list of uniform value descriptors.
|
|
57
|
-
* @param uniformTextures - Optional initial list of texture uniform descriptors.
|
|
58
|
-
*/ constructor(irFrag, irVertex, uniformValues, uniformTextures){
|
|
37
|
+
/** @internal */ _connectedOutputs;
|
|
38
|
+
/** @internal */ _vertexUsesColor;
|
|
39
|
+
/** @internal */ _vertexUsesUV;
|
|
40
|
+
constructor(irFrag, irVertex, uniformValues, uniformTextures){
|
|
59
41
|
super();
|
|
60
42
|
this._irFrag = irFrag ?? new MaterialBlueprintIR({
|
|
61
43
|
nodeMap: {
|
|
@@ -115,126 +97,34 @@ const PBR_REFLECTION_MODE = {
|
|
|
115
97
|
});
|
|
116
98
|
this._uniformValues = uniformValues ?? [];
|
|
117
99
|
this._uniformTextures = uniformTextures ?? [];
|
|
118
|
-
this.
|
|
119
|
-
this.
|
|
120
|
-
this.
|
|
121
|
-
this.
|
|
122
|
-
this._subsurfaceIntensity = 0.5;
|
|
123
|
-
this._anisotropy = 0.75;
|
|
124
|
-
this._anisotropyDirection = 0;
|
|
125
|
-
this._anisotropyDirectionScaleBias = new Vector2(1, 0);
|
|
126
|
-
this.useFeature(PBRBluePrintMaterial.FEATURE_SUBSURFACE_SCATTERING, false);
|
|
127
|
-
this.useFeature(PBRBluePrintMaterial.FEATURE_VERTEX_COLOR, this._irVertex.behaviors.useVertexColor);
|
|
128
|
-
this.useFeature(PBRBluePrintMaterial.FEATURE_VERTEX_UV, this._irVertex.behaviors.useVertexUV);
|
|
129
|
-
}
|
|
130
|
-
get reflectionMode() {
|
|
131
|
-
return this._reflectionMode;
|
|
132
|
-
}
|
|
133
|
-
set reflectionMode(val) {
|
|
134
|
-
if (val !== this._reflectionMode) {
|
|
135
|
-
this._reflectionMode = val;
|
|
136
|
-
this.uniformChanged();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
get subsurfaceScattering() {
|
|
140
|
-
return this.featureUsed(PBRBluePrintMaterial.FEATURE_SUBSURFACE_SCATTERING);
|
|
141
|
-
}
|
|
142
|
-
set subsurfaceScattering(val) {
|
|
143
|
-
this.useFeature(PBRBluePrintMaterial.FEATURE_SUBSURFACE_SCATTERING, !!val);
|
|
144
|
-
}
|
|
145
|
-
get subsurfaceColor() {
|
|
146
|
-
return this._subsurfaceColor;
|
|
147
|
-
}
|
|
148
|
-
set subsurfaceColor(val) {
|
|
149
|
-
if (!val.equalsTo(this._subsurfaceColor)) {
|
|
150
|
-
this._subsurfaceColor.set(val);
|
|
151
|
-
this.uniformChanged();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
get subsurfaceScale() {
|
|
155
|
-
return this._subsurfaceScale;
|
|
100
|
+
this._connectedOutputs = new Set();
|
|
101
|
+
this._vertexUsesColor = false;
|
|
102
|
+
this._vertexUsesUV = false;
|
|
103
|
+
this.syncBlueprintMetadata();
|
|
156
104
|
}
|
|
157
|
-
|
|
158
|
-
if (val !== this._subsurfaceScale) {
|
|
159
|
-
this._subsurfaceScale = val;
|
|
160
|
-
this.uniformChanged();
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
get subsurfacePower() {
|
|
164
|
-
return this._subsurfacePower;
|
|
165
|
-
}
|
|
166
|
-
set subsurfacePower(val) {
|
|
167
|
-
if (val !== this._subsurfacePower) {
|
|
168
|
-
this._subsurfacePower = val;
|
|
169
|
-
this.uniformChanged();
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
get subsurfaceIntensity() {
|
|
173
|
-
return this._subsurfaceIntensity;
|
|
174
|
-
}
|
|
175
|
-
set subsurfaceIntensity(val) {
|
|
176
|
-
if (val !== this._subsurfaceIntensity) {
|
|
177
|
-
this._subsurfaceIntensity = val;
|
|
178
|
-
this.uniformChanged();
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
get anisotropy() {
|
|
182
|
-
return this._anisotropy;
|
|
183
|
-
}
|
|
184
|
-
set anisotropy(val) {
|
|
185
|
-
const clamped = Math.max(-0.95, Math.min(0.95, val));
|
|
186
|
-
if (clamped !== this._anisotropy) {
|
|
187
|
-
this._anisotropy = clamped;
|
|
188
|
-
this.uniformChanged();
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
get anisotropyDirection() {
|
|
192
|
-
return this._anisotropyDirection;
|
|
193
|
-
}
|
|
194
|
-
set anisotropyDirection(val) {
|
|
195
|
-
if (val !== this._anisotropyDirection) {
|
|
196
|
-
this._anisotropyDirection = val;
|
|
197
|
-
this.uniformChanged();
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
get anisotropyDirectionScaleBias() {
|
|
201
|
-
return this._anisotropyDirectionScaleBias;
|
|
202
|
-
}
|
|
203
|
-
set anisotropyDirectionScaleBias(val) {
|
|
204
|
-
if (!val.equalsTo(this._anisotropyDirectionScaleBias)) {
|
|
205
|
-
this._anisotropyDirectionScaleBias.set(val);
|
|
206
|
-
this.uniformChanged();
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Gets the fragment blueprint IR.
|
|
211
|
-
*/ get fragmentIR() {
|
|
105
|
+
get fragmentIR() {
|
|
212
106
|
return this._irFrag;
|
|
213
107
|
}
|
|
214
108
|
set fragmentIR(ir) {
|
|
215
109
|
if (ir && ir !== this._irFrag) {
|
|
216
110
|
this._irFrag = ir;
|
|
111
|
+
this.syncBlueprintMetadata();
|
|
217
112
|
this.clearCache();
|
|
218
113
|
this.optionChanged(true);
|
|
219
114
|
}
|
|
220
115
|
}
|
|
221
|
-
|
|
222
|
-
* Gets the vertex blueprint IR.
|
|
223
|
-
*/ get vertexIR() {
|
|
116
|
+
get vertexIR() {
|
|
224
117
|
return this._irVertex;
|
|
225
118
|
}
|
|
226
119
|
set vertexIR(ir) {
|
|
227
120
|
if (ir && ir !== this._irVertex) {
|
|
228
121
|
this._irVertex = ir;
|
|
229
|
-
this.
|
|
230
|
-
this.useFeature(PBRBluePrintMaterial.FEATURE_VERTEX_UV, this._irVertex.behaviors.useVertexUV);
|
|
122
|
+
this.syncBlueprintMetadata();
|
|
231
123
|
this.clearCache();
|
|
232
124
|
this.optionChanged(true);
|
|
233
125
|
}
|
|
234
126
|
}
|
|
235
|
-
|
|
236
|
-
* Gets the list of uniform value descriptors used by the blueprints.
|
|
237
|
-
*/ get uniformValues() {
|
|
127
|
+
get uniformValues() {
|
|
238
128
|
return this._uniformValues;
|
|
239
129
|
}
|
|
240
130
|
set uniformValues(val) {
|
|
@@ -243,262 +133,535 @@ const PBR_REFLECTION_MODE = {
|
|
|
243
133
|
}));
|
|
244
134
|
this.uniformChanged();
|
|
245
135
|
}
|
|
246
|
-
|
|
247
|
-
* Gets the list of texture uniform descriptors used by the blueprints.
|
|
248
|
-
*/ get uniformTextures() {
|
|
136
|
+
get uniformTextures() {
|
|
249
137
|
return this._uniformTextures;
|
|
250
138
|
}
|
|
251
139
|
set uniformTextures(val) {
|
|
252
140
|
if (val !== this._uniformTextures) {
|
|
253
|
-
const newUniforms = val.map((v)=>({
|
|
254
|
-
finalTexture: new DRef(v.finalTexture
|
|
141
|
+
const newUniforms = (val ?? []).map((v)=>({
|
|
142
|
+
finalTexture: new DRef(v.finalTexture?.get() ?? null),
|
|
255
143
|
finalSampler: v.finalSampler,
|
|
144
|
+
inFragmentShader: v.inFragmentShader,
|
|
145
|
+
inVertexShader: v.inVertexShader,
|
|
146
|
+
magFilter: v.magFilter,
|
|
147
|
+
minFilter: v.minFilter,
|
|
148
|
+
mipFilter: v.mipFilter,
|
|
256
149
|
name: v.name,
|
|
257
150
|
params: v.params?.clone() ?? Vector4.zero(),
|
|
151
|
+
sRGB: v.sRGB,
|
|
258
152
|
texture: v.texture,
|
|
259
153
|
type: v.type,
|
|
260
|
-
sRGB: v.sRGB,
|
|
261
154
|
wrapS: v.wrapS,
|
|
262
|
-
wrapT: v.wrapT
|
|
263
|
-
inFragmentShader: v.inFragmentShader,
|
|
264
|
-
inVertexShader: v.inVertexShader,
|
|
265
|
-
minFilter: v.minFilter,
|
|
266
|
-
magFilter: v.magFilter,
|
|
267
|
-
mipFilter: v.mipFilter
|
|
155
|
+
wrapT: v.wrapT
|
|
268
156
|
}));
|
|
269
157
|
for (const u of this._uniformTextures){
|
|
270
|
-
u.finalTexture
|
|
158
|
+
u.finalTexture?.dispose();
|
|
271
159
|
}
|
|
272
160
|
this._uniformTextures = newUniforms;
|
|
273
161
|
this.uniformChanged();
|
|
274
162
|
}
|
|
275
163
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
* The clone shares the same vertex/fragment IR references and copies
|
|
281
|
-
* the current blueprint uniform descriptors, then calls `copyFrom`
|
|
282
|
-
* to copy base-class and mixin state.
|
|
283
|
-
*
|
|
284
|
-
* @returns A new {@link PBRBluePrintMaterial} instance.
|
|
285
|
-
*/ clone() {
|
|
164
|
+
hasConnectedOutput(name) {
|
|
165
|
+
return this._connectedOutputs.has(name);
|
|
166
|
+
}
|
|
167
|
+
clone() {
|
|
286
168
|
const other = new PBRBluePrintMaterial(this._irFrag, this._irVertex, this._uniformValues, this._uniformTextures);
|
|
287
169
|
other.copyFrom(this);
|
|
288
170
|
return other;
|
|
289
171
|
}
|
|
290
172
|
copyFrom(other) {
|
|
291
173
|
super.copyFrom(other);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
this.anisotropyDirectionScaleBias = other.anisotropyDirectionScaleBias;
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Builds the vertex shader for this PBR blueprint material.
|
|
304
|
-
*
|
|
305
|
-
* @param scope - The current vertex shader function scope.
|
|
306
|
-
*/ vertexShader(scope) {
|
|
174
|
+
if (other instanceof PBRBluePrintMaterial) {
|
|
175
|
+
this.fragmentIR = other.fragmentIR;
|
|
176
|
+
this.vertexIR = other.vertexIR;
|
|
177
|
+
this.uniformValues = other.uniformValues;
|
|
178
|
+
this.uniformTextures = other.uniformTextures;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
vertexShader(scope) {
|
|
307
182
|
super.vertexShader(scope);
|
|
308
183
|
const pb = scope.$builder;
|
|
309
|
-
scope
|
|
310
|
-
scope
|
|
311
|
-
scope
|
|
312
|
-
|
|
313
|
-
|
|
184
|
+
scope.zVertexColor = this.getBlueprintVertexColor(scope);
|
|
185
|
+
scope.zVertexUV = this.getBlueprintVertexUV(scope);
|
|
186
|
+
scope.zVertexNormal = scope.$outputs.wNorm ?? pb.vec3(0, 0, 1);
|
|
187
|
+
scope.zVertexTangent = scope.$outputs.wTangent ?? pb.vec3(1, 0, 0);
|
|
188
|
+
scope.zVertexBinormal = scope.$outputs.wBinormal ?? pb.vec3(0, 1, 0);
|
|
189
|
+
scope.zWorldPos = scope.$outputs.worldPos;
|
|
190
|
+
if (this._vertexUsesColor && !scope.$outputs.zOutDiffuse) {
|
|
191
|
+
scope.$outputs.zOutDiffuse = scope.zVertexColor;
|
|
314
192
|
}
|
|
315
|
-
if (this.
|
|
316
|
-
scope.$
|
|
193
|
+
if (this._vertexUsesUV) {
|
|
194
|
+
scope.$outputs.zVertexUV = scope.zVertexUV;
|
|
317
195
|
}
|
|
318
196
|
for (const u of [
|
|
319
197
|
...this._uniformValues,
|
|
320
198
|
...this._uniformTextures
|
|
321
199
|
]){
|
|
322
200
|
if (u.inVertexShader) {
|
|
323
|
-
// @ts-ignore
|
|
201
|
+
// @ts-ignore dynamic shader type constructor
|
|
324
202
|
pb.getGlobalScope()[u.name] = pb[u.type]().uniform(2);
|
|
325
203
|
}
|
|
326
204
|
}
|
|
327
205
|
const outputs = this._irVertex.create(pb);
|
|
328
|
-
|
|
206
|
+
if (!outputs) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const vertexOut = this.toVertexOutputMap(outputs);
|
|
329
210
|
const worldMatrix = ShaderHelper.getWorldMatrix(scope);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
211
|
+
if (vertexOut.Position) {
|
|
212
|
+
scope.$l.oPos = vertexOut.Position;
|
|
213
|
+
scope.$outputs.worldPos = pb.mul(worldMatrix, pb.vec4(scope.oPos, 1)).xyz;
|
|
214
|
+
scope.zWorldPos = scope.$outputs.worldPos;
|
|
215
|
+
scope.$l.csPos = pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.worldPos, 1));
|
|
216
|
+
ShaderHelper.setClipSpacePosition(scope, scope.csPos);
|
|
217
|
+
}
|
|
218
|
+
if (vertexOut.Color) {
|
|
219
|
+
scope.zVertexColor = this.toVec4(scope, vertexOut.Color, 1);
|
|
220
|
+
if (scope.$outputs.zOutDiffuse) {
|
|
221
|
+
scope.$outputs.zOutDiffuse = scope.zVertexColor;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (vertexOut.UV) {
|
|
225
|
+
scope.zVertexUV = this.toVec2(scope, vertexOut.UV);
|
|
226
|
+
if (this._vertexUsesUV) {
|
|
227
|
+
scope.$outputs.zVertexUV = scope.zVertexUV;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (vertexOut.Normal) {
|
|
231
|
+
scope.$l.oNorm = this.toVec3(scope, vertexOut.Normal);
|
|
232
|
+
scope.$outputs.wNorm = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oNorm, 0)).xyz;
|
|
233
|
+
scope.zVertexNormal = scope.$outputs.wNorm;
|
|
234
|
+
}
|
|
235
|
+
if (vertexOut.Tangent) {
|
|
236
|
+
const tangent = vertexOut.Tangent;
|
|
237
|
+
scope.$l.oTangent = tangent.getTypeName() === 'vec4' ? tangent : pb.vec4(this.toVec3(scope, tangent), 1);
|
|
238
|
+
scope.$outputs.wTangent = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oTangent.xyz, 0)).xyz;
|
|
239
|
+
scope.$outputs.wBinormal = pb.mul(pb.cross(scope.$outputs.wNorm, scope.$outputs.wTangent), scope.oTangent.w);
|
|
240
|
+
scope.zVertexTangent = scope.$outputs.wTangent;
|
|
241
|
+
scope.zVertexBinormal = scope.$outputs.wBinormal;
|
|
242
|
+
}
|
|
340
243
|
for (const outputName of [
|
|
341
244
|
'Output1',
|
|
342
245
|
'Output2',
|
|
343
246
|
'Output3',
|
|
344
247
|
'Output4'
|
|
345
248
|
]){
|
|
346
|
-
const output =
|
|
249
|
+
const output = outputs.find((output)=>output.name === outputName)?.exp;
|
|
347
250
|
if (output) {
|
|
348
251
|
scope.$outputs[outputName] = output;
|
|
349
252
|
}
|
|
350
253
|
}
|
|
351
254
|
}
|
|
352
|
-
|
|
353
|
-
* Builds the fragment shader for this PBR blueprint material.
|
|
354
|
-
*
|
|
355
|
-
* @param scope - The current fragment shader function scope.
|
|
356
|
-
*/ fragmentShader(scope) {
|
|
357
|
-
super.fragmentShader(scope);
|
|
255
|
+
fragmentShader(scope) {
|
|
358
256
|
const pb = scope.$builder;
|
|
359
|
-
if (this.
|
|
360
|
-
scope.zSubsurfaceColor = pb.vec3().uniform(2);
|
|
361
|
-
scope.zSubsurfaceScale = pb.float().uniform(2);
|
|
362
|
-
scope.zSubsurfacePower = pb.float().uniform(2);
|
|
363
|
-
scope.zSubsurfaceIntensity = pb.float().uniform(2);
|
|
364
|
-
}
|
|
365
|
-
if (this.needFragmentColor()) {
|
|
366
|
-
scope.zAnisotropy = pb.float().uniform(2);
|
|
367
|
-
scope.zAnisotropyDirection = pb.float().uniform(2);
|
|
368
|
-
scope.zAnisotropyDirectionScaleBias = pb.vec2().uniform(2);
|
|
257
|
+
if (this.needFragmentColorInput()) {
|
|
369
258
|
for (const u of [
|
|
370
259
|
...this._uniformValues,
|
|
371
260
|
...this._uniformTextures
|
|
372
261
|
]){
|
|
373
262
|
if (u.inFragmentShader) {
|
|
374
|
-
// @ts-ignore
|
|
263
|
+
// @ts-ignore dynamic shader type constructor
|
|
375
264
|
pb.getGlobalScope()[u.name] = pb[u.type]().uniform(2);
|
|
376
265
|
}
|
|
377
266
|
}
|
|
378
|
-
scope
|
|
379
|
-
scope
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
267
|
+
scope.zVertexColor = scope.$inputs.zOutDiffuse ?? pb.vec4(1);
|
|
268
|
+
scope.zVertexUV = scope.$inputs.zVertexUV ?? pb.vec2(0);
|
|
269
|
+
scope.zVertexNormal = scope.$inputs.wNorm ?? pb.vec3(0, 0, 1);
|
|
270
|
+
scope.zVertexTangent = scope.$inputs.wTangent ?? pb.vec3(1, 0, 0);
|
|
271
|
+
scope.zVertexBinormal = scope.$inputs.wBinormal ?? pb.vec3(0, 1, 0);
|
|
272
|
+
scope.zWorldPos = scope.$inputs.worldPos;
|
|
273
|
+
}
|
|
274
|
+
super.fragmentShader(scope);
|
|
275
|
+
}
|
|
276
|
+
applyUniformValues(bindGroup, ctx, pass) {
|
|
277
|
+
super.applyUniformValues(bindGroup, ctx, pass);
|
|
278
|
+
if (this.needFragmentColorInput(ctx)) {
|
|
279
|
+
for (const u of this._uniformValues){
|
|
280
|
+
bindGroup.setValue(u.name, u.finalValue);
|
|
281
|
+
}
|
|
282
|
+
for (const u of this._uniformTextures){
|
|
283
|
+
const texture = u.finalTexture?.get();
|
|
284
|
+
if (texture) {
|
|
285
|
+
bindGroup.setTexture(u.name, texture, u.finalSampler);
|
|
395
286
|
}
|
|
396
|
-
} else {
|
|
397
|
-
this.outputFragmentColor(scope, scope.$inputs.worldPos, scope.commonData.albedo);
|
|
398
287
|
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
createProgram(ctx, pass) {
|
|
291
|
+
return super.createProgram(ctx, pass);
|
|
292
|
+
}
|
|
293
|
+
_createHash() {
|
|
294
|
+
return `${super._createHash()}:${this._irFrag.hash}:${this._irVertex.hash}:${this._connectedOutputHash()}`;
|
|
295
|
+
}
|
|
296
|
+
onDispose() {
|
|
297
|
+
super.onDispose();
|
|
298
|
+
for (const u of this._uniformTextures){
|
|
299
|
+
u.finalTexture?.dispose();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
calculateAlbedoColor(scope, uv) {
|
|
303
|
+
const baseColor = this.getBlueprintOutput(scope, 'BaseColor');
|
|
304
|
+
const opacity = this.getBlueprintOutput(scope, 'Opacity');
|
|
305
|
+
if (baseColor !== undefined) {
|
|
306
|
+
const pb = scope.$builder;
|
|
307
|
+
return pb.vec4(this.toVec3(scope, baseColor), opacity ?? 1);
|
|
308
|
+
}
|
|
309
|
+
const albedo = super.calculateAlbedoColor(scope, uv);
|
|
310
|
+
if (opacity !== undefined) {
|
|
311
|
+
const pb = scope.$builder;
|
|
312
|
+
return pb.vec4(albedo.rgb, opacity);
|
|
313
|
+
}
|
|
314
|
+
return albedo;
|
|
315
|
+
}
|
|
316
|
+
calculateMetallic(scope, albedo, normal) {
|
|
317
|
+
const value = this.getBlueprintOutput(scope, 'Metallic');
|
|
318
|
+
if (value !== undefined) {
|
|
319
|
+
return this.toFloat(scope, value);
|
|
320
|
+
}
|
|
321
|
+
return super.calculateMetallic(scope, albedo, normal);
|
|
322
|
+
}
|
|
323
|
+
calculateRoughness(scope, albedo, normal) {
|
|
324
|
+
const value = this.getBlueprintOutput(scope, 'Roughness');
|
|
325
|
+
if (value !== undefined) {
|
|
326
|
+
return this.toFloat(scope, value);
|
|
327
|
+
}
|
|
328
|
+
return super.calculateRoughness(scope, albedo, normal);
|
|
329
|
+
}
|
|
330
|
+
calculateSpecularFactor(scope, albedo, normal) {
|
|
331
|
+
const pb = scope.$builder;
|
|
332
|
+
const base = super.calculateSpecularFactor(scope, albedo, normal);
|
|
333
|
+
const specular = this.getBlueprintOutput(scope, 'Specular');
|
|
334
|
+
const weight = this.getBlueprintOutput(scope, 'SpecularWeight');
|
|
335
|
+
if (specular !== undefined || weight !== undefined) {
|
|
336
|
+
return pb.vec4(specular !== undefined ? this.toVec3(scope, specular) : base.rgb, weight ?? base.a);
|
|
337
|
+
}
|
|
338
|
+
return base;
|
|
339
|
+
}
|
|
340
|
+
calculateEmissiveColor(scope) {
|
|
341
|
+
const emissive = this.getBlueprintOutput(scope, 'Emissive');
|
|
342
|
+
if (emissive !== undefined) {
|
|
343
|
+
return this.toVec3(scope, emissive);
|
|
344
|
+
}
|
|
345
|
+
return super.calculateEmissiveColor(scope);
|
|
346
|
+
}
|
|
347
|
+
calculateNormalAndTBN(scope, worldPos, worldNormal, worldTangent, worldBinormal) {
|
|
348
|
+
const outputNormal = this.getBlueprintOutput(scope, 'Normal');
|
|
349
|
+
const outputTangent = this.getBlueprintOutput(scope, 'Tangent');
|
|
350
|
+
if (outputNormal === undefined && outputTangent === undefined) {
|
|
351
|
+
return super.calculateNormalAndTBN(scope, worldPos, worldNormal, worldTangent, worldBinormal);
|
|
352
|
+
}
|
|
353
|
+
const pb = scope.$builder;
|
|
354
|
+
const NormalStruct = pb.defineStruct([
|
|
355
|
+
pb.mat3('TBN'),
|
|
356
|
+
pb.vec3('normal')
|
|
357
|
+
]);
|
|
358
|
+
const funcName = 'Z_calculateBlueprintNormalAndTBN';
|
|
359
|
+
const that = this;
|
|
360
|
+
pb.func(funcName, [
|
|
361
|
+
pb.vec3('worldPos'),
|
|
362
|
+
pb.vec3('worldNormal'),
|
|
363
|
+
pb.vec3('worldTangent'),
|
|
364
|
+
pb.vec3('worldBinormal'),
|
|
365
|
+
pb.vec3('surfaceNormal'),
|
|
366
|
+
pb.vec3('surfaceTangent')
|
|
367
|
+
], function() {
|
|
368
|
+
this.$l.TBN = that.calculateTBN(this, this.worldPos, this.worldNormal, this.worldTangent, this.worldBinormal);
|
|
369
|
+
this.$l.ng = this.TBN[2];
|
|
370
|
+
this.$l.t = this.TBN[0];
|
|
371
|
+
this.$l.b = this.TBN[1];
|
|
372
|
+
this.$if(pb.greaterThan(pb.length(this.surfaceTangent), 0.0001), function() {
|
|
373
|
+
this.$l.t_ = pb.normalize(this.surfaceTangent);
|
|
374
|
+
this.t = pb.normalize(pb.sub(this.t_, pb.mul(this.ng, pb.dot(this.ng, this.t_))));
|
|
375
|
+
this.b = pb.normalize(pb.cross(this.ng, this.t));
|
|
376
|
+
});
|
|
377
|
+
this.TBN = pb.mat3(this.t, this.b, this.ng);
|
|
378
|
+
this.$l.surfaceNormalTS = this.surfaceNormal;
|
|
379
|
+
this.$if(pb.lessThanEqual(pb.length(this.surfaceNormalTS), 0.0001), function() {
|
|
380
|
+
this.surfaceNormalTS = pb.vec3(0, 0, 1);
|
|
381
|
+
});
|
|
382
|
+
this.$l.surfaceNormalWS = pb.normalize(pb.mul(this.TBN, this.surfaceNormalTS));
|
|
383
|
+
this.$return(NormalStruct(this.TBN, this.surfaceNormalWS));
|
|
384
|
+
});
|
|
385
|
+
return pb.getGlobalScope()[funcName](worldPos, worldNormal ?? scope.zVertexNormal, worldTangent ?? scope.zVertexTangent, worldBinormal ?? scope.zVertexBinormal, outputNormal !== undefined ? this.toVec3(scope, outputNormal) : pb.vec3(0, 0, 1), outputTangent !== undefined ? this.toVec3(scope, outputTangent) : pb.vec3(0));
|
|
386
|
+
}
|
|
387
|
+
indirectLighting(scope, normal, viewVec, commonData, outColor, outRoughness, outDiffuseColor) {
|
|
388
|
+
const ao = this.getBlueprintOutput(scope, 'AO');
|
|
389
|
+
if (ao === undefined) {
|
|
390
|
+
super.indirectLighting(scope, normal, viewVec, commonData, outColor, outRoughness, outDiffuseColor);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const pb = scope.$builder;
|
|
394
|
+
const funcName = `Z_applyBlueprintAO${outDiffuseColor ? '_D' : ''}`;
|
|
395
|
+
pb.func(funcName, [
|
|
396
|
+
pb.vec3('outColor').inout(),
|
|
397
|
+
...outDiffuseColor ? [
|
|
398
|
+
pb.vec3('outDiffuseColor').inout()
|
|
399
|
+
] : [],
|
|
400
|
+
pb.float('ao')
|
|
401
|
+
], function() {
|
|
402
|
+
this.outColor = pb.mul(this.outColor, this.ao);
|
|
403
|
+
if (outDiffuseColor) {
|
|
404
|
+
this.outDiffuseColor = pb.mul(this.outDiffuseColor, this.ao);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
super.indirectLighting(scope, normal, viewVec, commonData, outColor, outRoughness, outDiffuseColor);
|
|
408
|
+
if (outDiffuseColor) {
|
|
409
|
+
pb.getGlobalScope()[funcName](outColor, outDiffuseColor, ao);
|
|
399
410
|
} else {
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
bindGroup.setValue('zSubsurfaceIntensity', this._subsurfaceIntensity);
|
|
411
|
+
pb.getGlobalScope()[funcName](outColor, ao);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
syncBlueprintMetadata() {
|
|
415
|
+
this._connectedOutputs = this.collectConnectedOutputs(this._irFrag, PBRBlockNode);
|
|
416
|
+
const fragmentUsesColor = this._irFrag.behaviors.useVertexColor;
|
|
417
|
+
const fragmentUsesUV = this._irFrag.behaviors.useVertexUV;
|
|
418
|
+
const vertexUsesColor = this._irVertex.behaviors.useVertexColor;
|
|
419
|
+
const vertexUsesUV = this._irVertex.behaviors.useVertexUV;
|
|
420
|
+
this._vertexUsesColor = fragmentUsesColor || vertexUsesColor;
|
|
421
|
+
this._vertexUsesUV = fragmentUsesUV || vertexUsesUV;
|
|
422
|
+
this.useFeature(PBRBluePrintMaterial.FEATURE_BLUEPRINT_VERTEX_COLOR, this._vertexUsesColor);
|
|
423
|
+
this.useFeature(PBRBluePrintMaterial.FEATURE_BLUEPRINT_VERTEX_UV, this._vertexUsesUV);
|
|
424
|
+
}
|
|
425
|
+
collectConnectedOutputs(ir, rootCtor) {
|
|
426
|
+
const outputs = new Set();
|
|
427
|
+
for (const rootId of ir.DAG.roots){
|
|
428
|
+
const rootNode = ir.DAG.nodeMap[rootId];
|
|
429
|
+
if (!(rootNode instanceof rootCtor)) {
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
for (const input of rootNode.inputs){
|
|
433
|
+
if (input.inputNode) {
|
|
434
|
+
outputs.add(input.name);
|
|
435
|
+
}
|
|
426
436
|
}
|
|
427
437
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
438
|
+
return outputs;
|
|
439
|
+
}
|
|
440
|
+
getBlueprintVertexColor(scope) {
|
|
441
|
+
const pb = scope.$builder;
|
|
442
|
+
if (this.vertexColor) {
|
|
443
|
+
return this.getVertexColor(scope);
|
|
444
|
+
}
|
|
445
|
+
if (this._vertexUsesColor) {
|
|
446
|
+
if (scope.$inputs.zDiffuse) {
|
|
447
|
+
return scope.$inputs.zDiffuse;
|
|
448
|
+
}
|
|
449
|
+
if (scope.$getVertexAttrib('diffuse')) {
|
|
450
|
+
return scope.$getVertexAttrib('diffuse');
|
|
431
451
|
}
|
|
452
|
+
scope.$inputs.zDiffuse = pb.vec4().attrib('diffuse');
|
|
453
|
+
return scope.$inputs.zDiffuse;
|
|
432
454
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
455
|
+
return pb.vec4(1);
|
|
456
|
+
}
|
|
457
|
+
getBlueprintVertexUV(scope) {
|
|
458
|
+
const pb = scope.$builder;
|
|
459
|
+
if (this._vertexUsesUV) {
|
|
460
|
+
if (scope.$inputs.zVertexUV) {
|
|
461
|
+
return scope.$inputs.zVertexUV;
|
|
436
462
|
}
|
|
463
|
+
if (scope.$getVertexAttrib('texCoord0')) {
|
|
464
|
+
return scope.$getVertexAttrib('texCoord0');
|
|
465
|
+
}
|
|
466
|
+
scope.$inputs.zVertexUV = pb.vec2().attrib('texCoord0');
|
|
467
|
+
return scope.$inputs.zVertexUV;
|
|
468
|
+
}
|
|
469
|
+
if (this.albedoTexture) {
|
|
470
|
+
return this.getAlbedoTexCoord(scope) ?? pb.vec2(0);
|
|
437
471
|
}
|
|
472
|
+
return pb.vec2(0);
|
|
438
473
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
* @remarks
|
|
443
|
-
* The hash includes:
|
|
444
|
-
* - The base material hash (`super._createHash()`).
|
|
445
|
-
* - The fragment IR hash.
|
|
446
|
-
* - The vertex IR hash.
|
|
447
|
-
*
|
|
448
|
-
* Different blueprint graphs will therefore produce different programs.
|
|
449
|
-
*
|
|
450
|
-
* @returns A hash string that uniquely identifies this material configuration.
|
|
451
|
-
*/ _createHash() {
|
|
452
|
-
return `${super._createHash()}:${this._irFrag.hash}:${this._irVertex.hash}`;
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Creates the GPU program for this blueprint PBR material.
|
|
456
|
-
*
|
|
457
|
-
* @remarks
|
|
458
|
-
* This calls the base implementation and returns its result.
|
|
459
|
-
* Commented-out `console.log` lines are provided for debugging the
|
|
460
|
-
* generated vertex and fragment shader sources.
|
|
461
|
-
*
|
|
462
|
-
* @param ctx - The current draw context.
|
|
463
|
-
* @param pass - Index of the active render pass.
|
|
464
|
-
* @returns The created GPU program.
|
|
465
|
-
*/ createProgram(ctx, pass) {
|
|
466
|
-
const program = super.createProgram(ctx, pass);
|
|
467
|
-
//console.log(program.getShaderSource('vertex'));
|
|
468
|
-
//console.log(program.getShaderSource('fragment'));
|
|
469
|
-
return program;
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* Disposes resources associated with this material.
|
|
473
|
-
*
|
|
474
|
-
* @remarks
|
|
475
|
-
* - Calls the base `onDispose` to clean up inherited resources.
|
|
476
|
-
* - Disposes all `finalTexture` references from the blueprint
|
|
477
|
-
* texture uniform descriptors.
|
|
478
|
-
*
|
|
479
|
-
* This method is intended to be called by the engine's resource
|
|
480
|
-
* management system rather than directly by user code.
|
|
481
|
-
*/ onDispose() {
|
|
482
|
-
super.onDispose();
|
|
483
|
-
for (const u of this._uniformTextures){
|
|
484
|
-
u.finalTexture.dispose();
|
|
474
|
+
getBlueprintOutput(scope, name) {
|
|
475
|
+
if (!this._connectedOutputs.has(name)) {
|
|
476
|
+
return undefined;
|
|
485
477
|
}
|
|
478
|
+
return this.getBlueprintOutputMap(scope)[name];
|
|
486
479
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
480
|
+
getBlueprintOutputMap(scope) {
|
|
481
|
+
const pb = scope.$builder;
|
|
482
|
+
const funcName = 'Z_GetPBRBlueprintOutputs';
|
|
483
|
+
const that = this;
|
|
484
|
+
const outputsStruct = pb.defineStruct(DEFAULT_OUTPUT_NAMES.map((name)=>{
|
|
485
|
+
switch(name){
|
|
486
|
+
case 'BaseColor':
|
|
487
|
+
return pb.vec3(name);
|
|
488
|
+
case 'Specular':
|
|
489
|
+
case 'Emissive':
|
|
490
|
+
case 'Normal':
|
|
491
|
+
case 'Tangent':
|
|
492
|
+
return pb.vec3(name);
|
|
493
|
+
default:
|
|
494
|
+
return pb.float(name);
|
|
495
|
+
}
|
|
496
|
+
}));
|
|
497
|
+
if (!pb.getGlobalScope()[funcName]) {
|
|
498
|
+
pb.func(funcName, [
|
|
499
|
+
pb.vec3('worldPos'),
|
|
500
|
+
pb.vec4('vertexColor'),
|
|
501
|
+
pb.vec2('vertexUV'),
|
|
502
|
+
pb.vec3('vertexNormal'),
|
|
503
|
+
pb.vec3('vertexTangent'),
|
|
504
|
+
pb.vec3('vertexBinormal')
|
|
505
|
+
], function() {
|
|
506
|
+
this.zWorldPos = this.worldPos;
|
|
507
|
+
this.zVertexColor = this.vertexColor;
|
|
508
|
+
this.zVertexUV = this.vertexUV;
|
|
509
|
+
this.zVertexNormal = this.vertexNormal;
|
|
510
|
+
this.zVertexTangent = this.vertexTangent;
|
|
511
|
+
this.zVertexBinormal = this.vertexBinormal;
|
|
512
|
+
const outputs = that._irFrag.create(pb);
|
|
513
|
+
let baseColor = pb.vec3(1);
|
|
514
|
+
let metallic = 0;
|
|
515
|
+
let roughness = 1;
|
|
516
|
+
let specular = pb.vec3(1);
|
|
517
|
+
let emissive = pb.vec3(0);
|
|
518
|
+
let normal = pb.vec3(0);
|
|
519
|
+
let tangent = pb.vec3(0);
|
|
520
|
+
let opacity = 1;
|
|
521
|
+
let specularWeight = 1;
|
|
522
|
+
let ao = 1;
|
|
523
|
+
if (outputs) {
|
|
524
|
+
const map = that.toOutputMap(outputs);
|
|
525
|
+
if (map.BaseColor !== undefined) {
|
|
526
|
+
baseColor = that.toVec3(scope, map.BaseColor);
|
|
527
|
+
}
|
|
528
|
+
if (map.Metallic !== undefined) {
|
|
529
|
+
metallic = map.Metallic;
|
|
530
|
+
}
|
|
531
|
+
if (map.Roughness !== undefined) {
|
|
532
|
+
roughness = map.Roughness;
|
|
533
|
+
}
|
|
534
|
+
if (map.Specular !== undefined) {
|
|
535
|
+
specular = that.toVec3(scope, map.Specular);
|
|
536
|
+
}
|
|
537
|
+
if (map.Emissive !== undefined) {
|
|
538
|
+
emissive = that.toVec3(scope, map.Emissive);
|
|
539
|
+
}
|
|
540
|
+
if (map.Normal !== undefined) {
|
|
541
|
+
normal = that.toVec3(scope, map.Normal);
|
|
542
|
+
}
|
|
543
|
+
if (map.Tangent !== undefined) {
|
|
544
|
+
tangent = that.toVec3(scope, map.Tangent);
|
|
545
|
+
}
|
|
546
|
+
if (map.Opacity !== undefined) {
|
|
547
|
+
opacity = map.Opacity;
|
|
548
|
+
}
|
|
549
|
+
if (map.SpecularWeight !== undefined) {
|
|
550
|
+
specularWeight = map.SpecularWeight;
|
|
551
|
+
}
|
|
552
|
+
if (map.AO !== undefined) {
|
|
553
|
+
ao = map.AO;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
this.$return(outputsStruct(baseColor, metallic, roughness, specular, emissive, normal, tangent, opacity, specularWeight, ao));
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
const result = pb.getGlobalScope()[funcName](this.getBlueprintWorldPos(scope), this.getBlueprintFragmentVertexColor(scope), this.getBlueprintFragmentVertexUV(scope), this.getBlueprintFragmentVertexNormal(scope), this.getBlueprintFragmentVertexTangent(scope), this.getBlueprintFragmentVertexBinormal(scope));
|
|
560
|
+
const map = {};
|
|
561
|
+
for (const name of DEFAULT_OUTPUT_NAMES){
|
|
562
|
+
map[name] = result[name];
|
|
563
|
+
}
|
|
564
|
+
return map;
|
|
565
|
+
}
|
|
566
|
+
getBlueprintWorldPos(scope) {
|
|
567
|
+
const pb = scope.$builder;
|
|
568
|
+
return scope.$inputs.worldPos ?? scope.zWorldPos ?? pb.vec3(0);
|
|
569
|
+
}
|
|
570
|
+
getBlueprintFragmentVertexColor(scope) {
|
|
571
|
+
const pb = scope.$builder;
|
|
572
|
+
return scope.$inputs.zOutDiffuse ?? scope.zVertexColor ?? pb.vec4(1);
|
|
573
|
+
}
|
|
574
|
+
getBlueprintFragmentVertexUV(scope) {
|
|
575
|
+
const pb = scope.$builder;
|
|
576
|
+
return scope.$inputs.zVertexUV ?? scope.zVertexUV ?? pb.vec2(0);
|
|
577
|
+
}
|
|
578
|
+
getBlueprintFragmentVertexNormal(scope) {
|
|
579
|
+
const pb = scope.$builder;
|
|
580
|
+
return scope.$inputs.wNorm ?? scope.zVertexNormal ?? pb.vec3(0, 0, 1);
|
|
581
|
+
}
|
|
582
|
+
getBlueprintFragmentVertexTangent(scope) {
|
|
583
|
+
const pb = scope.$builder;
|
|
584
|
+
return scope.$inputs.wTangent ?? scope.zVertexTangent ?? pb.vec3(1, 0, 0);
|
|
585
|
+
}
|
|
586
|
+
getBlueprintFragmentVertexBinormal(scope) {
|
|
587
|
+
const pb = scope.$builder;
|
|
588
|
+
return scope.$inputs.wBinormal ?? scope.zVertexBinormal ?? pb.vec3(0, 1, 0);
|
|
589
|
+
}
|
|
590
|
+
toOutputMap(outputs) {
|
|
591
|
+
const map = {};
|
|
592
|
+
for (const output of outputs){
|
|
593
|
+
map[output.name] = output.exp;
|
|
594
|
+
}
|
|
595
|
+
return map;
|
|
596
|
+
}
|
|
597
|
+
toVertexOutputMap(outputs) {
|
|
598
|
+
const map = {};
|
|
599
|
+
for (const output of outputs){
|
|
600
|
+
map[output.name] = output.exp;
|
|
601
|
+
}
|
|
602
|
+
return map;
|
|
603
|
+
}
|
|
604
|
+
toFloat(scope, value) {
|
|
605
|
+
const pb = scope.$builder;
|
|
606
|
+
if (typeof value === 'number') {
|
|
607
|
+
return pb.float(value);
|
|
608
|
+
}
|
|
609
|
+
const exp = value;
|
|
610
|
+
return exp.getTypeName() === 'float' ? exp : exp.x;
|
|
611
|
+
}
|
|
612
|
+
toVec2(scope, value) {
|
|
613
|
+
const pb = scope.$builder;
|
|
614
|
+
if (typeof value === 'number') {
|
|
615
|
+
return pb.vec2(value);
|
|
616
|
+
}
|
|
617
|
+
const exp = value;
|
|
618
|
+
const type = exp.getTypeName();
|
|
619
|
+
if (type === 'float') {
|
|
620
|
+
return pb.vec2(exp);
|
|
621
|
+
}
|
|
622
|
+
if (type === 'vec3' || type === 'vec4') {
|
|
623
|
+
return exp.xy;
|
|
624
|
+
}
|
|
625
|
+
return exp;
|
|
626
|
+
}
|
|
627
|
+
toVec3(scope, value) {
|
|
628
|
+
const pb = scope.$builder;
|
|
629
|
+
if (typeof value === 'number') {
|
|
630
|
+
return pb.vec3(value);
|
|
631
|
+
}
|
|
632
|
+
const exp = value;
|
|
633
|
+
const type = exp.getTypeName();
|
|
634
|
+
if (type === 'float') {
|
|
635
|
+
return pb.vec3(exp);
|
|
636
|
+
}
|
|
637
|
+
if (type === 'vec2') {
|
|
638
|
+
return pb.vec3(exp, 0);
|
|
639
|
+
}
|
|
640
|
+
if (type === 'vec4') {
|
|
641
|
+
return exp.xyz;
|
|
642
|
+
}
|
|
643
|
+
return exp;
|
|
495
644
|
}
|
|
496
|
-
|
|
645
|
+
toVec4(scope, value, alpha) {
|
|
497
646
|
const pb = scope.$builder;
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
647
|
+
if (typeof value === 'number') {
|
|
648
|
+
return pb.vec4(value, value, value, alpha);
|
|
649
|
+
}
|
|
650
|
+
const exp = value;
|
|
651
|
+
const type = exp.getTypeName();
|
|
652
|
+
if (type === 'float') {
|
|
653
|
+
return pb.vec4(pb.vec3(exp), alpha);
|
|
654
|
+
}
|
|
655
|
+
if (type === 'vec2') {
|
|
656
|
+
return pb.vec4(exp, 0, alpha);
|
|
657
|
+
}
|
|
658
|
+
if (type === 'vec3') {
|
|
659
|
+
return pb.vec4(exp, alpha);
|
|
660
|
+
}
|
|
661
|
+
return exp;
|
|
662
|
+
}
|
|
663
|
+
_connectedOutputHash() {
|
|
664
|
+
return DEFAULT_OUTPUT_NAMES.map((name)=>this._connectedOutputs.has(name) ? '1' : '0').join('');
|
|
502
665
|
}
|
|
503
666
|
}
|
|
504
667
|
|