@zephyr3d/scene 0.9.6 → 0.9.7
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/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 +21 -20
- 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 +134 -140
- 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 +20 -16
- package/dist/avatar/wardrobe.js.map +1 -1
- package/dist/camera/camera.js +416 -210
- package/dist/camera/camera.js.map +1 -1
- package/dist/index.d.ts +1349 -621
- 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 +105 -32
- 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 +499 -336
- 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 +324 -294
- 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 +422 -96
- 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 +110 -23
- 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 +80 -66
- 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 +327 -359
- 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
package/dist/shadow/shader.js
CHANGED
|
@@ -3,37 +3,88 @@ import '../material/lambert.js';
|
|
|
3
3
|
import '../material/blinn.js';
|
|
4
4
|
import '../material/unlit.js';
|
|
5
5
|
import '../material/particle.js';
|
|
6
|
+
import '../material/subsurfaceprofile.js';
|
|
6
7
|
import '@zephyr3d/device';
|
|
7
|
-
import '../values.js';
|
|
8
|
+
import { LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_SPOT, LIGHT_TYPE_POINT } from '../values.js';
|
|
8
9
|
import '@zephyr3d/base';
|
|
9
10
|
import '../material/meshmaterial.js';
|
|
10
11
|
import '../material/grassmaterial.js';
|
|
11
12
|
import '../material/terrain-cm.js';
|
|
12
13
|
import '../material/pbrmr.js';
|
|
13
14
|
import '../material/pbrsg.js';
|
|
15
|
+
import '../material/mtoon.js';
|
|
14
16
|
import '../material/pbrblueprint.js';
|
|
15
17
|
import '../material/sprite.js';
|
|
16
18
|
import '../material/sprite_std.js';
|
|
17
|
-
import '../material/msdf_text.js';
|
|
18
19
|
import '../utility/blueprint/material/texture.js';
|
|
19
20
|
|
|
21
|
+
function getShadowReceiverBiasFactors(scope) {
|
|
22
|
+
const pb = scope.$builder;
|
|
23
|
+
const alphaCutoff = scope.zAlphaCutoff;
|
|
24
|
+
if (alphaCutoff) {
|
|
25
|
+
// Thin masked geometry such as layered hair cards needs a tighter receiver bias,
|
|
26
|
+
// otherwise nearby layers lose self-shadow before the shadow map is even sampled.
|
|
27
|
+
const cutoff = pb.clamp(alphaCutoff, 0, 1);
|
|
28
|
+
return pb.vec2(pb.mix(0.22, 0.4, cutoff), pb.mix(0.05, 0.16, cutoff));
|
|
29
|
+
}
|
|
30
|
+
return pb.vec2(1, 1);
|
|
31
|
+
}
|
|
32
|
+
function isMaskedPerspectiveShadowLight(scope, lightType) {
|
|
33
|
+
const alphaCutoff = scope.zAlphaCutoff;
|
|
34
|
+
return !!alphaCutoff && (lightType === LIGHT_TYPE_SPOT || lightType === LIGHT_TYPE_POINT);
|
|
35
|
+
}
|
|
36
|
+
function getShadowReceiverNoL(scope, NdotL, lightType) {
|
|
37
|
+
const pb = scope.$builder;
|
|
38
|
+
const alphaCutoff = scope.zAlphaCutoff;
|
|
39
|
+
if (alphaCutoff) {
|
|
40
|
+
// Layered masked cards should not explode slope bias at grazing angles.
|
|
41
|
+
// This is especially visible for back / rim spot lights on hair cards.
|
|
42
|
+
const cutoff = pb.clamp(alphaCutoff, 0, 1);
|
|
43
|
+
if (lightType != null && isMaskedPerspectiveShadowLight(scope, lightType)) {
|
|
44
|
+
return pb.max(NdotL, pb.mix(0.85, 0.95, cutoff));
|
|
45
|
+
}
|
|
46
|
+
return pb.max(NdotL, pb.mix(0.45, 0.65, cutoff));
|
|
47
|
+
}
|
|
48
|
+
return NdotL;
|
|
49
|
+
}
|
|
50
|
+
function getShadowReceiverPerspectiveBiasScale(scope, lightType, linearDepth, farNearRatio) {
|
|
51
|
+
const pb = scope.$builder;
|
|
52
|
+
const alphaCutoff = scope.zAlphaCutoff;
|
|
53
|
+
if (alphaCutoff && isMaskedPerspectiveShadowLight(scope, lightType)) {
|
|
54
|
+
const cutoff = pb.clamp(alphaCutoff, 0, 1);
|
|
55
|
+
// Perspective shadow cameras (spot / point) can over-amplify receiver bias at depth.
|
|
56
|
+
// Keep masked layered geometry in a much tighter range so hair cards can still self-occlude.
|
|
57
|
+
const cappedFarNearRatio = pb.min(farNearRatio, pb.mix(1.15, 1.6, cutoff));
|
|
58
|
+
return pb.mix(1, cappedFarNearRatio, linearDepth);
|
|
59
|
+
}
|
|
60
|
+
return pb.mix(1, farNearRatio, linearDepth);
|
|
61
|
+
}
|
|
20
62
|
function computeShadowBiasCSM(scope, NdotL, split) {
|
|
21
63
|
const pb = scope.$builder;
|
|
22
64
|
const depthBiasParam = ShaderHelper.getDepthBiasValues(scope);
|
|
23
65
|
const splitFlags = pb.vec4(pb.float(pb.equal(split, 0)), pb.float(pb.equal(split, 1)), pb.float(pb.equal(split, 2)), pb.float(pb.equal(split, 3)));
|
|
24
66
|
const depthBiasScale = pb.dot(ShaderHelper.getDepthBiasScales(scope), splitFlags);
|
|
25
|
-
|
|
67
|
+
const receiverBiasFactors = getShadowReceiverBiasFactors(scope);
|
|
68
|
+
const receiverNoL = getShadowReceiverNoL(scope, NdotL);
|
|
69
|
+
return pb.dot(pb.mul(depthBiasParam.xy, receiverBiasFactors, pb.vec2(1, pb.sub(1, receiverNoL)), depthBiasScale), pb.vec2(1, 1));
|
|
26
70
|
}
|
|
27
71
|
function computeShadowBias(lightType, scope, z, NdotL, linear) {
|
|
28
72
|
const pb = scope.$builder;
|
|
29
73
|
const depthBiasParam = ShaderHelper.getDepthBiasValues(scope);
|
|
30
|
-
|
|
31
|
-
|
|
74
|
+
const receiverBiasFactors = getShadowReceiverBiasFactors(scope);
|
|
75
|
+
const receiverNoL = getShadowReceiverNoL(scope, NdotL, lightType);
|
|
76
|
+
if (lightType === LIGHT_TYPE_DIRECTIONAL) {
|
|
77
|
+
return pb.dot(pb.mul(depthBiasParam.xy, receiverBiasFactors, pb.vec2(1, pb.sub(1, receiverNoL))), pb.vec2(1, 1));
|
|
32
78
|
} else {
|
|
33
79
|
const nearFar = ShaderHelper.getShadowCameraParams(scope).xy;
|
|
34
80
|
const linearDepth = linear ? z : ShaderHelper.nonLinearDepthToLinearNormalized(scope, z, nearFar);
|
|
35
|
-
const biasScaleFactor =
|
|
36
|
-
|
|
81
|
+
const biasScaleFactor = getShadowReceiverPerspectiveBiasScale(scope, lightType, linearDepth, depthBiasParam.w);
|
|
82
|
+
let bias = pb.dot(pb.mul(depthBiasParam.xy, receiverBiasFactors, pb.vec2(1, pb.sub(1, receiverNoL)), biasScaleFactor), pb.vec2(1, 1));
|
|
83
|
+
if (isMaskedPerspectiveShadowLight(scope, lightType)) {
|
|
84
|
+
const alphaCutoff = scope.zAlphaCutoff;
|
|
85
|
+
bias = pb.mul(bias, pb.mix(0.12, 0.22, pb.clamp(alphaCutoff, 0, 1)));
|
|
86
|
+
}
|
|
87
|
+
return bias;
|
|
37
88
|
}
|
|
38
89
|
}
|
|
39
90
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader.js","sources":["../../src/shadow/shader.ts"],"sourcesContent":["import type { PBInsideFunctionScope, PBShaderExp } from '@zephyr3d/device';\r\nimport { ShaderHelper } from '../material';\r\n\r\nexport function computeShadowBiasCSM(scope: PBInsideFunctionScope, NdotL: PBShaderExp, split: PBShaderExp) {\r\n const pb = scope.$builder;\r\n const depthBiasParam = ShaderHelper.getDepthBiasValues(scope);\r\n const splitFlags = pb.vec4(\r\n pb.float(pb.equal(split, 0)),\r\n pb.float(pb.equal(split, 1)),\r\n pb.float(pb.equal(split, 2)),\r\n pb.float(pb.equal(split, 3))\r\n );\r\n const depthBiasScale = pb.dot(ShaderHelper.getDepthBiasScales(scope), splitFlags);\r\n return pb.dot(pb.mul(depthBiasParam.xy, pb.vec2(1, pb.sub(1,
|
|
1
|
+
{"version":3,"file":"shader.js","sources":["../../src/shadow/shader.ts"],"sourcesContent":["import type { PBInsideFunctionScope, PBShaderExp } from '@zephyr3d/device';\r\nimport { ShaderHelper } from '../material';\r\nimport { LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_POINT, LIGHT_TYPE_SPOT } from '../values';\r\n\r\nfunction getShadowReceiverBiasFactors(scope: PBInsideFunctionScope) {\r\n const pb = scope.$builder;\r\n const alphaCutoff = (scope as PBInsideFunctionScope & { zAlphaCutoff?: PBShaderExp }).zAlphaCutoff;\r\n if (alphaCutoff) {\r\n // Thin masked geometry such as layered hair cards needs a tighter receiver bias,\r\n // otherwise nearby layers lose self-shadow before the shadow map is even sampled.\r\n const cutoff = pb.clamp(alphaCutoff, 0, 1);\r\n return pb.vec2(pb.mix(0.22, 0.4, cutoff), pb.mix(0.05, 0.16, cutoff)) as PBShaderExp;\r\n }\r\n return pb.vec2(1, 1) as PBShaderExp;\r\n}\r\n\r\nfunction isMaskedPerspectiveShadowLight(scope: PBInsideFunctionScope, lightType: number) {\r\n const alphaCutoff = (scope as PBInsideFunctionScope & { zAlphaCutoff?: PBShaderExp }).zAlphaCutoff;\r\n return !!alphaCutoff && (lightType === LIGHT_TYPE_SPOT || lightType === LIGHT_TYPE_POINT);\r\n}\r\n\r\nfunction getShadowReceiverNoL(scope: PBInsideFunctionScope, NdotL: PBShaderExp, lightType?: number) {\r\n const pb = scope.$builder;\r\n const alphaCutoff = (scope as PBInsideFunctionScope & { zAlphaCutoff?: PBShaderExp }).zAlphaCutoff;\r\n if (alphaCutoff) {\r\n // Layered masked cards should not explode slope bias at grazing angles.\r\n // This is especially visible for back / rim spot lights on hair cards.\r\n const cutoff = pb.clamp(alphaCutoff, 0, 1);\r\n if (lightType != null && isMaskedPerspectiveShadowLight(scope, lightType)) {\r\n return pb.max(NdotL, pb.mix(0.85, 0.95, cutoff)) as PBShaderExp;\r\n }\r\n return pb.max(NdotL, pb.mix(0.45, 0.65, cutoff)) as PBShaderExp;\r\n }\r\n return NdotL as PBShaderExp;\r\n}\r\n\r\nfunction getShadowReceiverPerspectiveBiasScale(\r\n scope: PBInsideFunctionScope,\r\n lightType: number,\r\n linearDepth: PBShaderExp,\r\n farNearRatio: PBShaderExp\r\n) {\r\n const pb = scope.$builder;\r\n const alphaCutoff = (scope as PBInsideFunctionScope & { zAlphaCutoff?: PBShaderExp }).zAlphaCutoff;\r\n if (alphaCutoff && isMaskedPerspectiveShadowLight(scope, lightType)) {\r\n const cutoff = pb.clamp(alphaCutoff, 0, 1);\r\n // Perspective shadow cameras (spot / point) can over-amplify receiver bias at depth.\r\n // Keep masked layered geometry in a much tighter range so hair cards can still self-occlude.\r\n const cappedFarNearRatio = pb.min(farNearRatio, pb.mix(1.15, 1.6, cutoff));\r\n return pb.mix(1, cappedFarNearRatio, linearDepth) as PBShaderExp;\r\n }\r\n return pb.mix(1, farNearRatio, linearDepth) as PBShaderExp;\r\n}\r\n\r\nexport function computeShadowBiasCSM(scope: PBInsideFunctionScope, NdotL: PBShaderExp, split: PBShaderExp) {\r\n const pb = scope.$builder;\r\n const depthBiasParam = ShaderHelper.getDepthBiasValues(scope);\r\n const splitFlags = pb.vec4(\r\n pb.float(pb.equal(split, 0)),\r\n pb.float(pb.equal(split, 1)),\r\n pb.float(pb.equal(split, 2)),\r\n pb.float(pb.equal(split, 3))\r\n );\r\n const depthBiasScale = pb.dot(ShaderHelper.getDepthBiasScales(scope), splitFlags);\r\n const receiverBiasFactors = getShadowReceiverBiasFactors(scope);\r\n const receiverNoL = getShadowReceiverNoL(scope, NdotL);\r\n return pb.dot(\r\n pb.mul(depthBiasParam.xy, receiverBiasFactors, pb.vec2(1, pb.sub(1, receiverNoL)), depthBiasScale),\r\n pb.vec2(1, 1)\r\n );\r\n}\r\n\r\nexport function computeShadowBias(\r\n lightType: number,\r\n scope: PBInsideFunctionScope,\r\n z: PBShaderExp,\r\n NdotL: PBShaderExp,\r\n linear: boolean\r\n) {\r\n const pb = scope.$builder;\r\n const depthBiasParam = ShaderHelper.getDepthBiasValues(scope);\r\n const receiverBiasFactors = getShadowReceiverBiasFactors(scope);\r\n const receiverNoL = getShadowReceiverNoL(scope, NdotL, lightType);\r\n if (lightType === LIGHT_TYPE_DIRECTIONAL) {\r\n return pb.dot(\r\n pb.mul(depthBiasParam.xy, receiverBiasFactors, pb.vec2(1, pb.sub(1, receiverNoL))),\r\n pb.vec2(1, 1)\r\n );\r\n } else {\r\n const nearFar = ShaderHelper.getShadowCameraParams(scope).xy;\r\n const linearDepth = linear ? z : ShaderHelper.nonLinearDepthToLinearNormalized(scope, z, nearFar);\r\n const biasScaleFactor = getShadowReceiverPerspectiveBiasScale(\r\n scope,\r\n lightType,\r\n linearDepth,\r\n depthBiasParam.w\r\n );\r\n let bias = pb.dot(\r\n pb.mul(depthBiasParam.xy, receiverBiasFactors, pb.vec2(1, pb.sub(1, receiverNoL)), biasScaleFactor),\r\n pb.vec2(1, 1)\r\n );\r\n if (isMaskedPerspectiveShadowLight(scope, lightType)) {\r\n const alphaCutoff = (scope as PBInsideFunctionScope & { zAlphaCutoff?: PBShaderExp }).zAlphaCutoff!;\r\n bias = pb.mul(bias, pb.mix(0.12, 0.22, pb.clamp(alphaCutoff, 0, 1))) as PBShaderExp;\r\n }\r\n return bias;\r\n }\r\n}\r\n"],"names":["getShadowReceiverBiasFactors","scope","pb","$builder","alphaCutoff","zAlphaCutoff","cutoff","clamp","vec2","mix","isMaskedPerspectiveShadowLight","lightType","LIGHT_TYPE_SPOT","LIGHT_TYPE_POINT","getShadowReceiverNoL","NdotL","max","getShadowReceiverPerspectiveBiasScale","linearDepth","farNearRatio","cappedFarNearRatio","min","computeShadowBiasCSM","split","depthBiasParam","ShaderHelper","getDepthBiasValues","splitFlags","vec4","float","equal","depthBiasScale","dot","getDepthBiasScales","receiverBiasFactors","receiverNoL","mul","xy","sub","computeShadowBias","z","linear","LIGHT_TYPE_DIRECTIONAL","nearFar","getShadowCameraParams","nonLinearDepthToLinearNormalized","biasScaleFactor","w","bias"],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Vector4 } from '@zephyr3d/base';
|
|
2
|
+
|
|
1
3
|
/** @internal */ class ShadowImpl {
|
|
2
4
|
_resourceDirty;
|
|
3
5
|
constructor(){
|
|
@@ -9,6 +11,10 @@
|
|
|
9
11
|
updateResources(shadowMapParams) {
|
|
10
12
|
this.doUpdateResources(shadowMapParams);
|
|
11
13
|
}
|
|
14
|
+
getShadowMapClearColor(shadowMapParams) {
|
|
15
|
+
const colorAttachment = shadowMapParams.shadowMapFramebuffer?.getColorAttachments()[0];
|
|
16
|
+
return colorAttachment ? colorAttachment.isFloatFormat() ? new Vector4(1, 1, 1, 1) : new Vector4(0, 0, 0, 1) : null;
|
|
17
|
+
}
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
export { ShadowImpl };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow_impl.js","sources":["../../src/shadow/shadow_impl.ts"],"sourcesContent":["import type { PBInsideFunctionScope, PBShaderExp, TextureFormat } from '@zephyr3d/device';\r\nimport type { ShadowMapParams, ShadowMapType, ShadowMode } from './shadowmapper';\r\nimport type
|
|
1
|
+
{"version":3,"file":"shadow_impl.js","sources":["../../src/shadow/shadow_impl.ts"],"sourcesContent":["import type { PBInsideFunctionScope, PBShaderExp, TextureFormat } from '@zephyr3d/device';\r\nimport type { ShadowMapParams, ShadowMapType, ShadowMode } from './shadowmapper';\r\nimport { Vector4, type Nullable } from '@zephyr3d/base';\r\n\r\n/** @internal */\r\nexport abstract class ShadowImpl {\r\n protected _resourceDirty: boolean;\r\n constructor() {\r\n this._resourceDirty = true;\r\n }\r\n invalidateResource() {\r\n this._resourceDirty = true;\r\n }\r\n updateResources(shadowMapParams: ShadowMapParams) {\r\n this.doUpdateResources(shadowMapParams);\r\n }\r\n abstract getType(): ShadowMode;\r\n abstract getShadowMapBorder(shadowMapParams: ShadowMapParams): number;\r\n getShadowMapClearColor(shadowMapParams: ShadowMapParams) {\r\n const colorAttachment = shadowMapParams.shadowMapFramebuffer?.getColorAttachments()[0];\r\n return colorAttachment\r\n ? colorAttachment.isFloatFormat()\r\n ? new Vector4(1, 1, 1, 1)\r\n : new Vector4(0, 0, 0, 1)\r\n : null;\r\n }\r\n abstract getShadowMap(shadowMapParams: ShadowMapParams): ShadowMapType;\r\n abstract postRenderShadowMap(shadowMapParams: ShadowMapParams): void;\r\n abstract getDepthScale(): number;\r\n abstract setDepthScale(val: number): void;\r\n abstract resourceDirty(): boolean;\r\n abstract doUpdateResources(shadowMapParams: ShadowMapParams): void;\r\n abstract getShaderHash(): string;\r\n abstract computeShadowMapDepth(\r\n shadowMapParams: ShadowMapParams,\r\n scope: PBInsideFunctionScope,\r\n worldPos: PBShaderExp\r\n ): PBShaderExp;\r\n abstract computeShadow(\r\n shadowMapParams: ShadowMapParams,\r\n scope: PBInsideFunctionScope,\r\n shadowVertex: PBShaderExp,\r\n NdotL: PBShaderExp\r\n ): PBShaderExp;\r\n abstract computeShadowCSM(\r\n shadowMapParams: ShadowMapParams,\r\n scope: PBInsideFunctionScope,\r\n shadowVertex: PBShaderExp,\r\n NdotL: PBShaderExp,\r\n split: PBShaderExp\r\n ): PBShaderExp;\r\n abstract getShadowMapColorFormat(shadowMapParams: ShadowMapParams): Nullable<TextureFormat>;\r\n abstract getShadowMapDepthFormat(shadowMapParams: ShadowMapParams): TextureFormat;\r\n abstract useNativeShadowMap(shadowMapParams: ShadowMapParams): boolean;\r\n}\r\n"],"names":["ShadowImpl","_resourceDirty","invalidateResource","updateResources","shadowMapParams","doUpdateResources","getShadowMapClearColor","colorAttachment","shadowMapFramebuffer","getColorAttachments","isFloatFormat","Vector4"],"mappings":";;AAIA,iBACO,MAAeA,UAAAA,CAAAA;IACVC,cAAwB;IAClC,WAAc,EAAA;QACZ,IAAI,CAACA,cAAc,GAAG,IAAA;AACxB;IACAC,kBAAqB,GAAA;QACnB,IAAI,CAACD,cAAc,GAAG,IAAA;AACxB;AACAE,IAAAA,eAAAA,CAAgBC,eAAgC,EAAE;QAChD,IAAI,CAACC,iBAAiB,CAACD,eAAAA,CAAAA;AACzB;AAGAE,IAAAA,sBAAAA,CAAuBF,eAAgC,EAAE;AACvD,QAAA,MAAMG,kBAAkBH,eAAgBI,CAAAA,oBAAoB,EAAEC,mBAAAA,EAAqB,CAAC,CAAE,CAAA;AACtF,QAAA,OAAOF,eACHA,GAAAA,eAAAA,CAAgBG,aAAa,EAAA,GAC3B,IAAIC,OAAQ,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,EAAG,KACrB,IAAIA,OAAAA,CAAQ,CAAG,EAAA,CAAA,EAAG,GAAG,CACvB,CAAA,GAAA,IAAA;AACN;AA6BF;;;;"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Maintains the world-space region used by directional light shadow maps.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/ class ShadowRegion extends Disposable {
|
|
8
|
+
/** @internal */ _manualRegion;
|
|
9
|
+
/** @internal */ _staticRegion;
|
|
10
|
+
/** @internal */ _dynamicRegion;
|
|
11
|
+
/** @internal */ _region;
|
|
12
|
+
/** @internal */ _staticCasters;
|
|
13
|
+
/** @internal */ _dynamicCasters;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a shadow region.
|
|
16
|
+
*
|
|
17
|
+
* @param region - Optional manual world-space AABB used to initialize the region.
|
|
18
|
+
*/ constructor(region){
|
|
19
|
+
super();
|
|
20
|
+
this._manualRegion = region ? new AABB(region) : null;
|
|
21
|
+
this._staticRegion = new AABB().beginExtend();
|
|
22
|
+
this._dynamicRegion = new AABB().beginExtend();
|
|
23
|
+
this._region = new AABB().beginExtend();
|
|
24
|
+
this._staticCasters = [];
|
|
25
|
+
this._dynamicCasters = [];
|
|
26
|
+
this.updateRegion();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Final world-space shadow region.
|
|
30
|
+
*
|
|
31
|
+
* @returns The union of the manual, static caster, and dynamic caster regions, or `null` if no valid region exists.
|
|
32
|
+
*/ get region() {
|
|
33
|
+
return this._region.isValid() ? this._region : null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Region contributed by manually assigned AABB.
|
|
37
|
+
*
|
|
38
|
+
* @returns The manually assigned region, or `null` if no manual region is set.
|
|
39
|
+
*/ get manualRegion() {
|
|
40
|
+
return this._manualRegion;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Region contributed by static shadow casters.
|
|
44
|
+
*
|
|
45
|
+
* @returns The combined static caster region, or `null` if no valid static caster region exists.
|
|
46
|
+
*/ get staticRegion() {
|
|
47
|
+
return this._staticRegion.isValid() ? this._staticRegion : null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Region contributed by dynamic shadow casters.
|
|
51
|
+
*
|
|
52
|
+
* @returns The combined dynamic caster region, or `null` if no valid dynamic caster region exists.
|
|
53
|
+
*/ get dynamicRegion() {
|
|
54
|
+
return this._dynamicRegion.isValid() ? this._dynamicRegion : null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Assigns a manual world-space AABB to the region.
|
|
58
|
+
*
|
|
59
|
+
* @param region - The manual world-space AABB to use, or `null` to clear the manual region.
|
|
60
|
+
*/ setRegion(region) {
|
|
61
|
+
this._manualRegion = region ? new AABB(region) : null;
|
|
62
|
+
this.updateRegion();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Adds a static shadow caster using a snapshot of its current world-space AABB.
|
|
66
|
+
*
|
|
67
|
+
* @param caster - The mesh or clipmap terrain node to include as a static caster.
|
|
68
|
+
* @returns `this` for chaining.
|
|
69
|
+
*/ addStaticCaster(caster) {
|
|
70
|
+
if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
const aabb = this.getCasterAABB(caster);
|
|
74
|
+
if (!aabb) {
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
this._staticCasters.push({
|
|
78
|
+
ref: new DWeakRef(caster),
|
|
79
|
+
aabb
|
|
80
|
+
});
|
|
81
|
+
this.extendRegion(this._staticRegion, aabb);
|
|
82
|
+
this.updateRegion();
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Adds a dynamic shadow caster and tracks its bounding volume changes.
|
|
87
|
+
*
|
|
88
|
+
* @param caster - The mesh or clipmap terrain node to include as a dynamic caster.
|
|
89
|
+
* @returns `this` for chaining.
|
|
90
|
+
*/ addDynamicCaster(caster) {
|
|
91
|
+
if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
const callback = ()=>{
|
|
95
|
+
this.rebuildDynamicRegion();
|
|
96
|
+
};
|
|
97
|
+
caster.on('bvchanged', callback);
|
|
98
|
+
this._dynamicCasters.push({
|
|
99
|
+
ref: new DWeakRef(caster),
|
|
100
|
+
callback
|
|
101
|
+
});
|
|
102
|
+
const aabb = this.getCasterAABB(caster);
|
|
103
|
+
if (aabb) {
|
|
104
|
+
this.extendRegion(this._dynamicRegion, aabb);
|
|
105
|
+
this.updateRegion();
|
|
106
|
+
}
|
|
107
|
+
return this;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Removes a previously added shadow caster.
|
|
111
|
+
*
|
|
112
|
+
* @param caster - The caster node to remove from the static or dynamic caster list.
|
|
113
|
+
* @returns `this` for chaining.
|
|
114
|
+
*/ removeCaster(caster) {
|
|
115
|
+
let changed = false;
|
|
116
|
+
for(let i = this._staticCasters.length - 1; i >= 0; i--){
|
|
117
|
+
const entry = this._staticCasters[i];
|
|
118
|
+
const node = entry.ref.get();
|
|
119
|
+
if (!node || node === caster) {
|
|
120
|
+
entry.ref.dispose();
|
|
121
|
+
this._staticCasters.splice(i, 1);
|
|
122
|
+
changed = true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
for(let i = this._dynamicCasters.length - 1; i >= 0; i--){
|
|
126
|
+
const entry = this._dynamicCasters[i];
|
|
127
|
+
const node = entry.ref.get();
|
|
128
|
+
if (!node || node === caster) {
|
|
129
|
+
(node ?? caster).off('bvchanged', entry.callback);
|
|
130
|
+
entry.ref.dispose();
|
|
131
|
+
this._dynamicCasters.splice(i, 1);
|
|
132
|
+
changed = true;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (changed) {
|
|
136
|
+
this.rebuildStaticRegion();
|
|
137
|
+
this.rebuildDynamicRegion();
|
|
138
|
+
}
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Removes all shadow casters while keeping the manual region.
|
|
143
|
+
*/ clearCasters() {
|
|
144
|
+
for (const entry of this._dynamicCasters){
|
|
145
|
+
entry.ref.get()?.off('bvchanged', entry.callback);
|
|
146
|
+
entry.ref.dispose();
|
|
147
|
+
}
|
|
148
|
+
for (const entry of this._staticCasters){
|
|
149
|
+
entry.ref.dispose();
|
|
150
|
+
}
|
|
151
|
+
this._staticCasters.length = 0;
|
|
152
|
+
this._dynamicCasters.length = 0;
|
|
153
|
+
this._staticRegion.beginExtend();
|
|
154
|
+
this._dynamicRegion.beginExtend();
|
|
155
|
+
this.updateRegion();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Clears the manual region and all shadow casters.
|
|
159
|
+
*
|
|
160
|
+
* @returns `this` for chaining.
|
|
161
|
+
*/ clear() {
|
|
162
|
+
this._manualRegion = null;
|
|
163
|
+
this.clearCasters();
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
/** {@inheritDoc Disposable.onDispose} */ onDispose() {
|
|
167
|
+
this.clear();
|
|
168
|
+
}
|
|
169
|
+
/** @internal */ hasCaster(caster) {
|
|
170
|
+
return this._staticCasters.some((entry)=>entry.ref.get() === caster) || this._dynamicCasters.some((entry)=>entry.ref.get() === caster);
|
|
171
|
+
}
|
|
172
|
+
/** @internal */ isShadowCaster(caster) {
|
|
173
|
+
return !caster.disposed && (caster.isMesh() || caster.isClipmapTerrain());
|
|
174
|
+
}
|
|
175
|
+
/** @internal */ getCasterAABB(caster) {
|
|
176
|
+
const bbox = caster.getWorldBoundingVolume()?.toAABB();
|
|
177
|
+
return bbox?.isValid() ? new AABB(bbox) : null;
|
|
178
|
+
}
|
|
179
|
+
/** @internal */ rebuildStaticRegion() {
|
|
180
|
+
this._staticRegion.beginExtend();
|
|
181
|
+
for(let i = this._staticCasters.length - 1; i >= 0; i--){
|
|
182
|
+
const entry = this._staticCasters[i];
|
|
183
|
+
if (!entry.ref.get()) {
|
|
184
|
+
entry.ref.dispose();
|
|
185
|
+
this._staticCasters.splice(i, 1);
|
|
186
|
+
} else {
|
|
187
|
+
this.extendRegion(this._staticRegion, entry.aabb);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
this.updateRegion();
|
|
191
|
+
}
|
|
192
|
+
/** @internal */ rebuildDynamicRegion() {
|
|
193
|
+
this._dynamicRegion.beginExtend();
|
|
194
|
+
for(let i = this._dynamicCasters.length - 1; i >= 0; i--){
|
|
195
|
+
const entry = this._dynamicCasters[i];
|
|
196
|
+
const caster = entry.ref.get();
|
|
197
|
+
if (!caster || !this.isShadowCaster(caster)) {
|
|
198
|
+
caster?.off('bvchanged', entry.callback);
|
|
199
|
+
entry.ref.dispose();
|
|
200
|
+
this._dynamicCasters.splice(i, 1);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const aabb = this.getCasterAABB(caster);
|
|
204
|
+
if (aabb) {
|
|
205
|
+
this.extendRegion(this._dynamicRegion, aabb);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
this.updateRegion();
|
|
209
|
+
}
|
|
210
|
+
/** @internal */ updateRegion() {
|
|
211
|
+
this._region.beginExtend();
|
|
212
|
+
if (this._manualRegion?.isValid()) {
|
|
213
|
+
this.extendRegion(this._region, this._manualRegion);
|
|
214
|
+
}
|
|
215
|
+
if (this._staticRegion.isValid()) {
|
|
216
|
+
this.extendRegion(this._region, this._staticRegion);
|
|
217
|
+
}
|
|
218
|
+
if (this._dynamicRegion.isValid()) {
|
|
219
|
+
this.extendRegion(this._region, this._dynamicRegion);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/** @internal */ extendRegion(region, aabb) {
|
|
223
|
+
region.extend(aabb.minPoint);
|
|
224
|
+
region.extend(aabb.maxPoint);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export { ShadowRegion };
|
|
229
|
+
//# sourceMappingURL=shadow_region.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadow_region.js","sources":["../../src/shadow/shadow_region.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { AABB, Disposable, DWeakRef } from '@zephyr3d/base';\r\nimport type { SceneNode } from '../scene/scene_node';\r\n\r\ntype StaticShadowCasterEntry = {\r\n ref: DWeakRef<SceneNode>;\r\n aabb: AABB;\r\n};\r\n\r\ntype DynamicShadowCasterEntry = {\r\n ref: DWeakRef<SceneNode>;\r\n callback: (node: SceneNode) => void;\r\n};\r\n\r\n/**\r\n * Maintains the world-space region used by directional light shadow maps.\r\n *\r\n * @public\r\n */\r\nexport class ShadowRegion extends Disposable {\r\n /** @internal */\r\n private _manualRegion: Nullable<AABB>;\r\n /** @internal */\r\n private readonly _staticRegion: AABB;\r\n /** @internal */\r\n private readonly _dynamicRegion: AABB;\r\n /** @internal */\r\n private readonly _region: AABB;\r\n /** @internal */\r\n private readonly _staticCasters: StaticShadowCasterEntry[];\r\n /** @internal */\r\n private readonly _dynamicCasters: DynamicShadowCasterEntry[];\r\n\r\n /**\n * Creates a shadow region.\n *\n * @param region - Optional manual world-space AABB used to initialize the region.\n */\n constructor(region?: Nullable<AABB>) {\n super();\r\n this._manualRegion = region ? new AABB(region) : null;\r\n this._staticRegion = new AABB().beginExtend();\r\n this._dynamicRegion = new AABB().beginExtend();\r\n this._region = new AABB().beginExtend();\r\n this._staticCasters = [];\r\n this._dynamicCasters = [];\r\n this.updateRegion();\r\n }\r\n\r\n /**\n * Final world-space shadow region.\n *\n * @returns The union of the manual, static caster, and dynamic caster regions, or `null` if no valid region exists.\n */\n get region(): Nullable<AABB> {\n return this._region.isValid() ? this._region : null;\r\n }\r\n\r\n /**\n * Region contributed by manually assigned AABB.\n *\n * @returns The manually assigned region, or `null` if no manual region is set.\n */\n get manualRegion(): Nullable<AABB> {\n return this._manualRegion;\r\n }\r\n\r\n /**\n * Region contributed by static shadow casters.\n *\n * @returns The combined static caster region, or `null` if no valid static caster region exists.\n */\n get staticRegion(): Nullable<AABB> {\n return this._staticRegion.isValid() ? this._staticRegion : null;\r\n }\r\n\r\n /**\n * Region contributed by dynamic shadow casters.\n *\n * @returns The combined dynamic caster region, or `null` if no valid dynamic caster region exists.\n */\n get dynamicRegion(): Nullable<AABB> {\n return this._dynamicRegion.isValid() ? this._dynamicRegion : null;\r\n }\r\n\r\n /**\n * Assigns a manual world-space AABB to the region.\n *\n * @param region - The manual world-space AABB to use, or `null` to clear the manual region.\n */\n setRegion(region: Nullable<AABB>) {\n this._manualRegion = region ? new AABB(region) : null;\r\n this.updateRegion();\r\n }\r\n\r\n /**\n * Adds a static shadow caster using a snapshot of its current world-space AABB.\n *\n * @param caster - The mesh or clipmap terrain node to include as a static caster.\n * @returns `this` for chaining.\n */\n addStaticCaster(caster: SceneNode): this {\n if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {\r\n return this;\r\n }\r\n const aabb = this.getCasterAABB(caster);\r\n if (!aabb) {\r\n return this;\r\n }\r\n this._staticCasters.push({\r\n ref: new DWeakRef(caster),\r\n aabb\r\n });\r\n this.extendRegion(this._staticRegion, aabb);\r\n this.updateRegion();\r\n return this;\r\n }\r\n\r\n /**\n * Adds a dynamic shadow caster and tracks its bounding volume changes.\n *\n * @param caster - The mesh or clipmap terrain node to include as a dynamic caster.\n * @returns `this` for chaining.\n */\n addDynamicCaster(caster: SceneNode): this {\n if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {\r\n return this;\r\n }\r\n const callback = () => {\r\n this.rebuildDynamicRegion();\r\n };\r\n caster.on('bvchanged', callback);\r\n this._dynamicCasters.push({\r\n ref: new DWeakRef(caster),\r\n callback\r\n });\r\n const aabb = this.getCasterAABB(caster);\r\n if (aabb) {\r\n this.extendRegion(this._dynamicRegion, aabb);\r\n this.updateRegion();\r\n }\r\n return this;\r\n }\r\n\r\n /**\n * Removes a previously added shadow caster.\n *\n * @param caster - The caster node to remove from the static or dynamic caster list.\n * @returns `this` for chaining.\n */\n removeCaster(caster: SceneNode): this {\n let removed = false;\r\n let changed = false;\r\n for (let i = this._staticCasters.length - 1; i >= 0; i--) {\r\n const entry = this._staticCasters[i];\r\n const node = entry.ref.get();\r\n if (!node || node === caster) {\r\n entry.ref.dispose();\r\n this._staticCasters.splice(i, 1);\r\n changed = true;\r\n removed ||= node === caster;\r\n }\r\n }\r\n for (let i = this._dynamicCasters.length - 1; i >= 0; i--) {\r\n const entry = this._dynamicCasters[i];\r\n const node = entry.ref.get();\r\n if (!node || node === caster) {\r\n (node ?? caster).off('bvchanged', entry.callback);\r\n entry.ref.dispose();\r\n this._dynamicCasters.splice(i, 1);\r\n changed = true;\r\n removed ||= node === caster;\r\n }\r\n }\r\n if (changed) {\r\n this.rebuildStaticRegion();\r\n this.rebuildDynamicRegion();\r\n }\r\n return this;\r\n }\r\n\r\n /**\n * Removes all shadow casters while keeping the manual region.\n */\n clearCasters() {\n for (const entry of this._dynamicCasters) {\r\n entry.ref.get()?.off('bvchanged', entry.callback);\r\n entry.ref.dispose();\r\n }\r\n for (const entry of this._staticCasters) {\r\n entry.ref.dispose();\r\n }\r\n this._staticCasters.length = 0;\r\n this._dynamicCasters.length = 0;\r\n this._staticRegion.beginExtend();\r\n this._dynamicRegion.beginExtend();\r\n this.updateRegion();\r\n }\r\n\r\n /**\n * Clears the manual region and all shadow casters.\n *\n * @returns `this` for chaining.\n */\n clear(): this {\n this._manualRegion = null;\r\n this.clearCasters();\r\n return this;\r\n }\r\n\r\n /** {@inheritDoc Disposable.onDispose} */\r\n protected onDispose(): void {\r\n this.clear();\r\n }\r\n\r\n /** @internal */\r\n private hasCaster(caster: SceneNode): boolean {\r\n return (\r\n this._staticCasters.some((entry) => entry.ref.get() === caster) ||\r\n this._dynamicCasters.some((entry) => entry.ref.get() === caster)\r\n );\r\n }\r\n\r\n /** @internal */\r\n private isShadowCaster(caster: SceneNode): boolean {\r\n return !caster.disposed && (caster.isMesh() || caster.isClipmapTerrain());\r\n }\r\n\r\n /** @internal */\r\n private getCasterAABB(caster: SceneNode): Nullable<AABB> {\r\n const bbox = caster.getWorldBoundingVolume()?.toAABB();\r\n return bbox?.isValid() ? new AABB(bbox) : null;\r\n }\r\n\r\n /** @internal */\r\n private rebuildStaticRegion() {\r\n this._staticRegion.beginExtend();\r\n for (let i = this._staticCasters.length - 1; i >= 0; i--) {\r\n const entry = this._staticCasters[i];\r\n if (!entry.ref.get()) {\r\n entry.ref.dispose();\r\n this._staticCasters.splice(i, 1);\r\n } else {\r\n this.extendRegion(this._staticRegion, entry.aabb);\r\n }\r\n }\r\n this.updateRegion();\r\n }\r\n\r\n /** @internal */\r\n private rebuildDynamicRegion() {\r\n this._dynamicRegion.beginExtend();\r\n for (let i = this._dynamicCasters.length - 1; i >= 0; i--) {\r\n const entry = this._dynamicCasters[i];\r\n const caster = entry.ref.get();\r\n if (!caster || !this.isShadowCaster(caster)) {\r\n caster?.off('bvchanged', entry.callback);\r\n entry.ref.dispose();\r\n this._dynamicCasters.splice(i, 1);\r\n continue;\r\n }\r\n const aabb = this.getCasterAABB(caster);\r\n if (aabb) {\r\n this.extendRegion(this._dynamicRegion, aabb);\r\n }\r\n }\r\n this.updateRegion();\r\n }\r\n\r\n /** @internal */\r\n private updateRegion() {\r\n this._region.beginExtend();\r\n if (this._manualRegion?.isValid()) {\r\n this.extendRegion(this._region, this._manualRegion);\r\n }\r\n if (this._staticRegion.isValid()) {\r\n this.extendRegion(this._region, this._staticRegion);\r\n }\r\n if (this._dynamicRegion.isValid()) {\r\n this.extendRegion(this._region, this._dynamicRegion);\r\n }\r\n }\r\n\r\n /** @internal */\r\n private extendRegion(region: AABB, aabb: AABB) {\r\n region.extend(aabb.minPoint);\r\n region.extend(aabb.maxPoint);\r\n }\r\n}\r\n"],"names":["ShadowRegion","Disposable","region","_manualRegion","AABB","_staticRegion","beginExtend","_dynamicRegion","_region","_staticCasters","_dynamicCasters","updateRegion","isValid","manualRegion","staticRegion","dynamicRegion","setRegion","addStaticCaster","caster","isShadowCaster","hasCaster","aabb","getCasterAABB","push","ref","DWeakRef","extendRegion","addDynamicCaster","callback","rebuildDynamicRegion","on","removeCaster","changed","i","length","entry","node","get","dispose","splice","off","rebuildStaticRegion","clearCasters","clear","some","disposed","isMesh","isClipmapTerrain","bbox","getWorldBoundingVolume","toAABB","extend","minPoint","maxPoint"],"mappings":"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"}
|