@zephyr3d/scene 0.9.25 → 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 +4019 -1278
- package/dist/index.js +15 -5
- 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 +330 -20
- 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/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 +3 -0
- 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 +4 -0
- 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 +49 -2
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
|
@@ -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\nimport { LIGHT_TYPE_DIRECTIONAL
|
|
1
|
+
{"version":3,"file":"shader.js","sources":["../../src/shadow/shader.ts"],"sourcesContent":["import type { PBInsideFunctionScope, PBShaderExp } from '@zephyr3d/device';\r\nimport { ShaderHelper } from '../material/shader/helper';\r\nimport { LIGHT_TYPE_DIRECTIONAL } from '../values';\r\nimport { getShadowReceiverBiasFactor, isMaskedPerspectiveShadowLight } from './receiver_bias';\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\n/**\r\n * Constant depth bias for a cascaded directional shadow.\r\n *\r\n * @remarks\r\n * The slope-scaled term that used to occupy `depthBiasValues.y` is gone: `.y`\r\n * now carries the normal offset distance, and normal offsetting (see\r\n * `ShaderHelper.applyShadowNormalOffset`) is what handles receiver slope. A\r\n * depth bias cannot, because the depth spanned by one texel diverges as the\r\n * surface turns away from the light.\r\n */\r\nexport function computeShadowBiasCSM(scope: PBInsideFunctionScope, _NdotL: PBShaderExp, split: PBShaderExp) {\r\n const pb = scope.$builder;\r\n return pb.mul(\r\n ShaderHelper.getDepthBiasValues(scope).x,\r\n getShadowReceiverBiasFactor(scope),\r\n ShaderHelper.getShadowCascadeBiasScale(scope, split)\r\n );\r\n}\r\n\r\n/**\r\n * Constant depth bias for a single-cascade shadow. See {@link computeShadowBiasCSM}\r\n * for why there is no slope-scaled term.\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 receiverBiasFactor = getShadowReceiverBiasFactor(scope);\r\n if (lightType === LIGHT_TYPE_DIRECTIONAL) {\r\n return pb.mul(depthBiasParam.x, receiverBiasFactor);\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.mul(depthBiasParam.x, receiverBiasFactor, biasScaleFactor) as PBShaderExp;\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":["getShadowReceiverPerspectiveBiasScale","scope","lightType","linearDepth","farNearRatio","pb","$builder","alphaCutoff","zAlphaCutoff","isMaskedPerspectiveShadowLight","cutoff","clamp","cappedFarNearRatio","min","mix","computeShadowBiasCSM","_NdotL","split","mul","ShaderHelper","getDepthBiasValues","x","getShadowReceiverBiasFactor","getShadowCascadeBiasScale","computeShadowBias","z","linear","depthBiasParam","receiverBiasFactor","LIGHT_TYPE_DIRECTIONAL","nearFar","getShadowCameraParams","xy","nonLinearDepthToLinearNormalized","biasScaleFactor","w","bias"],"mappings":";;;;AAKA,SAASA,sCACPC,KAA4B,EAC5BC,SAAiB,EACjBC,WAAwB,EACxBC,YAAyB,EAAA;IAEzB,MAAMC,EAAAA,GAAKJ,MAAMK,QAAQ;IACzB,MAAMC,WAAAA,GAAc,KAACN,CAAiEO,YAAY;IAClG,IAAID,WAAAA,IAAeE,8BAA+BR,CAAAA,KAAAA,EAAOC,SAAY,CAAA,EAAA;AACnE,QAAA,MAAMQ,MAASL,GAAAA,EAAAA,CAAGM,KAAK,CAACJ,aAAa,CAAG,EAAA,CAAA,CAAA;;;QAGxC,MAAMK,kBAAAA,GAAqBP,GAAGQ,GAAG,CAACT,cAAcC,EAAGS,CAAAA,GAAG,CAAC,IAAA,EAAM,GAAKJ,EAAAA,MAAAA,CAAAA,CAAAA;AAClE,QAAA,OAAOL,EAAGS,CAAAA,GAAG,CAAC,CAAA,EAAGF,kBAAoBT,EAAAA,WAAAA,CAAAA;AACvC;AACA,IAAA,OAAOE,EAAGS,CAAAA,GAAG,CAAC,CAAA,EAAGV,YAAcD,EAAAA,WAAAA,CAAAA;AACjC;AAEA;;;;;;;;;AASC,IACM,SAASY,oBAAAA,CAAqBd,KAA4B,EAAEe,MAAmB,EAAEC,KAAkB,EAAA;IACxG,MAAMZ,EAAAA,GAAKJ,MAAMK,QAAQ;AACzB,IAAA,OAAOD,EAAGa,CAAAA,GAAG,CACXC,YAAAA,CAAaC,kBAAkB,CAACnB,KAAAA,CAAAA,CAAOoB,CAAC,EACxCC,2BAA4BrB,CAAAA,KAAAA,CAAAA,EAC5BkB,YAAaI,CAAAA,yBAAyB,CAACtB,KAAOgB,EAAAA,KAAAA,CAAAA,CAAAA;AAElD;AAEA;;;IAIO,SAASO,iBAAAA,CACdtB,SAAiB,EACjBD,KAA4B,EAC5BwB,CAAc,EACdT,MAAmB,EACnBU,MAAe,EAAA;IAEf,MAAMrB,EAAAA,GAAKJ,MAAMK,QAAQ;IACzB,MAAMqB,cAAAA,GAAiBR,YAAaC,CAAAA,kBAAkB,CAACnB,KAAAA,CAAAA;AACvD,IAAA,MAAM2B,qBAAqBN,2BAA4BrB,CAAAA,KAAAA,CAAAA;AACvD,IAAA,IAAIC,cAAc2B,sBAAwB,EAAA;AACxC,QAAA,OAAOxB,EAAGa,CAAAA,GAAG,CAACS,cAAAA,CAAeN,CAAC,EAAEO,kBAAAA,CAAAA;KAC3B,MAAA;AACL,QAAA,MAAME,OAAUX,GAAAA,YAAAA,CAAaY,qBAAqB,CAAC9B,OAAO+B,EAAE;AAC5D,QAAA,MAAM7B,cAAcuB,MAASD,GAAAA,CAAAA,GAAIN,aAAac,gCAAgC,CAAChC,OAAOwB,CAAGK,EAAAA,OAAAA,CAAAA;AACzF,QAAA,MAAMI,kBAAkBlC,qCACtBC,CAAAA,KAAAA,EACAC,SACAC,EAAAA,WAAAA,EACAwB,eAAeQ,CAAC,CAAA;AAElB,QAAA,IAAIC,OAAO/B,EAAGa,CAAAA,GAAG,CAACS,cAAeN,CAAAA,CAAC,EAAEO,kBAAoBM,EAAAA,eAAAA,CAAAA;QACxD,IAAIzB,8BAAAA,CAA+BR,OAAOC,SAAY,CAAA,EAAA;YACpD,MAAMK,WAAAA,GAAc,KAACN,CAAiEO,YAAY;AAClG4B,YAAAA,IAAAA,GAAO/B,EAAGa,CAAAA,GAAG,CAACkB,IAAAA,EAAM/B,EAAGS,CAAAA,GAAG,CAAC,IAAA,EAAM,IAAMT,EAAAA,EAAAA,CAAGM,KAAK,CAACJ,aAAa,CAAG,EAAA,CAAA,CAAA,CAAA,CAAA;AAClE;QACA,OAAO6B,IAAAA;AACT;AACF;;;;"}
|
|
@@ -41,6 +41,95 @@ import { getDevice } from '../app/api.js';
|
|
|
41
41
|
const device = getDevice();
|
|
42
42
|
return device.type !== 'webgl' || REVERSE_Z && device.getDeviceCaps().framebufferCaps.supportDepth32float ? 'd32f' : 'd24s8';
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Number of geometry passes this implementation needs over the shadow casters.
|
|
46
|
+
*
|
|
47
|
+
* Almost every technique rasterises the casters once and post-processes the
|
|
48
|
+
* result, which is what {@link postRenderShadowMap} is for - it runs after the
|
|
49
|
+
* geometry is on the map and receives no scene state, so a blur or resolve
|
|
50
|
+
* fits there but a second draw of the casters does not.
|
|
51
|
+
*
|
|
52
|
+
* Deep opacity maps do need that second draw: the first pass establishes the
|
|
53
|
+
* frontmost depth per texel and the second accumulates transmittance in layers
|
|
54
|
+
* measured from it, so the casters must be rasterised again with the first
|
|
55
|
+
* pass's output already available. Returning a count above one makes
|
|
56
|
+
* `ShadowMapper.render` repeat the draw, calling {@link beginGeometryPass}
|
|
57
|
+
* before each one.
|
|
58
|
+
*
|
|
59
|
+
* @returns The number of passes; one unless overridden.
|
|
60
|
+
*/ getGeometryPassCount(_shadowMapParams) {
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Whether this implementation can split a directional light into cascades.
|
|
65
|
+
*
|
|
66
|
+
* Cascades need one shadow map per split, which every depth-based technique
|
|
67
|
+
* gets by rendering into array layers. A technique whose storage is already
|
|
68
|
+
* spoken for - a deep opacity map packs layer depth and coverage into the one
|
|
69
|
+
* texture the receiver is allowed to bind - has nowhere to put them, and asks
|
|
70
|
+
* to be driven with a single split instead.
|
|
71
|
+
*
|
|
72
|
+
* @returns True unless overridden.
|
|
73
|
+
*/ supportsCascades() {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Prepares state for the given geometry pass.
|
|
78
|
+
*
|
|
79
|
+
* Only called when {@link getGeometryPassCount} returns more than one. The
|
|
80
|
+
* index is zero-based. Implementations that vary the emitted shader between
|
|
81
|
+
* passes must fold the index into {@link getShaderHash} as well, since the
|
|
82
|
+
* shadow pass keys its programs on that hash.
|
|
83
|
+
*
|
|
84
|
+
* @param shadowMapParams - Current shadow map state.
|
|
85
|
+
* @param pass - Zero-based index of the geometry pass about to run.
|
|
86
|
+
*/ beginGeometryPass(_shadowMapParams, _pass) {}
|
|
87
|
+
/**
|
|
88
|
+
* Last say on the render states a shadow caster is drawn with.
|
|
89
|
+
*
|
|
90
|
+
* Runs after the material has set up its own states, in the same spirit as the
|
|
91
|
+
* OIT hook on the transparent pass. Techniques that rasterise the casters once
|
|
92
|
+
* want the defaults - depth test and write on, no blending - and leave this
|
|
93
|
+
* alone. An accumulating pass wants the opposite and overrides it here rather
|
|
94
|
+
* than teaching the material about shadow implementations.
|
|
95
|
+
*
|
|
96
|
+
* @param shadowMapParams - Current shadow map state.
|
|
97
|
+
* @param stateSet - The state set about to be applied, already populated.
|
|
98
|
+
*/ setCasterRenderStates(_shadowMapParams, _stateSet) {}
|
|
99
|
+
/**
|
|
100
|
+
* Declares any extra resources the caster shader needs, in bind group 0.
|
|
101
|
+
*
|
|
102
|
+
* The shadow map pass otherwise gives a caster only the camera and the light,
|
|
103
|
+
* which is all a technique needs when it just records depth. One that reads
|
|
104
|
+
* back its own earlier output - a deep opacity map measuring layers from the
|
|
105
|
+
* frontmost strand - declares that input here instead of the pass hard-coding
|
|
106
|
+
* knowledge of the implementation.
|
|
107
|
+
*
|
|
108
|
+
* @param scope - Global shader scope of the caster program.
|
|
109
|
+
* @param shadowMapParams - Current shadow map state.
|
|
110
|
+
*/ declareCasterUniforms(_scope, _shadowMapParams) {}
|
|
111
|
+
/**
|
|
112
|
+
* Binds whatever {@link declareCasterUniforms} declared.
|
|
113
|
+
*
|
|
114
|
+
* @param bindGroup - Bind group 0 of the caster program.
|
|
115
|
+
* @param shadowMapParams - Current shadow map state.
|
|
116
|
+
*/ applyCasterUniforms(_bindGroup, _shadowMapParams) {}
|
|
117
|
+
/**
|
|
118
|
+
* Whether casters should still be alpha-clipped before their shadow output.
|
|
119
|
+
*
|
|
120
|
+
* A depth-recording technique wants the clip: a fragment that fails it is not
|
|
121
|
+
* there, and letting it write depth would block light with geometry the eye
|
|
122
|
+
* never sees. A technique that records coverage instead wants the raw alpha,
|
|
123
|
+
* because the clip destroys exactly the quantity it is accumulating - a
|
|
124
|
+
* dithered caster survives with probability alpha and then contributes alpha,
|
|
125
|
+
* which accumulates alpha squared, and a cutoff drops the thin strands that
|
|
126
|
+
* carry most of a groom's transmittance.
|
|
127
|
+
*
|
|
128
|
+
* @param shadowMapParams - Current shadow map state.
|
|
129
|
+
* @returns True unless overridden.
|
|
130
|
+
*/ clipsCasterAlpha(_shadowMapParams) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
44
133
|
}
|
|
45
134
|
|
|
46
135
|
export { ShadowImpl, getPackedShadowMapClearColor, getShadowMapFarthestDepth };
|
|
@@ -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 { REVERSE_Z, Vector4, type Nullable } from '@zephyr3d/base';\r\nimport { isDeviceDepthShadow } from '../shaders/shadow';\r\nimport { getDevice } from '../app/api';\r\n\r\n/** @internal */\r\nexport function getShadowMapFarthestDepth(lightType: number) {\r\n return REVERSE_Z && isDeviceDepthShadow(lightType) ? 0 : 1;\r\n}\r\n\r\n/** @internal */\r\nexport function getPackedShadowMapClearColor(lightType: number) {\r\n // The RGBA8 decoder assigns the alpha channel a weight of 1, so the\r\n // normalized depth endpoints are represented by transparent/opaque black.\r\n return new Vector4(0, 0, 0, getShadowMapFarthestDepth(lightType));\r\n}\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 // Empty texels must read as \"farthest\": under reverse-Z that is 0 for\r\n // device-encoded directional/rect maps, 1 for linear point/spot maps.\r\n const farthest = getShadowMapFarthestDepth(shadowMapParams.lightType);\r\n return colorAttachment\r\n ? colorAttachment.isFloatFormat()\r\n ? new Vector4(farthest, farthest, farthest, 1)\r\n : getPackedShadowMapClearColor(shadowMapParams.lightType)\r\n : null;\r\n }\r\n /**\r\n * Depth format for shadow maps rendered into a native depth attachment.\r\n *\r\n * Float depth everywhere except WebGL, where d24s8 is kept under\r\n * standard-Z (WebGL1 compatibility, no precision benefit anyway). Under\r\n * reverse-Z the WebGL2 float depth format is used so shadow maps share\r\n * the near-uniform precision distribution (full benefit with\r\n * EXT_clip_control active).\r\n * @internal\r\n */\r\n protected preferredShadowMapDepthFormat(): TextureFormat {\r\n const device = getDevice();\r\n return device.type !== 'webgl' ||\r\n (REVERSE_Z && device.getDeviceCaps().framebufferCaps.supportDepth32float)\r\n ? 'd32f'\r\n : 'd24s8';\r\n }\r\n abstract getParams(out?: Vector4): Vector4;\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":["getShadowMapFarthestDepth","lightType","REVERSE_Z","isDeviceDepthShadow","getPackedShadowMapClearColor","Vector4","ShadowImpl","_resourceDirty","invalidateResource","updateResources","shadowMapParams","doUpdateResources","getShadowMapClearColor","colorAttachment","shadowMapFramebuffer","getColorAttachments","farthest","isFloatFormat","device","getDevice","type","getDeviceCaps","framebufferCaps","supportDepth32float"],"mappings":";;;;AAMA,iBACO,SAASA,yBAAAA,CAA0BC,SAAiB,EAAA;IACzD,OAAOC,SAAAA,IAAaC,mBAAoBF,CAAAA,SAAAA,CAAAA,GAAa,CAAI,GAAA,CAAA;AAC3D;AAEA,iBACO,SAASG,4BAAAA,CAA6BH,SAAiB,EAAA;;;AAG5D,IAAA,OAAO,IAAII,OAAAA,CAAQ,CAAG,EAAA,CAAA,EAAG,GAAGL,yBAA0BC,CAAAA,SAAAA,CAAAA,CAAAA;AACxD;AAEA,iBACO,MAAeK,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;;;QAGtF,MAAMC,QAAAA,GAAWhB,yBAA0BU,CAAAA,eAAAA,CAAgBT,SAAS,CAAA;AACpE,QAAA,OAAOY,eACHA,GAAAA,eAAAA,CAAgBI,aAAa,EAAA,GAC3B,IAAIZ,OAAAA,CAAQW,QAAUA,EAAAA,QAAAA,EAAUA,QAAU,EAAA,CAAA,CAAA,GAC1CZ,4BAA6BM,CAAAA,eAAAA,CAAgBT,SAAS,CACxD,GAAA,IAAA;AACN;AACA;;;;;;;;;AASC,MACD,6BAAyD,GAAA;AACvD,QAAA,MAAMiB,MAASC,GAAAA,SAAAA,EAAAA;AACf,QAAA,OAAOD,MAAOE,CAAAA,IAAI,KAAK,OAAA,IACpBlB,SAAagB,IAAAA,MAAAA,CAAOG,aAAa,EAAA,CAAGC,eAAe,CAACC,mBAAmB,GACtE,MACA,GAAA,OAAA;AACN;AA8BF;;;;"}
|
|
1
|
+
{"version":3,"file":"shadow_impl.js","sources":["../../src/shadow/shadow_impl.ts"],"sourcesContent":["import type {\r\n BindGroup,\r\n PBGlobalScope,\r\n PBInsideFunctionScope,\r\n PBShaderExp,\r\n RenderStateSet,\r\n TextureFormat\r\n} from '@zephyr3d/device';\r\nimport type { ShadowMapParams, ShadowMapType, ShadowMode } from './shadowmapper';\r\nimport { REVERSE_Z, Vector4, type Nullable } from '@zephyr3d/base';\r\nimport { isDeviceDepthShadow } from '../shaders/shadow';\r\nimport { getDevice } from '../app/api';\r\n\r\n/** @internal */\r\nexport function getShadowMapFarthestDepth(lightType: number) {\r\n return REVERSE_Z && isDeviceDepthShadow(lightType) ? 0 : 1;\r\n}\r\n\r\n/** @internal */\r\nexport function getPackedShadowMapClearColor(lightType: number) {\r\n // The RGBA8 decoder assigns the alpha channel a weight of 1, so the\r\n // normalized depth endpoints are represented by transparent/opaque black.\r\n return new Vector4(0, 0, 0, getShadowMapFarthestDepth(lightType));\r\n}\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 // Empty texels must read as \"farthest\": under reverse-Z that is 0 for\r\n // device-encoded directional/rect maps, 1 for linear point/spot maps.\r\n const farthest = getShadowMapFarthestDepth(shadowMapParams.lightType);\r\n return colorAttachment\r\n ? colorAttachment.isFloatFormat()\r\n ? new Vector4(farthest, farthest, farthest, 1)\r\n : getPackedShadowMapClearColor(shadowMapParams.lightType)\r\n : null;\r\n }\r\n /**\r\n * Depth format for shadow maps rendered into a native depth attachment.\r\n *\r\n * Float depth everywhere except WebGL, where d24s8 is kept under\r\n * standard-Z (WebGL1 compatibility, no precision benefit anyway). Under\r\n * reverse-Z the WebGL2 float depth format is used so shadow maps share\r\n * the near-uniform precision distribution (full benefit with\r\n * EXT_clip_control active).\r\n * @internal\r\n */\r\n protected preferredShadowMapDepthFormat(): TextureFormat {\r\n const device = getDevice();\r\n return device.type !== 'webgl' ||\r\n (REVERSE_Z && device.getDeviceCaps().framebufferCaps.supportDepth32float)\r\n ? 'd32f'\r\n : 'd24s8';\r\n }\r\n abstract getParams(out?: Vector4): Vector4;\r\n /**\r\n * Number of geometry passes this implementation needs over the shadow casters.\r\n *\r\n * Almost every technique rasterises the casters once and post-processes the\r\n * result, which is what {@link postRenderShadowMap} is for - it runs after the\r\n * geometry is on the map and receives no scene state, so a blur or resolve\r\n * fits there but a second draw of the casters does not.\r\n *\r\n * Deep opacity maps do need that second draw: the first pass establishes the\r\n * frontmost depth per texel and the second accumulates transmittance in layers\r\n * measured from it, so the casters must be rasterised again with the first\r\n * pass's output already available. Returning a count above one makes\r\n * `ShadowMapper.render` repeat the draw, calling {@link beginGeometryPass}\r\n * before each one.\r\n *\r\n * @returns The number of passes; one unless overridden.\r\n */\r\n getGeometryPassCount(_shadowMapParams: ShadowMapParams): number {\r\n return 1;\r\n }\r\n /**\r\n * Whether this implementation can split a directional light into cascades.\r\n *\r\n * Cascades need one shadow map per split, which every depth-based technique\r\n * gets by rendering into array layers. A technique whose storage is already\r\n * spoken for - a deep opacity map packs layer depth and coverage into the one\r\n * texture the receiver is allowed to bind - has nowhere to put them, and asks\r\n * to be driven with a single split instead.\r\n *\r\n * @returns True unless overridden.\r\n */\r\n supportsCascades(): boolean {\r\n return true;\r\n }\r\n /**\r\n * Prepares state for the given geometry pass.\r\n *\r\n * Only called when {@link getGeometryPassCount} returns more than one. The\r\n * index is zero-based. Implementations that vary the emitted shader between\r\n * passes must fold the index into {@link getShaderHash} as well, since the\r\n * shadow pass keys its programs on that hash.\r\n *\r\n * @param shadowMapParams - Current shadow map state.\r\n * @param pass - Zero-based index of the geometry pass about to run.\r\n */\r\n beginGeometryPass(_shadowMapParams: ShadowMapParams, _pass: number): void {}\r\n /**\r\n * Last say on the render states a shadow caster is drawn with.\r\n *\r\n * Runs after the material has set up its own states, in the same spirit as the\r\n * OIT hook on the transparent pass. Techniques that rasterise the casters once\r\n * want the defaults - depth test and write on, no blending - and leave this\r\n * alone. An accumulating pass wants the opposite and overrides it here rather\r\n * than teaching the material about shadow implementations.\r\n *\r\n * @param shadowMapParams - Current shadow map state.\r\n * @param stateSet - The state set about to be applied, already populated.\r\n */\r\n setCasterRenderStates(_shadowMapParams: ShadowMapParams, _stateSet: RenderStateSet): void {}\r\n /**\r\n * Declares any extra resources the caster shader needs, in bind group 0.\r\n *\r\n * The shadow map pass otherwise gives a caster only the camera and the light,\r\n * which is all a technique needs when it just records depth. One that reads\r\n * back its own earlier output - a deep opacity map measuring layers from the\r\n * frontmost strand - declares that input here instead of the pass hard-coding\r\n * knowledge of the implementation.\r\n *\r\n * @param scope - Global shader scope of the caster program.\r\n * @param shadowMapParams - Current shadow map state.\r\n */\r\n declareCasterUniforms(_scope: PBGlobalScope, _shadowMapParams: ShadowMapParams): void {}\r\n /**\r\n * Binds whatever {@link declareCasterUniforms} declared.\r\n *\r\n * @param bindGroup - Bind group 0 of the caster program.\r\n * @param shadowMapParams - Current shadow map state.\r\n */\r\n applyCasterUniforms(_bindGroup: BindGroup, _shadowMapParams: ShadowMapParams): void {}\r\n /**\r\n * Whether casters should still be alpha-clipped before their shadow output.\r\n *\r\n * A depth-recording technique wants the clip: a fragment that fails it is not\r\n * there, and letting it write depth would block light with geometry the eye\r\n * never sees. A technique that records coverage instead wants the raw alpha,\r\n * because the clip destroys exactly the quantity it is accumulating - a\r\n * dithered caster survives with probability alpha and then contributes alpha,\r\n * which accumulates alpha squared, and a cutoff drops the thin strands that\r\n * carry most of a groom's transmittance.\r\n *\r\n * @param shadowMapParams - Current shadow map state.\r\n * @returns True unless overridden.\r\n */\r\n clipsCasterAlpha(_shadowMapParams: ShadowMapParams): boolean {\r\n return true;\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 /**\r\n * Fragment output for a shadow caster.\r\n *\r\n * @param shadowMapParams - Current shadow map state.\r\n * @param scope - Caster fragment scope.\r\n * @param worldPos - World position of the fragment.\r\n * @param alpha - The material's own alpha, or null when it computes no fragment\r\n * colour and the fragment is therefore fully opaque. Depth-recording techniques\r\n * ignore it - by the time this runs the fragment has already survived whatever\r\n * alpha test applies - but one that records absorption needs the value itself.\r\n * It must be passed rather than read out of `scope`, because the caller's\r\n * `outColor` is local to the material's own shader function and defaults to a\r\n * zero vector when no colour was computed, which is indistinguishable from a\r\n * genuinely transparent fragment.\r\n */\r\n abstract computeShadowMapDepth(\r\n shadowMapParams: ShadowMapParams,\r\n scope: PBInsideFunctionScope,\r\n worldPos: PBShaderExp,\r\n alpha: Nullable<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":["getShadowMapFarthestDepth","lightType","REVERSE_Z","isDeviceDepthShadow","getPackedShadowMapClearColor","Vector4","ShadowImpl","_resourceDirty","invalidateResource","updateResources","shadowMapParams","doUpdateResources","getShadowMapClearColor","colorAttachment","shadowMapFramebuffer","getColorAttachments","farthest","isFloatFormat","device","getDevice","type","getDeviceCaps","framebufferCaps","supportDepth32float","getGeometryPassCount","_shadowMapParams","supportsCascades","beginGeometryPass","_pass","setCasterRenderStates","_stateSet","declareCasterUniforms","_scope","applyCasterUniforms","_bindGroup","clipsCasterAlpha"],"mappings":";;;;AAaA,iBACO,SAASA,yBAAAA,CAA0BC,SAAiB,EAAA;IACzD,OAAOC,SAAAA,IAAaC,mBAAoBF,CAAAA,SAAAA,CAAAA,GAAa,CAAI,GAAA,CAAA;AAC3D;AAEA,iBACO,SAASG,4BAAAA,CAA6BH,SAAiB,EAAA;;;AAG5D,IAAA,OAAO,IAAII,OAAAA,CAAQ,CAAG,EAAA,CAAA,EAAG,GAAGL,yBAA0BC,CAAAA,SAAAA,CAAAA,CAAAA;AACxD;AAEA,iBACO,MAAeK,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;;;QAGtF,MAAMC,QAAAA,GAAWhB,yBAA0BU,CAAAA,eAAAA,CAAgBT,SAAS,CAAA;AACpE,QAAA,OAAOY,eACHA,GAAAA,eAAAA,CAAgBI,aAAa,EAAA,GAC3B,IAAIZ,OAAAA,CAAQW,QAAUA,EAAAA,QAAAA,EAAUA,QAAU,EAAA,CAAA,CAAA,GAC1CZ,4BAA6BM,CAAAA,eAAAA,CAAgBT,SAAS,CACxD,GAAA,IAAA;AACN;AACA;;;;;;;;;AASC,MACD,6BAAyD,GAAA;AACvD,QAAA,MAAMiB,MAASC,GAAAA,SAAAA,EAAAA;AACf,QAAA,OAAOD,MAAOE,CAAAA,IAAI,KAAK,OAAA,IACpBlB,SAAagB,IAAAA,MAAAA,CAAOG,aAAa,EAAA,CAAGC,eAAe,CAACC,mBAAmB,GACtE,MACA,GAAA,OAAA;AACN;AAEA;;;;;;;;;;;;;;;;MAiBAC,oBAAAA,CAAqBC,gBAAiC,EAAU;QAC9D,OAAO,CAAA;AACT;AACA;;;;;;;;;;AAUC,MACDC,gBAA4B,GAAA;QAC1B,OAAO,IAAA;AACT;AACA;;;;;;;;;;AAUC,MACDC,iBAAkBF,CAAAA,gBAAiC,EAAEG,KAAa,EAAQ;AAC1E;;;;;;;;;;;AAWC,MACDC,qBAAsBJ,CAAAA,gBAAiC,EAAEK,SAAyB,EAAQ;AAC1F;;;;;;;;;;;AAWC,MACDC,qBAAsBC,CAAAA,MAAqB,EAAEP,gBAAiC,EAAQ;AACtF;;;;;AAKC,MACDQ,mBAAoBC,CAAAA,UAAqB,EAAET,gBAAiC,EAAQ;AACpF;;;;;;;;;;;;;MAcAU,gBAAAA,CAAiBV,gBAAiC,EAAW;QAC3D,OAAO,IAAA;AACT;AA6CF;;;;"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Maintains the world-space region used by directional light shadow maps.
|
|
5
|
-
*
|
|
6
|
-
* @public
|
|
3
|
+
/**
|
|
4
|
+
* Maintains the world-space region used by directional light shadow maps.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
7
|
*/ class ShadowRegion extends Disposable {
|
|
8
8
|
/** @internal */ _manualRegion;
|
|
9
9
|
/** @internal */ _staticRegion;
|
|
@@ -11,10 +11,10 @@ import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
|
11
11
|
/** @internal */ _region;
|
|
12
12
|
/** @internal */ _staticCasters;
|
|
13
13
|
/** @internal */ _dynamicCasters;
|
|
14
|
-
/**
|
|
15
|
-
* Creates a shadow region.
|
|
16
|
-
*
|
|
17
|
-
* @param region - Optional manual world-space AABB used to initialize the region.
|
|
14
|
+
/**
|
|
15
|
+
* Creates a shadow region.
|
|
16
|
+
*
|
|
17
|
+
* @param region - Optional manual world-space AABB used to initialize the region.
|
|
18
18
|
*/ constructor(region){
|
|
19
19
|
super();
|
|
20
20
|
this._manualRegion = region ? new AABB(region) : null;
|
|
@@ -25,47 +25,47 @@ import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
|
25
25
|
this._dynamicCasters = [];
|
|
26
26
|
this.updateRegion();
|
|
27
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.
|
|
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
32
|
*/ get region() {
|
|
33
33
|
return this._region.isValid() ? this._region : null;
|
|
34
34
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Region contributed by manually assigned AABB.
|
|
37
|
-
*
|
|
38
|
-
* @returns The manually assigned region, or `null` if no manual region is set.
|
|
35
|
+
/**
|
|
36
|
+
* Region contributed by manually assigned AABB.
|
|
37
|
+
*
|
|
38
|
+
* @returns The manually assigned region, or `null` if no manual region is set.
|
|
39
39
|
*/ get manualRegion() {
|
|
40
40
|
return this._manualRegion;
|
|
41
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.
|
|
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
46
|
*/ get staticRegion() {
|
|
47
47
|
return this._staticRegion.isValid() ? this._staticRegion : null;
|
|
48
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.
|
|
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
53
|
*/ get dynamicRegion() {
|
|
54
54
|
return this._dynamicRegion.isValid() ? this._dynamicRegion : null;
|
|
55
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.
|
|
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
60
|
*/ setRegion(region) {
|
|
61
61
|
this._manualRegion = region ? new AABB(region) : null;
|
|
62
62
|
this.updateRegion();
|
|
63
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.
|
|
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
69
|
*/ addStaticCaster(caster) {
|
|
70
70
|
if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {
|
|
71
71
|
return this;
|
|
@@ -82,11 +82,11 @@ import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
|
82
82
|
this.updateRegion();
|
|
83
83
|
return this;
|
|
84
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.
|
|
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
90
|
*/ addDynamicCaster(caster) {
|
|
91
91
|
if (!this.isShadowCaster(caster) || this.hasCaster(caster)) {
|
|
92
92
|
return this;
|
|
@@ -106,11 +106,11 @@ import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
|
106
106
|
}
|
|
107
107
|
return this;
|
|
108
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.
|
|
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
114
|
*/ removeCaster(caster) {
|
|
115
115
|
let changed = false;
|
|
116
116
|
for(let i = this._staticCasters.length - 1; i >= 0; i--){
|
|
@@ -138,8 +138,8 @@ import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
|
138
138
|
}
|
|
139
139
|
return this;
|
|
140
140
|
}
|
|
141
|
-
/**
|
|
142
|
-
* Removes all shadow casters while keeping the manual region.
|
|
141
|
+
/**
|
|
142
|
+
* Removes all shadow casters while keeping the manual region.
|
|
143
143
|
*/ clearCasters() {
|
|
144
144
|
for (const entry of this._dynamicCasters){
|
|
145
145
|
entry.ref.get()?.off('bvchanged', entry.callback);
|
|
@@ -154,10 +154,10 @@ import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
|
154
154
|
this._dynamicRegion.beginExtend();
|
|
155
155
|
this.updateRegion();
|
|
156
156
|
}
|
|
157
|
-
/**
|
|
158
|
-
* Clears the manual region and all shadow casters.
|
|
159
|
-
*
|
|
160
|
-
* @returns `this` for chaining.
|
|
157
|
+
/**
|
|
158
|
+
* Clears the manual region and all shadow casters.
|
|
159
|
+
*
|
|
160
|
+
* @returns `this` for chaining.
|
|
161
161
|
*/ clear() {
|
|
162
162
|
this._manualRegion = null;
|
|
163
163
|
this.clearCasters();
|
|
@@ -170,7 +170,7 @@ import { Disposable, AABB, DWeakRef } from '@zephyr3d/base';
|
|
|
170
170
|
return this._staticCasters.some((entry)=>entry.ref.get() === caster) || this._dynamicCasters.some((entry)=>entry.ref.get() === caster);
|
|
171
171
|
}
|
|
172
172
|
/** @internal */ isShadowCaster(caster) {
|
|
173
|
-
return !caster.disposed && (caster.isMesh() || caster.isClipmapTerrain());
|
|
173
|
+
return !caster.disposed && (caster.isMesh() || caster.isClipmapTerrain() || caster.isHair());
|
|
174
174
|
}
|
|
175
175
|
/** @internal */ getCasterAABB(caster) {
|
|
176
176
|
const bbox = caster.getWorldBoundingVolume()?.toAABB();
|
|
@@ -1 +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 /**\r\n * Creates a shadow region.\r\n *\r\n * @param region - Optional manual world-space AABB used to initialize the region.\r\n */\r\n constructor(region?: Nullable<AABB>) {\r\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 /**\r\n * Final world-space shadow region.\r\n *\r\n * @returns The union of the manual, static caster, and dynamic caster regions, or `null` if no valid region exists.\r\n */\r\n get region(): Nullable<AABB> {\r\n return this._region.isValid() ? this._region : null;\r\n }\r\n\r\n /**\r\n * Region contributed by manually assigned AABB.\r\n *\r\n * @returns The manually assigned region, or `null` if no manual region is set.\r\n */\r\n get manualRegion(): Nullable<AABB> {\r\n return this._manualRegion;\r\n }\r\n\r\n /**\r\n * Region contributed by static shadow casters.\r\n *\r\n * @returns The combined static caster region, or `null` if no valid static caster region exists.\r\n */\r\n get staticRegion(): Nullable<AABB> {\r\n return this._staticRegion.isValid() ? this._staticRegion : null;\r\n }\r\n\r\n /**\r\n * Region contributed by dynamic shadow casters.\r\n *\r\n * @returns The combined dynamic caster region, or `null` if no valid dynamic caster region exists.\r\n */\r\n get dynamicRegion(): Nullable<AABB> {\r\n return this._dynamicRegion.isValid() ? this._dynamicRegion : null;\r\n }\r\n\r\n /**\r\n * Assigns a manual world-space AABB to the region.\r\n *\r\n * @param region - The manual world-space AABB to use, or `null` to clear the manual region.\r\n */\r\n setRegion(region: Nullable<AABB>) {\r\n this._manualRegion = region ? new AABB(region) : null;\r\n this.updateRegion();\r\n }\r\n\r\n /**\r\n * Adds a static shadow caster using a snapshot of its current world-space AABB.\r\n *\r\n * @param caster - The mesh or clipmap terrain node to include as a static caster.\r\n * @returns `this` for chaining.\r\n */\r\n addStaticCaster(caster: SceneNode): this {\r\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 /**\r\n * Adds a dynamic shadow caster and tracks its bounding volume changes.\r\n *\r\n * @param caster - The mesh or clipmap terrain node to include as a dynamic caster.\r\n * @returns `this` for chaining.\r\n */\r\n addDynamicCaster(caster: SceneNode): this {\r\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 /**\r\n * Removes a previously added shadow caster.\r\n *\r\n * @param caster - The caster node to remove from the static or dynamic caster list.\r\n * @returns `this` for chaining.\r\n */\r\n removeCaster(caster: SceneNode): this {\r\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 /**\r\n * Removes all shadow casters while keeping the manual region.\r\n */\r\n clearCasters() {\r\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 /**\r\n * Clears the manual region and all shadow casters.\r\n *\r\n * @returns `this` for chaining.\r\n */\r\n clear(): this {\r\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":";;AAcA;;;;IAKO,MAAMA,YAAqBC,SAAAA,UAAAA,CAAAA;qBAEhC,aAAsC;qBAEtC,aAAqC;qBAErC,cAAsC;qBAEtC,OAA+B;qBAE/B,cAA2D;qBAE3D,eAA6D;AAE7D;;;;MAKA,WAAA,CAAYC,MAAuB,CAAE;QACnC,KAAK,EAAA;AACL,QAAA,IAAI,CAACC,aAAa,GAAGD,MAAS,GAAA,IAAIE,KAAKF,MAAU,CAAA,GAAA,IAAA;AACjD,QAAA,IAAI,CAACG,aAAa,GAAG,IAAID,OAAOE,WAAW,EAAA;AAC3C,QAAA,IAAI,CAACC,cAAc,GAAG,IAAIH,OAAOE,WAAW,EAAA;AAC5C,QAAA,IAAI,CAACE,OAAO,GAAG,IAAIJ,OAAOE,WAAW,EAAA;QACrC,IAAI,CAACG,cAAc,GAAG,EAAE;QACxB,IAAI,CAACC,eAAe,GAAG,EAAE;AACzB,QAAA,IAAI,CAACC,YAAY,EAAA;AACnB;AAEA;;;;AAIC,MACD,IAAIT,MAAyB,GAAA;QAC3B,OAAO,IAAI,CAACM,OAAO,CAACI,OAAO,EAAK,GAAA,IAAI,CAACJ,OAAO,GAAG,IAAA;AACjD;AAEA;;;;AAIC,MACD,IAAIK,YAA+B,GAAA;QACjC,OAAO,IAAI,CAACV,aAAa;AAC3B;AAEA;;;;AAIC,MACD,IAAIW,YAA+B,GAAA;QACjC,OAAO,IAAI,CAACT,aAAa,CAACO,OAAO,EAAK,GAAA,IAAI,CAACP,aAAa,GAAG,IAAA;AAC7D;AAEA;;;;AAIC,MACD,IAAIU,aAAgC,GAAA;QAClC,OAAO,IAAI,CAACR,cAAc,CAACK,OAAO,EAAK,GAAA,IAAI,CAACL,cAAc,GAAG,IAAA;AAC/D;AAEA;;;;MAKAS,SAAAA,CAAUd,MAAsB,EAAE;AAChC,QAAA,IAAI,CAACC,aAAa,GAAGD,MAAS,GAAA,IAAIE,KAAKF,MAAU,CAAA,GAAA,IAAA;AACjD,QAAA,IAAI,CAACS,YAAY,EAAA;AACnB;AAEA;;;;;MAMAM,eAAAA,CAAgBC,MAAiB,EAAQ;QACvC,IAAI,CAAC,IAAI,CAACC,cAAc,CAACD,WAAW,IAAI,CAACE,SAAS,CAACF,MAAS,CAAA,EAAA;AAC1D,YAAA,OAAO,IAAI;AACb;AACA,QAAA,MAAMG,IAAO,GAAA,IAAI,CAACC,aAAa,CAACJ,MAAAA,CAAAA;AAChC,QAAA,IAAI,CAACG,IAAM,EAAA;AACT,YAAA,OAAO,IAAI;AACb;AACA,QAAA,IAAI,CAACZ,cAAc,CAACc,IAAI,CAAC;AACvBC,YAAAA,GAAAA,EAAK,IAAIC,QAASP,CAAAA,MAAAA,CAAAA;AAClBG,YAAAA;AACF,SAAA,CAAA;AACA,QAAA,IAAI,CAACK,YAAY,CAAC,IAAI,CAACrB,aAAa,EAAEgB,IAAAA,CAAAA;AACtC,QAAA,IAAI,CAACV,YAAY,EAAA;AACjB,QAAA,OAAO,IAAI;AACb;AAEA;;;;;MAMAgB,gBAAAA,CAAiBT,MAAiB,EAAQ;QACxC,IAAI,CAAC,IAAI,CAACC,cAAc,CAACD,WAAW,IAAI,CAACE,SAAS,CAACF,MAAS,CAAA,EAAA;AAC1D,YAAA,OAAO,IAAI;AACb;AACA,QAAA,MAAMU,QAAW,GAAA,IAAA;AACf,YAAA,IAAI,CAACC,oBAAoB,EAAA;AAC3B,SAAA;QACAX,MAAOY,CAAAA,EAAE,CAAC,WAAaF,EAAAA,QAAAA,CAAAA;AACvB,QAAA,IAAI,CAAClB,eAAe,CAACa,IAAI,CAAC;AACxBC,YAAAA,GAAAA,EAAK,IAAIC,QAASP,CAAAA,MAAAA,CAAAA;AAClBU,YAAAA;AACF,SAAA,CAAA;AACA,QAAA,MAAMP,IAAO,GAAA,IAAI,CAACC,aAAa,CAACJ,MAAAA,CAAAA;AAChC,QAAA,IAAIG,IAAM,EAAA;AACR,YAAA,IAAI,CAACK,YAAY,CAAC,IAAI,CAACnB,cAAc,EAAEc,IAAAA,CAAAA;AACvC,YAAA,IAAI,CAACV,YAAY,EAAA;AACnB;AACA,QAAA,OAAO,IAAI;AACb;AAEA;;;;;MAMAoB,YAAAA,CAAab,MAAiB,EAAQ;AAEpC,QAAA,IAAIc,OAAU,GAAA,KAAA;QACd,IAAK,IAAIC,CAAI,GAAA,IAAI,CAACxB,cAAc,CAACyB,MAAM,GAAG,CAAA,EAAGD,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;AACxD,YAAA,MAAME,KAAQ,GAAA,IAAI,CAAC1B,cAAc,CAACwB,CAAE,CAAA;AACpC,YAAA,MAAMG,IAAOD,GAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAA;YAC1B,IAAI,CAACD,IAAQA,IAAAA,IAAAA,KAASlB,MAAQ,EAAA;gBAC5BiB,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACjB,gBAAA,IAAI,CAAC7B,cAAc,CAAC8B,MAAM,CAACN,CAAG,EAAA,CAAA,CAAA;gBAC9BD,OAAU,GAAA,IAAA;AAEZ;AACF;QACA,IAAK,IAAIC,CAAI,GAAA,IAAI,CAACvB,eAAe,CAACwB,MAAM,GAAG,CAAA,EAAGD,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;AACzD,YAAA,MAAME,KAAQ,GAAA,IAAI,CAACzB,eAAe,CAACuB,CAAE,CAAA;AACrC,YAAA,MAAMG,IAAOD,GAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAA;YAC1B,IAAI,CAACD,IAAQA,IAAAA,IAAAA,KAASlB,MAAQ,EAAA;AAC3BkB,gBAAAA,CAAAA,QAAQlB,MAAK,EAAGsB,GAAG,CAAC,WAAA,EAAaL,MAAMP,QAAQ,CAAA;gBAChDO,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACjB,gBAAA,IAAI,CAAC5B,eAAe,CAAC6B,MAAM,CAACN,CAAG,EAAA,CAAA,CAAA;gBAC/BD,OAAU,GAAA,IAAA;AAEZ;AACF;AACA,QAAA,IAAIA,OAAS,EAAA;AACX,YAAA,IAAI,CAACS,mBAAmB,EAAA;AACxB,YAAA,IAAI,CAACZ,oBAAoB,EAAA;AAC3B;AACA,QAAA,OAAO,IAAI;AACb;AAEA;;AAEC,MACDa,YAAe,GAAA;AACb,QAAA,KAAK,MAAMP,KAAAA,IAAS,IAAI,CAACzB,eAAe,CAAE;AACxCyB,YAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,IAAIG,GAAI,CAAA,WAAA,EAAaL,MAAMP,QAAQ,CAAA;YAChDO,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACnB;AACA,QAAA,KAAK,MAAMH,KAAAA,IAAS,IAAI,CAAC1B,cAAc,CAAE;YACvC0B,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACnB;AACA,QAAA,IAAI,CAAC7B,cAAc,CAACyB,MAAM,GAAG,CAAA;AAC7B,QAAA,IAAI,CAACxB,eAAe,CAACwB,MAAM,GAAG,CAAA;QAC9B,IAAI,CAAC7B,aAAa,CAACC,WAAW,EAAA;QAC9B,IAAI,CAACC,cAAc,CAACD,WAAW,EAAA;AAC/B,QAAA,IAAI,CAACK,YAAY,EAAA;AACnB;AAEA;;;;AAIC,MACDgC,KAAc,GAAA;QACZ,IAAI,CAACxC,aAAa,GAAG,IAAA;AACrB,QAAA,IAAI,CAACuC,YAAY,EAAA;AACjB,QAAA,OAAO,IAAI;AACb;8CAGA,SAA4B,GAAA;AAC1B,QAAA,IAAI,CAACC,KAAK,EAAA;AACZ;AAEA,qBACQvB,SAAUF,CAAAA,MAAiB,EAAW;QAC5C,OACE,IAAI,CAACT,cAAc,CAACmC,IAAI,CAAC,CAACT,KAAUA,GAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAA,KAAOnB,WACxD,IAAI,CAACR,eAAe,CAACkC,IAAI,CAAC,CAACT,KAAAA,GAAUA,KAAMX,CAAAA,GAAG,CAACa,GAAG,EAAOnB,KAAAA,MAAAA,CAAAA;AAE7D;AAEA,qBACQC,cAAeD,CAAAA,MAAiB,EAAW;QACjD,OAAO,CAACA,MAAO2B,CAAAA,QAAQ,KAAK3B,OAAO4B,MAAM,EAAA,IAAM5B,MAAO6B,CAAAA,gBAAgB,EAAC,CAAA;AACzE;AAEA,qBACQzB,aAAcJ,CAAAA,MAAiB,EAAkB;QACvD,MAAM8B,IAAAA,GAAO9B,MAAO+B,CAAAA,sBAAsB,EAAIC,EAAAA,MAAAA,EAAAA;AAC9C,QAAA,OAAOF,IAAMpC,EAAAA,OAAAA,EAAAA,GAAY,IAAIR,IAAAA,CAAK4C,IAAQ,CAAA,GAAA,IAAA;AAC5C;qBAGA,mBAA8B,GAAA;QAC5B,IAAI,CAAC3C,aAAa,CAACC,WAAW,EAAA;QAC9B,IAAK,IAAI2B,CAAI,GAAA,IAAI,CAACxB,cAAc,CAACyB,MAAM,GAAG,CAAA,EAAGD,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;AACxD,YAAA,MAAME,KAAQ,GAAA,IAAI,CAAC1B,cAAc,CAACwB,CAAE,CAAA;AACpC,YAAA,IAAI,CAACE,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAI,EAAA;gBACpBF,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACjB,gBAAA,IAAI,CAAC7B,cAAc,CAAC8B,MAAM,CAACN,CAAG,EAAA,CAAA,CAAA;aACzB,MAAA;gBACL,IAAI,CAACP,YAAY,CAAC,IAAI,CAACrB,aAAa,EAAE8B,MAAMd,IAAI,CAAA;AAClD;AACF;AACA,QAAA,IAAI,CAACV,YAAY,EAAA;AACnB;qBAGA,oBAA+B,GAAA;QAC7B,IAAI,CAACJ,cAAc,CAACD,WAAW,EAAA;QAC/B,IAAK,IAAI2B,CAAI,GAAA,IAAI,CAACvB,eAAe,CAACwB,MAAM,GAAG,CAAA,EAAGD,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;AACzD,YAAA,MAAME,KAAQ,GAAA,IAAI,CAACzB,eAAe,CAACuB,CAAE,CAAA;AACrC,YAAA,MAAMf,MAASiB,GAAAA,KAAAA,CAAMX,GAAG,CAACa,GAAG,EAAA;AAC5B,YAAA,IAAI,CAACnB,MAAU,IAAA,CAAC,IAAI,CAACC,cAAc,CAACD,MAAS,CAAA,EAAA;gBAC3CA,MAAQsB,EAAAA,GAAAA,CAAI,WAAaL,EAAAA,KAAAA,CAAMP,QAAQ,CAAA;gBACvCO,KAAMX,CAAAA,GAAG,CAACc,OAAO,EAAA;AACjB,gBAAA,IAAI,CAAC5B,eAAe,CAAC6B,MAAM,CAACN,CAAG,EAAA,CAAA,CAAA;AAC/B,gBAAA;AACF;AACA,YAAA,MAAMZ,IAAO,GAAA,IAAI,CAACC,aAAa,CAACJ,MAAAA,CAAAA;AAChC,YAAA,IAAIG,IAAM,EAAA;AACR,gBAAA,IAAI,CAACK,YAAY,CAAC,IAAI,CAACnB,cAAc,EAAEc,IAAAA,CAAAA;AACzC;AACF;AACA,QAAA,IAAI,CAACV,YAAY,EAAA;AACnB;qBAGA,YAAuB,GAAA;QACrB,IAAI,CAACH,OAAO,CAACF,WAAW,EAAA;AACxB,QAAA,IAAI,IAAI,CAACH,aAAa,EAAES,OAAW,EAAA,EAAA;YACjC,IAAI,CAACc,YAAY,CAAC,IAAI,CAAClB,OAAO,EAAE,IAAI,CAACL,aAAa,CAAA;AACpD;AACA,QAAA,IAAI,IAAI,CAACE,aAAa,CAACO,OAAO,EAAI,EAAA;YAChC,IAAI,CAACc,YAAY,CAAC,IAAI,CAAClB,OAAO,EAAE,IAAI,CAACH,aAAa,CAAA;AACpD;AACA,QAAA,IAAI,IAAI,CAACE,cAAc,CAACK,OAAO,EAAI,EAAA;YACjC,IAAI,CAACc,YAAY,CAAC,IAAI,CAAClB,OAAO,EAAE,IAAI,CAACD,cAAc,CAAA;AACrD;AACF;AAEA,qBACA,YAAQmB,CAAaxB,MAAY,EAAEmB,IAAU,EAAE;QAC7CnB,MAAOiD,CAAAA,MAAM,CAAC9B,IAAAA,CAAK+B,QAAQ,CAAA;QAC3BlD,MAAOiD,CAAAA,MAAM,CAAC9B,IAAAA,CAAKgC,QAAQ,CAAA;AAC7B;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"shadow_region.js","sources":["../../src/shadow/shadow_region.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\nimport { AABB, Disposable, DWeakRef } from '@zephyr3d/base';\nimport type { SceneNode } from '../scene/scene_node';\n\ntype StaticShadowCasterEntry = {\n ref: DWeakRef<SceneNode>;\n aabb: AABB;\n};\n\ntype DynamicShadowCasterEntry = {\n ref: DWeakRef<SceneNode>;\n callback: (node: SceneNode) => void;\n};\n\n/**\n * Maintains the world-space region used by directional light shadow maps.\n *\n * @public\n */\nexport class ShadowRegion extends Disposable {\n /** @internal */\n private _manualRegion: Nullable<AABB>;\n /** @internal */\n private readonly _staticRegion: AABB;\n /** @internal */\n private readonly _dynamicRegion: AABB;\n /** @internal */\n private readonly _region: AABB;\n /** @internal */\n private readonly _staticCasters: StaticShadowCasterEntry[];\n /** @internal */\n private readonly _dynamicCasters: DynamicShadowCasterEntry[];\n\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();\n this._manualRegion = region ? new AABB(region) : null;\n this._staticRegion = new AABB().beginExtend();\n this._dynamicRegion = new AABB().beginExtend();\n this._region = new AABB().beginExtend();\n this._staticCasters = [];\n this._dynamicCasters = [];\n this.updateRegion();\n }\n\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;\n }\n\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;\n }\n\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;\n }\n\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;\n }\n\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;\n this.updateRegion();\n }\n\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)) {\n return this;\n }\n const aabb = this.getCasterAABB(caster);\n if (!aabb) {\n return this;\n }\n this._staticCasters.push({\n ref: new DWeakRef(caster),\n aabb\n });\n this.extendRegion(this._staticRegion, aabb);\n this.updateRegion();\n return this;\n }\n\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)) {\n return this;\n }\n const callback = () => {\n this.rebuildDynamicRegion();\n };\n caster.on('bvchanged', callback);\n this._dynamicCasters.push({\n ref: new DWeakRef(caster),\n callback\n });\n const aabb = this.getCasterAABB(caster);\n if (aabb) {\n this.extendRegion(this._dynamicRegion, aabb);\n this.updateRegion();\n }\n return this;\n }\n\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;\n let changed = false;\n for (let i = this._staticCasters.length - 1; i >= 0; i--) {\n const entry = this._staticCasters[i];\n const node = entry.ref.get();\n if (!node || node === caster) {\n entry.ref.dispose();\n this._staticCasters.splice(i, 1);\n changed = true;\n removed ||= node === caster;\n }\n }\n for (let i = this._dynamicCasters.length - 1; i >= 0; i--) {\n const entry = this._dynamicCasters[i];\n const node = entry.ref.get();\n if (!node || node === caster) {\n (node ?? caster).off('bvchanged', entry.callback);\n entry.ref.dispose();\n this._dynamicCasters.splice(i, 1);\n changed = true;\n removed ||= node === caster;\n }\n }\n if (changed) {\n this.rebuildStaticRegion();\n this.rebuildDynamicRegion();\n }\n return this;\n }\n\n /**\n * Removes all shadow casters while keeping the manual region.\n */\n clearCasters() {\n for (const entry of this._dynamicCasters) {\n entry.ref.get()?.off('bvchanged', entry.callback);\n entry.ref.dispose();\n }\n for (const entry of this._staticCasters) {\n entry.ref.dispose();\n }\n this._staticCasters.length = 0;\n this._dynamicCasters.length = 0;\n this._staticRegion.beginExtend();\n this._dynamicRegion.beginExtend();\n this.updateRegion();\n }\n\n /**\n * Clears the manual region and all shadow casters.\n *\n * @returns `this` for chaining.\n */\n clear(): this {\n this._manualRegion = null;\n this.clearCasters();\n return this;\n }\n\n /** {@inheritDoc Disposable.onDispose} */\n protected onDispose(): void {\n this.clear();\n }\n\n /** @internal */\n private hasCaster(caster: SceneNode): boolean {\n return (\n this._staticCasters.some((entry) => entry.ref.get() === caster) ||\n this._dynamicCasters.some((entry) => entry.ref.get() === caster)\n );\n }\n\n /** @internal */\n private isShadowCaster(caster: SceneNode): boolean {\n return !caster.disposed && (caster.isMesh() || caster.isClipmapTerrain() || caster.isHair());\n }\n\n /** @internal */\n private getCasterAABB(caster: SceneNode): Nullable<AABB> {\n const bbox = caster.getWorldBoundingVolume()?.toAABB();\n return bbox?.isValid() ? new AABB(bbox) : null;\n }\n\n /** @internal */\n private rebuildStaticRegion() {\n this._staticRegion.beginExtend();\n for (let i = this._staticCasters.length - 1; i >= 0; i--) {\n const entry = this._staticCasters[i];\n if (!entry.ref.get()) {\n entry.ref.dispose();\n this._staticCasters.splice(i, 1);\n } else {\n this.extendRegion(this._staticRegion, entry.aabb);\n }\n }\n this.updateRegion();\n }\n\n /** @internal */\n private rebuildDynamicRegion() {\n this._dynamicRegion.beginExtend();\n for (let i = this._dynamicCasters.length - 1; i >= 0; i--) {\n const entry = this._dynamicCasters[i];\n const caster = entry.ref.get();\n if (!caster || !this.isShadowCaster(caster)) {\n caster?.off('bvchanged', entry.callback);\n entry.ref.dispose();\n this._dynamicCasters.splice(i, 1);\n continue;\n }\n const aabb = this.getCasterAABB(caster);\n if (aabb) {\n this.extendRegion(this._dynamicRegion, aabb);\n }\n }\n this.updateRegion();\n }\n\n /** @internal */\n private updateRegion() {\n this._region.beginExtend();\n if (this._manualRegion?.isValid()) {\n this.extendRegion(this._region, this._manualRegion);\n }\n if (this._staticRegion.isValid()) {\n this.extendRegion(this._region, this._staticRegion);\n }\n if (this._dynamicRegion.isValid()) {\n this.extendRegion(this._region, this._dynamicRegion);\n }\n }\n\n /** @internal */\n private extendRegion(region: AABB, aabb: AABB) {\n region.extend(aabb.minPoint);\n region.extend(aabb.maxPoint);\n }\n}\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","isHair","bbox","getWorldBoundingVolume","toAABB","extend","minPoint","maxPoint"],"mappings":"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"}
|