@zephyr3d/scene 0.9.24 → 0.9.26
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/hair/gpu_hair_simulation.js +1090 -0
- package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
- package/dist/animation/joint_dynamics/controller.js +7 -5
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -4
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/skeleton.js +58 -24
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/spring/multi_chain_spring_system.js +577 -179
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +4 -3
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
- package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
- package/dist/animation/spring/spring_particle.js +2 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_system.js +11 -3
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +10 -0
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/engine.js +53 -43
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptingsystem.js +119 -6
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +3 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +284 -67
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/zhair/zhair_format.js +288 -0
- package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
- package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
- package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
- package/dist/asset/model.js +178 -67
- package/dist/asset/model.js.map +1 -1
- package/dist/camera/camera.js +193 -21
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +3 -1
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +4040 -1290
- package/dist/index.js +16 -6
- package/dist/index.js.map +1 -1
- package/dist/material/eye.js +932 -0
- package/dist/material/eye.js.map +1 -0
- package/dist/material/hair.js +917 -0
- package/dist/material/hair.js.map +1 -0
- package/dist/material/hairstrand.js +842 -0
- package/dist/material/hairstrand.js.map +1 -0
- package/dist/material/hairstrand_data.js +162 -0
- package/dist/material/hairstrand_data.js.map +1 -0
- package/dist/material/lambert.js +5 -2
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +338 -300
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +120 -19
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +1 -1
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +5 -4
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +73 -18
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +4 -4
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +48 -11
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mtoon.js +6 -5
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +146 -28
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrblueprint_instance.js +501 -0
- package/dist/material/pbrblueprint_instance.js.map +1 -0
- package/dist/material/pbrmr.js +15 -16
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/shader/helper.js +766 -456
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +55 -0
- package/dist/material/shader/terrain_blend.js.map +1 -0
- package/dist/material/skin.js +192 -32
- package/dist/material/skin.js.map +1 -1
- package/dist/material/spriteblueprint.js +16 -1
- package/dist/material/spriteblueprint.js.map +1 -1
- package/dist/material/subsurfaceprofile.js +86 -23
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/water.js +3 -1
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +167 -7
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/coloradjust.js +2 -1
- package/dist/posteffect/coloradjust.js.map +1 -1
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/fxaa.js +2 -1
- package/dist/posteffect/fxaa.js.map +1 -1
- package/dist/posteffect/grayscale.js +3 -1
- package/dist/posteffect/grayscale.js.map +1 -1
- package/dist/posteffect/motionblur.js +4 -1
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/skinsss.js +368 -69
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +16 -9
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -0
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +91 -34
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +44 -1
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +45 -39
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js +4 -4
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +19 -0
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/depthpass.js +36 -2
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +26 -1
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +52 -51
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +1 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +3 -0
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +3 -0
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +3 -0
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/oit.js +29 -0
- package/dist/render/oit.js.map +1 -0
- package/dist/render/render_queue.js +3 -0
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +2 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +61 -1
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +73 -8
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +166 -126
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +36 -35
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +8 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +3 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +4 -1
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/hair.js +963 -0
- package/dist/scene/hair.js.map +1 -0
- package/dist/scene/light.js +5 -1
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +481 -47
- 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 +3 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +3 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +6 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +3 -0
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +6 -1
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +273 -249
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +3 -0
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +6 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/texture_cache.js +309 -0
- package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
- package/dist/scene/water.js +6 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/diffusion.js +54 -0
- package/dist/shaders/diffusion.js.map +1 -0
- package/dist/shaders/shadow.js +33 -21
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/temporal.js +71 -33
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shadow/dom.js +546 -0
- package/dist/shadow/dom.js.map +1 -0
- package/dist/shadow/pcf_opt.js +3 -5
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +1 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/receiver_bias.js +41 -0
- package/dist/shadow/receiver_bias.js.map +1 -0
- package/dist/shadow/shader.js +20 -60
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js +89 -0
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +50 -50
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +150 -37
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shapes/shape.js +11 -2
- package/dist/shapes/shape.js.map +1 -1
- package/dist/shapes/sphere.js +50 -9
- package/dist/shapes/sphere.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +112 -2
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/material/func.js +142 -49
- package/dist/utility/blueprint/material/func.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +490 -25
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +898 -4
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/serialization/manager.js +431 -100
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +370 -3
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -0
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +133 -1
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +26 -5
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/hair.js +1141 -0
- package/dist/utility/serialization/scene/hair.js.map +1 -0
- package/dist/utility/serialization/scene/light.js +84 -4
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1867 -166
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +231 -14
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +141 -7
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +4 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +18 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +4 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +92 -69
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +4 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +4 -0
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +96 -95
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/values.js +105 -58
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
|
@@ -5,8 +5,8 @@ import { ESM } from './esm.js';
|
|
|
5
5
|
import { VSM } from './vsm.js';
|
|
6
6
|
import { PCFOPT } from './pcf_opt.js';
|
|
7
7
|
import { PCSS } from './pcss.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { DOM } from './dom.js';
|
|
9
|
+
import { LIGHT_TYPE_NONE, LIGHT_TYPE_POINT, LIGHT_TYPE_DIRECTIONAL } from '../values.js';
|
|
10
10
|
import { getDevice } from '../app/api.js';
|
|
11
11
|
import { ShadowRegion } from './shadow_region.js';
|
|
12
12
|
|
|
@@ -38,6 +38,9 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
38
38
|
/** @internal */ _pcssFilterSampleCount;
|
|
39
39
|
/** @internal */ _pcssMaxFilterRadius;
|
|
40
40
|
/** @internal */ _pcssTemporalJitter;
|
|
41
|
+
/** @internal */ _domLayerDistance;
|
|
42
|
+
/** @internal */ _domDensity;
|
|
43
|
+
/** @internal */ _domFilterSize;
|
|
41
44
|
/** @internal */ _vsmBlurKernelSize;
|
|
42
45
|
/** @internal */ _vsmBlurRadius;
|
|
43
46
|
/** @internal */ _vsmDarkness;
|
|
@@ -59,7 +62,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
59
62
|
numCascades: 1,
|
|
60
63
|
splitLambda: 0.5,
|
|
61
64
|
depthBias: 0.003,
|
|
62
|
-
normalBias:
|
|
65
|
+
normalBias: 1.5,
|
|
63
66
|
nearClip: 1
|
|
64
67
|
};
|
|
65
68
|
this._resourceDirty = true;
|
|
@@ -74,6 +77,9 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
74
77
|
this._pcssFilterSampleCount = 32;
|
|
75
78
|
this._pcssMaxFilterRadius = 32;
|
|
76
79
|
this._pcssTemporalJitter = true;
|
|
80
|
+
this._domLayerDistance = 0.25;
|
|
81
|
+
this._domDensity = 1;
|
|
82
|
+
this._domFilterSize = 5;
|
|
77
83
|
this._vsmBlurKernelSize = 5;
|
|
78
84
|
this._vsmBlurRadius = 4;
|
|
79
85
|
this._vsmDarkness = 0.3;
|
|
@@ -174,7 +180,20 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
174
180
|
set depthBias(val) {
|
|
175
181
|
this._config.depthBias = val;
|
|
176
182
|
}
|
|
177
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* Normal offset bias, in shadow map texels.
|
|
185
|
+
*
|
|
186
|
+
* @remarks
|
|
187
|
+
* Before sampling, the receiver is moved along its normal by this many texel
|
|
188
|
+
* widths, scaled by `sin(theta)` between the normal and the light so the
|
|
189
|
+
* offset is zero facing the light and largest at grazing incidence. This is
|
|
190
|
+
* what removes grazing-angle self-shadowing acne; {@link depthBias} alone
|
|
191
|
+
* cannot, because the depth error over one texel grows without bound as the
|
|
192
|
+
* surface turns away from the light.
|
|
193
|
+
*
|
|
194
|
+
* Useful values are roughly 1 to 4. Too little leaves acne on curved surfaces
|
|
195
|
+
* near the terminator; too much detaches contact shadows from thin geometry.
|
|
196
|
+
*/ get normalBias() {
|
|
178
197
|
return this._config.normalBias;
|
|
179
198
|
}
|
|
180
199
|
set normalBias(val) {
|
|
@@ -215,7 +234,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
215
234
|
this.shadowDistance = 120;
|
|
216
235
|
this.splitLambda = 0.75;
|
|
217
236
|
this.depthBias = 0.005;
|
|
218
|
-
this.normalBias =
|
|
237
|
+
this.normalBias = 2;
|
|
219
238
|
this.nearClip = 0.2;
|
|
220
239
|
this.pcfKernelSize = 5;
|
|
221
240
|
this.numShadowCascades = this._light.isDirectionLight() ? 3 : 1;
|
|
@@ -226,7 +245,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
226
245
|
this.shadowDistance = 800;
|
|
227
246
|
this.splitLambda = 0.6;
|
|
228
247
|
this.depthBias = 0.0035;
|
|
229
|
-
this.normalBias =
|
|
248
|
+
this.normalBias = 1.5;
|
|
230
249
|
this.nearClip = 1;
|
|
231
250
|
this.pcfKernelSize = 3;
|
|
232
251
|
this.numShadowCascades = this._light.isDirectionLight() ? 4 : 1;
|
|
@@ -283,6 +302,69 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
283
302
|
}
|
|
284
303
|
}
|
|
285
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Depth spanned by the deep opacity map's layers, in world units along the
|
|
307
|
+
* light direction. Only meaningful when the shadow mode is `dom`.
|
|
308
|
+
*
|
|
309
|
+
* @remarks
|
|
310
|
+
* Set it to roughly the thickness of the hair. Too small and everything past
|
|
311
|
+
* the outer strands saturates the last layer, which is a hard shadow again;
|
|
312
|
+
* too large and all three layers fall inside the first strand, leaving the
|
|
313
|
+
* interior unshadowed.
|
|
314
|
+
*/ get domLayerDistance() {
|
|
315
|
+
return this._domLayerDistance;
|
|
316
|
+
}
|
|
317
|
+
set domLayerDistance(val) {
|
|
318
|
+
val = Math.max(0.0001, Number(val) || 0);
|
|
319
|
+
if (val !== this._domLayerDistance) {
|
|
320
|
+
this._domLayerDistance = val;
|
|
321
|
+
const dom = this.asDOM();
|
|
322
|
+
if (dom) {
|
|
323
|
+
dom.layerDistance = this._domLayerDistance;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* How strongly accumulated hair coverage attenuates light. Only meaningful when
|
|
329
|
+
* the shadow mode is `dom`.
|
|
330
|
+
*
|
|
331
|
+
* @remarks
|
|
332
|
+
* Raise it to darken the interior of a groom without moving the layers.
|
|
333
|
+
*/ get domDensity() {
|
|
334
|
+
return this._domDensity;
|
|
335
|
+
}
|
|
336
|
+
set domDensity(val) {
|
|
337
|
+
val = Math.max(0, Number(val) || 0);
|
|
338
|
+
if (val !== this._domDensity) {
|
|
339
|
+
this._domDensity = val;
|
|
340
|
+
const dom = this.asDOM();
|
|
341
|
+
if (dom) {
|
|
342
|
+
dom.density = this._domDensity;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Width of the deep opacity map's sampling kernel in texels: 1, 3, 5 or 7. Only
|
|
348
|
+
* meaningful when the shadow mode is `dom`.
|
|
349
|
+
*
|
|
350
|
+
* @remarks
|
|
351
|
+
* The technique's own gradation runs along the light rather than across the
|
|
352
|
+
* map, so without a kernel the silhouette of a groom is as hard an edge as an
|
|
353
|
+
* unfiltered shadow map gives. This is what softens it, at one layer lookup per
|
|
354
|
+
* tap. Defaults to 5.
|
|
355
|
+
*/ get domFilterSize() {
|
|
356
|
+
return this._domFilterSize;
|
|
357
|
+
}
|
|
358
|
+
set domFilterSize(val) {
|
|
359
|
+
val = val !== 1 && val !== 3 && val !== 5 && val !== 7 ? 5 : val;
|
|
360
|
+
if (val !== this._domFilterSize) {
|
|
361
|
+
this._domFilterSize = val;
|
|
362
|
+
const dom = this.asDOM();
|
|
363
|
+
if (dom) {
|
|
364
|
+
dom.filterSize = this._domFilterSize;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
286
368
|
/** Blocker search sample count for PCSS shadow */ get pcssBlockerSampleCount() {
|
|
287
369
|
return this._pcssBlockerSampleCount;
|
|
288
370
|
}
|
|
@@ -456,25 +538,6 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
456
538
|
ctx.shadowMapInfo = null;
|
|
457
539
|
}
|
|
458
540
|
}
|
|
459
|
-
/** @internal */ static computeShadowBias(shadowMapParams, scope, z, NdotL, linear) {
|
|
460
|
-
const pb = scope.$builder;
|
|
461
|
-
const depthBiasParam = ShaderHelper.getDepthBiasValues(scope);
|
|
462
|
-
if (shadowMapParams.lightType === LIGHT_TYPE_DIRECTIONAL) {
|
|
463
|
-
return pb.dot(pb.mul(depthBiasParam.xy, pb.vec2(1, pb.sub(1, NdotL))), pb.vec2(1, 1));
|
|
464
|
-
} else {
|
|
465
|
-
const nearFar = ShaderHelper.getShadowCameraParams(scope).xy;
|
|
466
|
-
const linearDepth = linear ? z : ShaderHelper.nonLinearDepthToLinearNormalized(scope, z, nearFar);
|
|
467
|
-
const biasScaleFactor = pb.mix(1, depthBiasParam.w, linearDepth);
|
|
468
|
-
return pb.dot(pb.mul(depthBiasParam.xy, pb.vec2(1, pb.sub(1, NdotL)), biasScaleFactor), pb.vec2(1, 1));
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
/** @internal */ static computeShadowBiasCSM(shadowMapParams, scope, NdotL, split) {
|
|
472
|
-
const pb = scope.$builder;
|
|
473
|
-
const depthBiasParam = ShaderHelper.getDepthBiasValues(scope);
|
|
474
|
-
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)));
|
|
475
|
-
const depthBiasScale = pb.dot(ShaderHelper.getDepthBiasScales(scope), splitFlags);
|
|
476
|
-
return pb.dot(pb.mul(depthBiasParam.xy, pb.vec2(1, pb.sub(1, NdotL)), depthBiasScale), pb.vec2(1, 1));
|
|
477
|
-
}
|
|
478
541
|
/** @internal */ isTextureInvalid(texture, target, format, width, height) {
|
|
479
542
|
return texture && (texture.target !== target || texture.format !== format || texture.width !== width || texture.height !== height || texture.depth !== this.numShadowCascades);
|
|
480
543
|
}
|
|
@@ -766,8 +829,15 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
766
829
|
/** @internal */ calcDepthBiasParams(camera, shadowMapSize, depthBias, normalBias, depthScale, result) {
|
|
767
830
|
const sizeNear = Math.min(camera.getProjectionMatrix().getNearPlaneWidth(), camera.getProjectionMatrix().getNearPlaneHeight());
|
|
768
831
|
const sizeFar = Math.min(camera.getProjectionMatrix().getFarPlaneWidth(), camera.getProjectionMatrix().getFarPlaneHeight());
|
|
769
|
-
|
|
770
|
-
|
|
832
|
+
// World-space size of one shadow map texel at the near plane. Both bias
|
|
833
|
+
// terms are expressed in multiples of it, so a tighter cascade automatically
|
|
834
|
+
// gets a proportionally smaller offset.
|
|
835
|
+
const texelWorldSize = sizeNear / shadowMapSize;
|
|
836
|
+
result.setXYZW(depthBias * texelWorldSize * 2, // Normal offset distance in world units. Unlike a depth bias this moves
|
|
837
|
+
// the receiver sideways out of the texel that produces grazing-angle
|
|
838
|
+
// acne, which no amount of depth bias can fix (the required depth offset
|
|
839
|
+
// diverges as NdotL approaches zero).
|
|
840
|
+
normalBias * texelWorldSize, depthScale, sizeFar / sizeNear);
|
|
771
841
|
}
|
|
772
842
|
/** @internal */ postRenderShadowMap(shadowMapParams) {
|
|
773
843
|
this._impl.postRenderShadowMap(shadowMapParams);
|
|
@@ -779,7 +849,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
779
849
|
const shadowMapParams = ShadowMapper.fetchShadowMapParams();
|
|
780
850
|
shadowMapParams.impl = this._impl;
|
|
781
851
|
shadowMapParams.lightType = this.light.lightType;
|
|
782
|
-
shadowMapParams.numShadowCascades = shadowMapParams.lightType === LIGHT_TYPE_DIRECTIONAL ? this._config.numCascades ?? 1 : 1;
|
|
852
|
+
shadowMapParams.numShadowCascades = shadowMapParams.lightType === LIGHT_TYPE_DIRECTIONAL && this._impl.supportsCascades() ? this._config.numCascades ?? 1 : 1;
|
|
783
853
|
ctx.shadowMapInfo.set(this.light, shadowMapParams);
|
|
784
854
|
const scene = ctx.scene;
|
|
785
855
|
const camera = ctx.camera;
|
|
@@ -791,6 +861,32 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
791
861
|
shadowMapParams.depthClampEnabled = false;
|
|
792
862
|
renderPass.clearColor = this._impl.getShadowMapClearColor(shadowMapParams);
|
|
793
863
|
const depthScale = this._impl.getDepthScale();
|
|
864
|
+
const geometryPassCount = Math.max(1, this._impl.getGeometryPassCount(shadowMapParams) >> 0);
|
|
865
|
+
// Repeats the caster draw for implementations that need more than one look at
|
|
866
|
+
// the geometry (deep opacity maps). Single-pass implementations - every one
|
|
867
|
+
// but DOM - take the `pass === 0` path once and behave exactly as before.
|
|
868
|
+
const renderGeometry = (renderCamera, cullCamera)=>{
|
|
869
|
+
if (geometryPassCount === 1) {
|
|
870
|
+
renderPass.render(ctx, renderCamera, cullCamera);
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
// Culling depends only on the camera, so the extra passes reuse the first
|
|
874
|
+
// pass's queue rather than walking the scene graph again per pass.
|
|
875
|
+
const renderQueue = renderPass.cullScene(ctx, cullCamera ?? renderCamera);
|
|
876
|
+
try {
|
|
877
|
+
for(let pass = 0; pass < geometryPassCount; pass++){
|
|
878
|
+
this._impl.beginGeometryPass(shadowMapParams, pass);
|
|
879
|
+
// The emitted caster shader differs between passes, and the shadow pass
|
|
880
|
+
// keys its programs on this hash, so it has to be refreshed per pass
|
|
881
|
+
// rather than computed once up front.
|
|
882
|
+
shadowMapParams.shaderHash = this.getShaderHash(shadowMapParams);
|
|
883
|
+
renderPass.clearColor = this._impl.getShadowMapClearColor(shadowMapParams);
|
|
884
|
+
renderPass.render(ctx, renderCamera, cullCamera, renderQueue);
|
|
885
|
+
}
|
|
886
|
+
} finally{
|
|
887
|
+
renderQueue.dispose();
|
|
888
|
+
}
|
|
889
|
+
};
|
|
794
890
|
const directionalShadowRegion = this._shadowRegion.region;
|
|
795
891
|
const shadowRegion = this._light.isDirectionLight() && directionalShadowRegion?.isValid() ? directionalShadowRegion : scene.boundingBox;
|
|
796
892
|
if (this._light.isPointLight()) {
|
|
@@ -811,20 +907,24 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
811
907
|
shadowMapRenderCamera.lookAtCubeFace(face);
|
|
812
908
|
fb.setColorAttachmentCubeFace(0, face);
|
|
813
909
|
fb.setDepthAttachmentCubeFace(face);
|
|
814
|
-
|
|
910
|
+
renderGeometry(shadowMapRenderCamera);
|
|
815
911
|
}
|
|
816
912
|
shadowMapParams.shadowMatrices.set(Matrix4x4.identity());
|
|
817
913
|
ShadowMapper.releaseCamera(shadowMapRenderCamera);
|
|
818
914
|
} else {
|
|
819
|
-
|
|
820
|
-
|
|
915
|
+
// Reads the resolved count, not the configured one: an implementation that
|
|
916
|
+
// cannot store cascades has already collapsed it to a single split, and the
|
|
917
|
+
// cascade path would index array layers its shadow map does not have.
|
|
918
|
+
const numCascades = shadowMapParams.numShadowCascades;
|
|
919
|
+
if (numCascades > 1) {
|
|
920
|
+
const distances = this.calcSplitDistances(camera.getNearPlane(), Math.min(this._shadowDistance, camera.getFarPlane()), numCascades);
|
|
821
921
|
const cascadeCamera = ShadowMapper.fetchCameraForScene(scene);
|
|
822
922
|
const shadowMapRenderCamera = ShadowMapper.fetchCameraForScene(scene);
|
|
823
923
|
const shadowMapCullCamera = ShadowMapper.fetchCameraForScene(scene);
|
|
824
924
|
shadowMapCullCamera.clipMask = AABB.ClipLeft | AABB.ClipRight | AABB.ClipBottom | AABB.ClipTop;
|
|
825
925
|
cascadeCamera.parent = camera;
|
|
826
926
|
shadowMapParams.depthClampEnabled = getDevice().getDeviceCaps().shaderCaps.supportFragmentDepth;
|
|
827
|
-
for(let split = 0; split <
|
|
927
|
+
for(let split = 0; split < numCascades; split++){
|
|
828
928
|
cascadeCamera.setPerspective(camera.getFOV(), camera.getAspect(), distances[split], distances[split + 1]);
|
|
829
929
|
const snapMatrix = ShadowMapper._snapMatrix;
|
|
830
930
|
const border = shadowMapParams.impl.getShadowMapBorder(shadowMapParams); //20 / this._config.shadowMapSize;
|
|
@@ -839,8 +939,8 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
839
939
|
fb.setColorAttachmentLayer(0, split);
|
|
840
940
|
fb.setDepthAttachmentLayer(split);
|
|
841
941
|
} else {
|
|
842
|
-
const numRows =
|
|
843
|
-
const numCols =
|
|
942
|
+
const numRows = numCascades > 2 ? 2 : 1;
|
|
943
|
+
const numCols = numCascades > 1 ? 2 : 1;
|
|
844
944
|
const adjMatrix = new Matrix4x4();
|
|
845
945
|
const col = split % 2;
|
|
846
946
|
const row = split >> 1;
|
|
@@ -867,7 +967,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
867
967
|
}
|
|
868
968
|
device.setFramebuffer(fb);
|
|
869
969
|
device.setScissor(scissor);
|
|
870
|
-
|
|
970
|
+
renderGeometry(shadowMapRenderCamera, shadowMapCullCamera);
|
|
871
971
|
shadowMapParams.shadowMatrices.set(Matrix4x4.transpose(shadowMapRenderCamera.viewProjectionMatrix), split * 16);
|
|
872
972
|
shadowMapParams.cascadeDistances[split] = distances[split + 1];
|
|
873
973
|
}
|
|
@@ -890,7 +990,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
890
990
|
shadowMapParams.cameraParams.setXYZW(shadowMapRenderCamera.getNearPlane(), shadowMapRenderCamera.getFarPlane(), this._config.shadowMapSize, this._shadowDistance);
|
|
891
991
|
device.setFramebuffer(fb);
|
|
892
992
|
shadowMapRenderCamera.setProjectionMatrix(Matrix4x4.multiply(snapMatrix, shadowMapRenderCamera.getProjectionMatrix()));
|
|
893
|
-
|
|
993
|
+
renderGeometry(shadowMapRenderCamera);
|
|
894
994
|
shadowMapParams.shadowMatrices.set(Matrix4x4.transpose(shadowMapRenderCamera.viewProjectionMatrix));
|
|
895
995
|
ShadowMapper.releaseCamera(shadowMapRenderCamera);
|
|
896
996
|
}
|
|
@@ -898,10 +998,18 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
898
998
|
this.postRenderShadowMap(shadowMapParams);
|
|
899
999
|
}
|
|
900
1000
|
/** @internal */ applyMode(mode) {
|
|
901
|
-
if (mode !== 'hard' && mode !== 'vsm' && mode !== 'esm' && mode !== 'pcf' && mode !== 'pcf-pd' && mode !== 'pcf-opt' && mode !== 'pcss') {
|
|
1001
|
+
if (mode !== 'hard' && mode !== 'vsm' && mode !== 'esm' && mode !== 'pcf' && mode !== 'pcf-pd' && mode !== 'pcf-opt' && mode !== 'pcss' && mode !== 'dom') {
|
|
902
1002
|
console.error(`ShadowMapper.setShadowMode() failed: invalid mode: ${mode}`);
|
|
903
1003
|
return;
|
|
904
1004
|
}
|
|
1005
|
+
if (mode === 'dom' && getDevice().type !== 'webgpu') {
|
|
1006
|
+
// The strand geometry this mode exists to shadow is WebGPU only, so the
|
|
1007
|
+
// WebGL paths were never built. Falling back keeps a scene authored with it
|
|
1008
|
+
// renderable rather than failing to produce a shadow map at all.
|
|
1009
|
+
console.warn(`ShadowMapper.setShadowMode(): 'dom' requires WebGPU, falling back to 'pcf'`);
|
|
1010
|
+
this.applyMode('pcf');
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
905
1013
|
this._impl = null;
|
|
906
1014
|
if (mode === 'hard') {
|
|
907
1015
|
this._impl = new SSM();
|
|
@@ -914,6 +1022,8 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
914
1022
|
esm.logSpace = this._esmLogSpace;
|
|
915
1023
|
} else if (mode === 'pcf' || mode === 'pcf-opt' || mode === 'pcf-pd') {
|
|
916
1024
|
this._impl = new PCFOPT(this._pcfKernelSize);
|
|
1025
|
+
} else if (mode === 'dom') {
|
|
1026
|
+
this._impl = new DOM(this._domLayerDistance, this._domDensity, this._domFilterSize);
|
|
917
1027
|
} else if (mode === 'pcss') {
|
|
918
1028
|
this._impl = new PCSS(this._pcssLightRadius, this._pcssBlockerSampleCount, this._pcssFilterSampleCount, this._pcssMaxFilterRadius, this._pcssTemporalJitter);
|
|
919
1029
|
}
|
|
@@ -921,6 +1031,9 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
|
|
|
921
1031
|
/** @internal */ asVSM() {
|
|
922
1032
|
return this._impl?.getType() === 'vsm' ? this._impl : null;
|
|
923
1033
|
}
|
|
1034
|
+
/** @internal */ asDOM() {
|
|
1035
|
+
return this._impl?.getType() === 'dom' ? this._impl : null;
|
|
1036
|
+
}
|
|
924
1037
|
/** @internal */ asESM() {
|
|
925
1038
|
return this._impl?.getType() === 'esm' ? this._impl : null;
|
|
926
1039
|
}
|