babylonjs-editor-tools 5.5.0 → 5.5.1-alpha.1

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.
Files changed (68) hide show
  1. package/build/index.node.js +2342 -1
  2. package/build/src/decorators/inspector.js.map +1 -1
  3. package/build/src/index.js +5 -0
  4. package/build/src/index.js.map +1 -1
  5. package/build/src/loading/loader.js +10 -2
  6. package/build/src/loading/loader.js.map +1 -1
  7. package/build/src/loading/mesh.js +22 -0
  8. package/build/src/loading/mesh.js.map +1 -0
  9. package/build/src/loading/rendering.js +4 -0
  10. package/build/src/loading/rendering.js.map +1 -1
  11. package/build/src/loading/script/preload/plugins/navmesh.js +3 -0
  12. package/build/src/loading/script/preload/plugins/navmesh.js.map +1 -1
  13. package/build/src/loading/sound.js +17 -2
  14. package/build/src/loading/sound.js.map +1 -1
  15. package/build/src/loading/transform-node.js +4 -1
  16. package/build/src/loading/transform-node.js.map +1 -1
  17. package/build/src/rendering/default-pipeline.js +5 -8
  18. package/build/src/rendering/default-pipeline.js.map +1 -1
  19. package/build/src/rendering/motion-blur.js +7 -7
  20. package/build/src/rendering/motion-blur.js.map +1 -1
  21. package/build/src/rendering/ssao.js +9 -9
  22. package/build/src/rendering/ssao.js.map +1 -1
  23. package/build/src/rendering/ssr.js +7 -9
  24. package/build/src/rendering/ssr.js.map +1 -1
  25. package/build/src/rendering/taa.js +7 -9
  26. package/build/src/rendering/taa.js.map +1 -1
  27. package/build/src/rendering/tools.js +38 -6
  28. package/build/src/rendering/tools.js.map +1 -1
  29. package/build/src/rendering/vls.js +13 -11
  30. package/build/src/rendering/vls.js.map +1 -1
  31. package/build/src/rendering/volumetric/depth.js +110 -0
  32. package/build/src/rendering/volumetric/depth.js.map +1 -0
  33. package/build/src/rendering/volumetric/pipeline.js +1070 -0
  34. package/build/src/rendering/volumetric/pipeline.js.map +1 -0
  35. package/build/src/rendering/volumetric/selector.js +525 -0
  36. package/build/src/rendering/volumetric/selector.js.map +1 -0
  37. package/build/src/rendering/volumetric/shaders-wgsl.js +1212 -0
  38. package/build/src/rendering/volumetric/shaders-wgsl.js.map +1 -0
  39. package/build/src/rendering/volumetric/shaders.js +1300 -0
  40. package/build/src/rendering/volumetric/shaders.js.map +1 -0
  41. package/build/src/rendering/volumetric/types.js +301 -0
  42. package/build/src/rendering/volumetric/types.js.map +1 -0
  43. package/build/src/rendering/volumetric-lighting.js +74 -0
  44. package/build/src/rendering/volumetric-lighting.js.map +1 -0
  45. package/build/src/tools/guards.js +14 -0
  46. package/build/src/tools/guards.js.map +1 -1
  47. package/build/src/tools/ragdoll.js +54 -0
  48. package/build/src/tools/ragdoll.js.map +1 -1
  49. package/declaration/src/decorators/inspector.d.ts +1 -0
  50. package/declaration/src/index.d.ts +5 -0
  51. package/declaration/src/loading/mesh.d.ts +1 -0
  52. package/declaration/src/rendering/default-pipeline.d.ts +3 -2
  53. package/declaration/src/rendering/motion-blur.d.ts +3 -2
  54. package/declaration/src/rendering/ssao.d.ts +3 -2
  55. package/declaration/src/rendering/ssr.d.ts +3 -2
  56. package/declaration/src/rendering/taa.d.ts +3 -2
  57. package/declaration/src/rendering/tools.d.ts +18 -1
  58. package/declaration/src/rendering/vls.d.ts +3 -2
  59. package/declaration/src/rendering/volumetric/depth.d.ts +68 -0
  60. package/declaration/src/rendering/volumetric/pipeline.d.ts +284 -0
  61. package/declaration/src/rendering/volumetric/selector.d.ts +263 -0
  62. package/declaration/src/rendering/volumetric/shaders-wgsl.d.ts +21 -0
  63. package/declaration/src/rendering/volumetric/shaders.d.ts +60 -0
  64. package/declaration/src/rendering/volumetric/types.d.ts +362 -0
  65. package/declaration/src/rendering/volumetric-lighting.d.ts +29 -0
  66. package/declaration/src/tools/guards.d.ts +12 -0
  67. package/declaration/src/tools/ragdoll.d.ts +20 -1
  68. package/package.json +2 -2
@@ -1 +1,2342 @@
1
- var Pe=Object.defineProperty;var In=Object.getOwnPropertyDescriptor;var En=Object.getOwnPropertyNames;var Tn=Object.prototype.hasOwnProperty;var i=(e,r)=>Pe(e,"name",{value:r,configurable:!0});var On=(e,r)=>{for(var t in r)Pe(e,t,{get:r[t],enumerable:!0})},Dn=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of En(r))!Tn.call(e,o)&&o!==t&&Pe(e,o,{get:()=>r[o],enumerable:!(n=In(r,o))||n.enumerable});return e};var Mn=e=>Dn(Pe({},"__esModule",{value:!0}),e);var $o={};On($o,{AdvancedAssetContainer:()=>de,AdvancedAssetContainerInstantiatedEntries:()=>ue,Cinematic:()=>Se,Database:()=>be,NodeParticleSystemSet:()=>dn.NodeParticleSystemSet,_applyScriptsForObject:()=>F,_getKtx2TextureName:()=>Oe,_preloadScriptsAssets:()=>xt,_registerScriptInstance:()=>Ct,_removeRegisteredScriptInstance:()=>Ie,addExcludedCompressedTexture:()=>De,animationFromSprite:()=>Fo,animationGroupFromScene:()=>fo,applyMeshesLODQuality:()=>ze,applyRenderingConfigurationForCamera:()=>mt,applyScriptOnObject:()=>ro,applyShadowsQuality:()=>kn,applyTexturesQuality:()=>io,componentFromScene:()=>mo,configureEngineToUseCompressedTextures:()=>oo,configureMeshDistanceOrScreenCoverage:()=>ke,configureShadowMapRefreshRate:()=>ve,configureShadowMapRenderListPredicate:()=>$e,copyAndParseRagdollConfiguration:()=>ft,createAndOpenDatabase:()=>_t,createDefaultRenderingPipeline:()=>nr,createMotionBlurPostProcess:()=>Zt,createSSAO2RenderingPipeline:()=>qt,createSSRRenderingPipeline:()=>Qt,createTAARenderingPipeline:()=>Yt,createVLSPostProcess:()=>jt,defaultPipelineCameraConfigurations:()=>Z,disposeDefaultRenderingPipeline:()=>lt,disposeMotionBlurPostProcess:()=>ot,disposeSSAO2RenderingPipeline:()=>et,disposeSSRRenderingPipeline:()=>Ye,disposeTAARenderingPipeline:()=>Je,disposeVLSPostProcess:()=>Ue,forceCompileAllSceneMaterials:()=>co,generateCinematicAnimationGroup:()=>Bo,getAllScriptsByClassForObject:()=>ne,getAnimationTypeForObject:()=>ye,getDefaultRenderingPipeline:()=>pe,getFromIndexDB:()=>he,getMotionBlurPostProcess:()=>nt,getPowerOfTwoUntil:()=>M,getSSAO2RenderingPipeline:()=>Wn,getSSRRenderingPipeline:()=>$n,getScriptByClassForObject:()=>vt,getTAARenderingPipeline:()=>Un,getTextureUrl:()=>Me,getVLSPostProcess:()=>je,guiFromAsset:()=>yo,isAbstractMesh:()=>$,isAnyParticleSystem:()=>Ve,isArcRotateCamera:()=>Rn,isBone:()=>wn,isCamera:()=>xe,isCinematicGroup:()=>Lo,isCinematicKey:()=>Ft,isCinematicKeyCut:()=>ie,isCinematicKeyEvent:()=>_o,isCinematicSound:()=>Vo,isClusteredLightContainer:()=>Ae,isDecalMesh:()=>Bt,isDirectionalLight:()=>Ln,isFreeCamera:()=>Fn,isGPUParticleSystem:()=>Gn,isGaussianSplattingMesh:()=>Ge,isGroundMesh:()=>Nn,isHemisphericLight:()=>Bn,isInstancedMesh:()=>le,isLight:()=>Vt,isMesh:()=>D,isNode:()=>Q,isNodeFromStaticGroup:()=>Ke,isParticleSystem:()=>Le,isPointLight:()=>_n,isScene:()=>_e,isSoundNode:()=>j,isSpotLight:()=>Vn,isSprite:()=>Be,isTexture:()=>ce,isTransformNode:()=>k,isUsingKtx2CompressedTextures:()=>ge,loadMaterialFromFile:()=>lo,loadScene:()=>ao,motionBlurPostProcessCameraConfigurations:()=>J,nodeFromDescendants:()=>uo,nodeFromScene:()=>po,normalizeAtlasJson:()=>Tt,onKeyboardEvent:()=>wo,onPointerEvent:()=>Mo,openIndexDB:()=>Rt,parseCinematic:()=>Ro,parseCinematicKeyValue:()=>_,parseDefaultRenderingPipeline:()=>pt,parseKeyFrameAnimations:()=>wt,parseMotionBlurPostProcess:()=>st,parseRagdollConfiguration:()=>cr,parseSSAO2RenderingPipeline:()=>rt,parseSSRRenderingPipeline:()=>qe,parseTAARenderingPipeline:()=>Xe,parseVLSPostProcess:()=>We,particleSystemFromScene:()=>ho,playSpriteAnimationFromName:()=>so,preloadAssetsToDatabase:()=>zo,putInIndexDB:()=>V,registerScriptAssetParser:()=>to,saveRenderingConfigurationForCamera:()=>Jn,sceneAsset:()=>go,scriptAssetsCache:()=>O,scriptAssetsParsers:()=>fe,scriptsDictionary:()=>R,serializeDefaultRenderingPipeline:()=>ct,serializeMotionBlurPostProcess:()=>it,serializeSSAO2RenderingPipeline:()=>tt,serializeSSRRenderingPipeline:()=>He,serializeTAARenderingPipeline:()=>Ze,serializeVLSPostProcess:()=>Qe,setDefaultRenderingPipelineRef:()=>qn,setMotionBlurPostProcessRef:()=>Hn,setSSAO2RenderingPipelineRef:()=>Yn,setSSRRenderingPipelineRef:()=>jn,setStaticDecalsEnabled:()=>Kn,setTAARenderingPipelineRef:()=>Qn,setUseKtx2CompressedTextures:()=>no,setVLSPostProcessRef:()=>zn,setupOfflineProvider:()=>Go,soundFromScene:()=>So,spriteFromSpriteManager:()=>No,ssaoRenderingPipelineCameraConfigurations:()=>q,ssrRenderingPipelineCameraConfigurations:()=>Y,taaRenderingPipelineCameraConfigurations:()=>H,visibleAsAsset:()=>Do,visibleAsBoolean:()=>bo,visibleAsColor3:()=>Co,visibleAsColor4:()=>Io,visibleAsEntity:()=>Eo,visibleAsKeyMap:()=>Oo,visibleAsNumber:()=>xo,visibleAsString:()=>Po,visibleAsTexture:()=>To,visibleAsVector2:()=>Ao,visibleAsVector3:()=>vo,vlsPostProcessCameraConfigurations:()=>W});module.exports=Mn($o);function $(e){switch(e.getClassName?.()){case"Mesh":case"LineMesh":case"GroundMesh":case"InstancedMesh":return!0}return!1}i($,"isAbstractMesh");function D(e){switch(e.getClassName?.()){case"Mesh":case"GroundMesh":return!0}return!1}i(D,"isMesh");function le(e){return e.getClassName?.()==="InstancedMesh"}i(le,"isInstancedMesh");function wn(e){return e.getClassName?.()==="Bone"}i(wn,"isBone");function Nn(e){return e.getClassName?.()==="GroundMesh"}i(Nn,"isGroundMesh");function k(e){return e.getClassName?.()==="TransformNode"}i(k,"isTransformNode");function ce(e){return e?.getClassName?.()==="Texture"}i(ce,"isTexture");function xe(e){switch(e.getClassName?.()){case"Camera":case"FreeCamera":case"TargetCamera":case"EditorCamera":case"ArcRotateCamera":case"UniversalCamera":return!0}return!1}i(xe,"isCamera");function Fn(e){switch(e.getClassName?.()){case"FreeCamera":case"UniversalCamera":return!0}return!1}i(Fn,"isFreeCamera");function Rn(e){return e.getClassName?.()==="ArcRotateCamera"}i(Rn,"isArcRotateCamera");function _n(e){return e.getClassName?.()==="PointLight"}i(_n,"isPointLight");function Ln(e){return e.getClassName?.()==="DirectionalLight"}i(Ln,"isDirectionalLight");function Vn(e){return e.getClassName?.()==="SpotLight"}i(Vn,"isSpotLight");function Bn(e){return e.getClassName?.()==="HemisphericLight"}i(Bn,"isHemisphericLight");function Vt(e){switch(e.getClassName?.()){case"Light":case"PointLight":case"SpotLight":case"DirectionalLight":case"HemisphericLight":return!0}return!1}i(Vt,"isLight");function Ae(e){return e.getClassName?.()==="ClusteredLightContainer"}i(Ae,"isClusteredLightContainer");function Q(e){return $(e)||k(e)||Vt(e)||xe(e)}i(Q,"isNode");function _e(e){return e.getClassName?.()==="Scene"}i(_e,"isScene");function Le(e){return e.getClassName?.()==="ParticleSystem"}i(Le,"isParticleSystem");function Gn(e){return e.getClassName?.()==="GPUParticleSystem"}i(Gn,"isGPUParticleSystem");function Ve(e){switch(e.getClassName?.()){case"ParticleSystem":case"GPUParticleSystem":return!0}return!1}i(Ve,"isAnyParticleSystem");function Be(e){return e.getClassName?.()==="Sprite"}i(Be,"isSprite");function j(e){return e.getClassName?.()==="SoundNode"}i(j,"isSoundNode");function Ge(e){return e.getClassName?.()==="GaussianSplattingMesh"}i(Ge,"isGaussianSplattingMesh");function Ke(e){let r=e;for(;r;){if(r.metadata?.isStaticGroup)return!0;r=r.parent}return!1}i(Ke,"isNodeFromStaticGroup");function ke(e){e.meshes.forEach(r=>{D(r)&&r.getLODLevels().forEach(t=>{t.mesh&&(t.mesh.originalDistanceOrScreenCoverage=t.distanceOrScreenCoverage)})})}i(ke,"configureMeshDistanceOrScreenCoverage");function ze(e,r){r.meshes.forEach(t=>{D(t)&&t.getLODLevels().forEach(n=>{if(n.mesh?.originalDistanceOrScreenCoverage)switch(e){case"very-low":n.distanceOrScreenCoverage=n.mesh.originalDistanceOrScreenCoverage*.125;break;case"low":n.distanceOrScreenCoverage=n.mesh.originalDistanceOrScreenCoverage*.25;break;case"medium":n.distanceOrScreenCoverage=n.mesh.originalDistanceOrScreenCoverage*.5;break;case"high":n.distanceOrScreenCoverage=n.mesh.originalDistanceOrScreenCoverage;break}})})}i(ze,"applyMeshesLODQuality");function Bt(e){return(e.metadata?.decal??null)!==null}i(Bt,"isDecalMesh");function Kn(e,r){r.meshes.forEach(t=>{Bt(t)&&Ke(t)&&t.setEnabled(e)})}i(Kn,"setStaticDecalsEnabled");function M(e){let r=1;for(;r<=e;)r<<=1;return r>>1}i(M,"getPowerOfTwoUntil");var Gt=require("babylonjs"),Kt=require("babylonjs");function $e(e){e.lights.forEach(r=>{let t=r.getShadowGenerator()?.getShadowMap();t&&(t.renderListPredicate=n=>Ge(n)?!1:Gt.Vector3.Distance(n.getAbsolutePosition(),r.getAbsolutePosition())<=r.range)})}i($e,"configureShadowMapRenderListPredicate");async function ve(e){e.executeWhenReady(()=>{e.lights.forEach(r=>{let t=r.getShadowGenerator()?.getShadowMap();t&&(t.refreshRate=r.metadata?.refreshRate??Kt.RenderTargetTexture.REFRESHRATE_RENDER_ONEVERYFRAME)})})}i(ve,"configureShadowMapRefreshRate");function kn(e,r){r.lights.forEach(t=>{let n=t.getShadowGenerator(),o=n?.getShadowMap();if(n?.originalMapSize){let s=n.originalMapSize;switch(e){case"medium":s=s*.5;break;case"low":s=s*.25;break;case"very-low":s=s*.125;break}s=Math.max(128,M(s)),o?.getSize().width!==s&&o.resize(s)}}),ve(r)}i(kn,"applyShadowsQuality");var kt=require("babylonjs"),zt=require("babylonjs"),$t=require("babylonjs"),I=null,W=new Map;function je(){return I}i(je,"getVLSPostProcess");function zn(e){I=e}i(zn,"setVLSPostProcessRef");function Ue(e){I&&e.activeCamera&&(I.dispose(e.activeCamera),I=null)}i(Ue,"disposeVLSPostProcess");function jt(e,r){return r??=e.meshes.find(t=>D(t)),I=new $t.VolumetricLightScatteringPostProcess("VolumetricLightScatteringPostProcess",1,e.activeCamera,r,100,zt.Texture.BILINEAR_SAMPLINGMODE,e.getEngine(),!1),I}i(jt,"createVLSPostProcess");function Qe(){return I?{meshId:I.mesh?.id,exposure:I.exposure,decay:I.decay,weight:I.weight,density:I.density,invert:I.invert,useCustomMeshPosition:I.useCustomMeshPosition,customMeshPosition:I.customMeshPosition.asArray()}:null}i(Qe,"serializeVLSPostProcess");function We(e,r){let t=null;if(r.meshId){let o=e.getMeshById(r.meshId);o&&D(o)&&(t=o)}let n=jt(e,t);return n.exposure=r.exposure,n.decay=r.decay,n.weight=r.weight,n.density=r.density,n.invert=r.invert,n.useCustomMeshPosition=r.useCustomMeshPosition,n.customMeshPosition.copyFrom(kt.Vector3.FromArray(r.customMeshPosition)),n}i(We,"parseVLSPostProcess");var Ut=require("babylonjs"),b=null,Y=new Map;function $n(){return b}i($n,"getSSRRenderingPipeline");function jn(e){b=e}i(jn,"setSSRRenderingPipelineRef");function Ye(){b&&(b.dispose(),b=null)}i(Ye,"disposeSSRRenderingPipeline");function Qt(e,r){return b=new Ut.SSRRenderingPipeline("SSRRenderingPipeline",e,[r]),b.samples=4,b}i(Qt,"createSSRRenderingPipeline");function He(){return b?{samples:b.samples,step:b.step,thickness:b.thickness,strength:b.strength,reflectionSpecularFalloffExponent:b.reflectionSpecularFalloffExponent,maxSteps:b.maxSteps,maxDistance:b.maxDistance,roughnessFactor:b.roughnessFactor,reflectivityThreshold:b.reflectivityThreshold,blurDispersionStrehgth:b.blurDispersionStrength,clipToFrustum:b.clipToFrustum,enableSmoothReflections:b.enableSmoothReflections,enableAutomaticThicknessComputation:b.enableAutomaticThicknessComputation,attenuateFacingCamera:b.attenuateFacingCamera,attenuateScreenBorders:b.attenuateScreenBorders,attenuateIntersectionDistance:b.attenuateIntersectionDistance,attenuateBackfaceReflection:b.attenuateBackfaceReflection,blurDownsample:b.blurDownsample,selfCollisionNumSkip:b.selfCollisionNumSkip,ssrDownsample:b.ssrDownsample,backfaceDepthTextureDownsample:b.backfaceDepthTextureDownsample}:null}i(He,"serializeSSRRenderingPipeline");function qe(e,r,t){if(b)return b;let n=Qt(e,r);return n.samples=t.samples,n.step=t.step,n.thickness=t.thickness,n.strength=t.strength,n.reflectionSpecularFalloffExponent=t.reflectionSpecularFalloffExponent,n.maxSteps=t.maxSteps,n.maxDistance=t.maxDistance,n.roughnessFactor=t.roughnessFactor,n.reflectivityThreshold=t.reflectivityThreshold,n.blurDispersionStrength=t.blurDispersionStrehgth,n.clipToFrustum=t.clipToFrustum,n.enableSmoothReflections=t.enableSmoothReflections,n.enableAutomaticThicknessComputation=t.enableAutomaticThicknessComputation,n.attenuateFacingCamera=t.attenuateFacingCamera,n.attenuateScreenBorders=t.attenuateScreenBorders,n.attenuateIntersectionDistance=t.attenuateIntersectionDistance,n.attenuateBackfaceReflection=t.attenuateBackfaceReflection,n.blurDownsample=t.blurDownsample,n.selfCollisionNumSkip=t.selfCollisionNumSkip,n.ssrDownsample=t.ssrDownsample,n.backfaceDepthTextureDownsample=t.backfaceDepthTextureDownsample,n}i(qe,"parseSSRRenderingPipeline");var Wt=require("babylonjs"),E=null,H=new Map;function Un(){return E}i(Un,"getTAARenderingPipeline");function Qn(e){E=e}i(Qn,"setTAARenderingPipelineRef");function Je(){E&&(E.dispose(),E=null)}i(Je,"disposeTAARenderingPipeline");function Yt(e,r){return E=new Wt.TAARenderingPipeline("TAARenderingPipeline",e,[r]),E.samples=4,E}i(Yt,"createTAARenderingPipeline");function Ze(){return E?{factor:E.factor,samples:E.samples,clampHistory:E.clampHistory,reprojectHistory:E.reprojectHistory,disableOnCameraMove:E.disableOnCameraMove}:null}i(Ze,"serializeTAARenderingPipeline");function Xe(e,r,t){if(E)return E;let n=Yt(e,r);return n.factor=t.factor,n.samples=t.samples,n.clampHistory=t.clampHistory,n.reprojectHistory=t.reprojectHistory,n.disableOnCameraMove=t.disableOnCameraMove,n}i(Xe,"parseTAARenderingPipeline");var Ht=require("babylonjs"),x=null,q=new Map;function Wn(){return x}i(Wn,"getSSAO2RenderingPipeline");function Yn(e){x=e}i(Yn,"setSSAO2RenderingPipelineRef");function et(){x&&(x.dispose(),x=null)}i(et,"disposeSSAO2RenderingPipeline");function qt(e,r){return x=new Ht.SSAO2RenderingPipeline("SSAO2RenderingPipeline",e,1,[r]),x.samples=4,x}i(qt,"createSSAO2RenderingPipeline");function tt(){return x?{radius:x.radius,totalStrength:x.totalStrength,samples:x.samples,maxZ:x.maxZ,minZAspect:x.minZAspect,epsilon:x.epsilon,textureSamples:x.textureSamples,bypassBlur:x.bypassBlur,bilateralSamples:x.bilateralSamples,bilateralSoften:x.bilateralSoften,bilateralTolerance:x.bilateralTolerance,expensiveBlur:x.expensiveBlur}:null}i(tt,"serializeSSAO2RenderingPipeline");function rt(e,r,t){if(x)return x;let n=qt(e,r);return n.radius=t.radius,n.totalStrength=t.totalStrength,n.samples=t.samples,n.maxZ=t.maxZ,n.minZAspect=t.minZAspect,n.epsilon=t.epsilon,n.textureSamples=t.textureSamples,n.bypassBlur=t.bypassBlur,n.bilateralSamples=t.bilateralSamples,n.bilateralSoften=t.bilateralSoften,n.bilateralTolerance=t.bilateralTolerance,n.expensiveBlur=t.expensiveBlur,n}i(rt,"parseSSAO2RenderingPipeline");var Jt=require("babylonjs"),T=null,J=new Map;function nt(){return T}i(nt,"getMotionBlurPostProcess");function Hn(e){T=e}i(Hn,"setMotionBlurPostProcessRef");function ot(){T&&(T.dispose(),T=null)}i(ot,"disposeMotionBlurPostProcess");function Zt(e,r){return T=new Jt.MotionBlurPostProcess("MotionBlurPostProcess",e,1,r),T.motionStrength=1,T.isObjectBased=!0,T}i(Zt,"createMotionBlurPostProcess");function it(){return T?{isObjectBased:T.isObjectBased,motionStrength:T.motionStrength,motionBlurSamples:T.motionBlurSamples}:null}i(it,"serializeMotionBlurPostProcess");function st(e,r,t){if(T)return T;let n=Zt(e,r);return n.isObjectBased=t.isObjectBased,n.motionStrength=t.motionStrength,n.motionBlurSamples=t.motionBlurSamples,n}i(st,"parseMotionBlurPostProcess");var Xt=require("babylonjs"),at=require("babylonjs"),er=require("babylonjs"),tr=require("babylonjs"),rr=require("babylonjs"),d=null,Z=new Map;function pe(){return d}i(pe,"getDefaultRenderingPipeline");function qn(e){d=e}i(qn,"setDefaultRenderingPipelineRef");function lt(){d&&(d.dispose(),d=null)}i(lt,"disposeDefaultRenderingPipeline");function nr(e,r){return d=new rr.DefaultRenderingPipeline("DefaultRenderingPipeline",!0,e,[r]),d.samples=4,d.depthOfField.lensSize=512,d.depthOfField.fStop=.25,d.depthOfField.focusDistance=55e3,d}i(nr,"createDefaultRenderingPipeline");function ct(){return d?{samples:d.samples,fxaaEnabled:d.fxaaEnabled,imageProcessingEnabled:d.imageProcessingEnabled,exposure:d.imageProcessing?.exposure,contrast:d.imageProcessing?.contrast,fromLinearSpace:d.imageProcessing?.fromLinearSpace,toneMappingEnabled:d.imageProcessing?.toneMappingEnabled,toneMappingType:d.imageProcessing?.toneMappingType,ditheringEnabled:d.imageProcessing?.ditheringEnabled,ditheringIntensity:d.imageProcessing?.ditheringIntensity,bloomEnabled:d.bloomEnabled,bloomThreshold:d.bloomThreshold,bloomWeight:d.bloomWeight,bloomScale:d.bloomScale,bloomKernel:d.bloomKernel,sharpenEnabled:d.sharpenEnabled,sharpenEdgeAmount:d.sharpen.edgeAmount,sharpenColorAmount:d.sharpen.colorAmount,grainEnabled:d.grainEnabled,grainIntensity:d.grain.intensity,grainAnimated:d.grain.animated,depthOfFieldEnabled:d.depthOfFieldEnabled,depthOfFieldBlurLevel:d.depthOfFieldBlurLevel,lensSize:d.depthOfField.lensSize,fStop:d.depthOfField.fStop,focusDistance:d.depthOfField.focusDistance,focalLength:d.depthOfField.focalLength,vignetteEnabled:d.imageProcessing?.vignetteEnabled,vignetteColor:d.imageProcessing?.vignetteColor.asArray(),vignetteWeight:d.imageProcessing?.vignetteWeight,chromaticAberrationEnabled:d.chromaticAberrationEnabled,aberrationAmount:d.chromaticAberration.aberrationAmount,radialIntensity:d.chromaticAberration.radialIntensity,direction:d.chromaticAberration.direction.asArray(),centerPosition:d.chromaticAberration.centerPosition.asArray(),glowLayerEnabled:d.glowLayerEnabled,glowLayerIntensity:d.glowLayer?.intensity,glowLayerBlurKernelSize:d.glowLayer?.blurKernelSize,colorGradingEnabled:d.imageProcessing.colorGradingEnabled,colorGradingTexture:d.imageProcessing.colorGradingTexture?.serialize(),colorGradingWithGreenDepth:d.imageProcessing.imageProcessingConfiguration.colorGradingWithGreenDepth,colorCurvesEnabled:d.imageProcessing.colorCurvesEnabled,globalHue:d.imageProcessing.colorCurves?.globalHue,globalDensity:d.imageProcessing.colorCurves?.globalDensity,globalExposure:d.imageProcessing.colorCurves?.globalExposure,globalSaturation:d.imageProcessing.colorCurves?.globalSaturation,highlightsHue:d.imageProcessing.colorCurves?.highlightsHue,highlightsDensity:d.imageProcessing.colorCurves?.highlightsDensity,highlightsExposure:d.imageProcessing.colorCurves?.highlightsExposure,highlightsSaturation:d.imageProcessing.colorCurves?.highlightsSaturation,midtonesHue:d.imageProcessing.colorCurves?.midtonesHue,midtonesDensity:d.imageProcessing.colorCurves?.midtonesDensity,midtonesExposure:d.imageProcessing.colorCurves?.midtonesExposure,midtonesSaturation:d.imageProcessing.colorCurves?.midtonesSaturation,shadowsHue:d.imageProcessing.colorCurves?.shadowsHue,shadowsDensity:d.imageProcessing.colorCurves?.shadowsDensity,shadowsExposure:d.imageProcessing.colorCurves?.shadowsExposure,shadowsSaturation:d.imageProcessing.colorCurves?.shadowsSaturation}:null}i(ct,"serializeDefaultRenderingPipeline");function pt(e,r,t,n){if(d)return d;let o=nr(e,r);if(o.samples=t.samples,o.fxaaEnabled=t.fxaaEnabled,o.imageProcessingEnabled=t.imageProcessingEnabled,o.imageProcessing){if(o.imageProcessing.exposure=t.exposure,o.imageProcessing.contrast=t.contrast,o.imageProcessing.fromLinearSpace=t.fromLinearSpace,o.imageProcessing.toneMappingEnabled=t.toneMappingEnabled,o.imageProcessing.toneMappingType=t.toneMappingType,o.imageProcessing.ditheringEnabled=t.ditheringEnabled,o.imageProcessing.ditheringIntensity=t.ditheringIntensity,o.imageProcessing.vignetteEnabled=t.vignetteEnabled??!1,o.imageProcessing.vignetteColor=Xt.Color4.FromArray(t.vignetteColor??[0,0,0]),o.imageProcessing.vignetteWeight=t.vignetteWeight??.3,o.imageProcessing.colorGradingEnabled=t.colorGradingEnabled??!1,o.imageProcessing.imageProcessingConfiguration.colorGradingWithGreenDepth=t.colorGradingWithGreenDepth??!0,t.colorGradingTexture){let s=null;if(t.colorGradingTexture.customType==="BABYLON.ColorGradingTexture"){let a=n+t.colorGradingTexture.name;s=new tr.ColorGradingTexture(a,e),s.level=t.colorGradingTexture.level}else{let a=er.Texture.Parse(t.colorGradingTexture,e,n);ce(a)&&(s=a)}o.imageProcessing.colorGradingTexture=s}o.imageProcessing.colorCurvesEnabled=t.colorCurvesEnabled??!1,o.imageProcessing.colorCurves&&(o.imageProcessing.colorCurves.globalHue=t.globalHue??30,o.imageProcessing.colorCurves.globalDensity=t.globalDensity??0,o.imageProcessing.colorCurves.globalExposure=t.globalExposure??0,o.imageProcessing.colorCurves.globalSaturation=t.globalSaturation??0,o.imageProcessing.colorCurves.highlightsHue=t.highlightsHue??30,o.imageProcessing.colorCurves.highlightsDensity=t.highlightsDensity??0,o.imageProcessing.colorCurves.highlightsExposure=t.highlightsExposure??0,o.imageProcessing.colorCurves.highlightsSaturation=t.highlightsSaturation??0,o.imageProcessing.colorCurves.midtonesHue=t.midtonesHue??30,o.imageProcessing.colorCurves.midtonesDensity=t.midtonesDensity??0,o.imageProcessing.colorCurves.midtonesExposure=t.midtonesExposure??0,o.imageProcessing.colorCurves.midtonesSaturation=t.midtonesSaturation??0,o.imageProcessing.colorCurves.shadowsHue=t.shadowsHue??30,o.imageProcessing.colorCurves.shadowsDensity=t.shadowsDensity??0,o.imageProcessing.colorCurves.shadowsExposure=t.shadowsExposure??0,o.imageProcessing.colorCurves.shadowsSaturation=t.shadowsSaturation??0)}return o.bloomEnabled=t.bloomEnabled,o.bloomThreshold=t.bloomThreshold,o.bloomWeight=t.bloomWeight,o.bloomScale=t.bloomScale,o.bloomKernel=t.bloomKernel,o.sharpenEnabled=t.sharpenEnabled,o.sharpen.edgeAmount=t.sharpenEdgeAmount,o.sharpen.colorAmount=t.sharpenColorAmount,o.grainEnabled=t.grainEnabled,o.grain.intensity=t.grainIntensity,o.grain.animated=t.grainAnimated,o.depthOfFieldEnabled=t.depthOfFieldEnabled,o.depthOfFieldBlurLevel=t.depthOfFieldBlurLevel,o.depthOfField.lensSize=t.lensSize,o.depthOfField.fStop=t.fStop,o.depthOfField.focusDistance=t.focusDistance,o.depthOfField.focalLength=t.focalLength,o.chromaticAberrationEnabled=t.chromaticAberrationEnabled??!1,o.chromaticAberration.aberrationAmount=t.aberrationAmount??10,o.chromaticAberration.radialIntensity=t.radialIntensity??1,o.chromaticAberration.direction=at.Vector2.FromArray(t.direction??[0,0]),o.chromaticAberration.centerPosition=at.Vector2.FromArray(t.centerPosition??[0,0]),o.glowLayerEnabled=t.glowLayerEnabled??!1,o.glowLayer&&(o.glowLayer.intensity=t.glowLayerIntensity??1,o.glowLayer.blurKernelSize=t.glowLayerBlurKernelSize??32),o}i(pt,"parseDefaultRenderingPipeline");function Jn(e){q.set(e,tt()),W.set(e,Qe()),Y.set(e,He()),J.set(e,it()),Z.set(e,ct()),H.set(e,Ze())}i(Jn,"saveRenderingConfigurationForCamera");function mt(e,r,t){et(),Ue(e.getScene()),Ye(),ot(),lt(),Je();let n=q.get(e);n&&!t?.ssao2Disabled&&rt(e.getScene(),e,n);let o=W.get(e);o&&!t?.vlsDisabled&&We(e.getScene(),o);let s=Y.get(e);s&&!t?.ssrDisabled&&qe(e.getScene(),e,s);let a=J.get(e);a&&!t?.motionBlurDisabled&&st(e.getScene(),e,a);let c=Z.get(e);c&&!t?.defaultPipelineDisabled&&pt(e.getScene(),e,c,r);let l=H.get(e);l&&!t?.taaDisabled&&Xe(e.getScene(),e,l)}i(mt,"applyRenderingConfigurationForCamera");var me=require("babylonjs"),or=require("babylonjs");function ir(e){let r=e.metadata?.physicsAggregate;if(!r)return;let t;D(e)?t=e:le(e)&&(t=e.sourceMesh);let n=new or.PhysicsAggregate(e,r.shape.type,{mesh:t,mass:r.massProperties.mass});n.body.setMassProperties({mass:r.massProperties.mass,inertia:r.massProperties.inertia?me.Vector3.FromArray(r.massProperties.inertia):void 0,centerOfMass:r.massProperties.centerOfMass?me.Vector3.FromArray(r.massProperties.centerOfMass):void 0,inertiaOrientation:r.massProperties.inertiaOrientation?me.Quaternion.FromArray(r.massProperties.inertiaOrientation):void 0}),n.shape.density=r.shape.density,n.body.setMotionType(r.body.motionType),n.shape.material=r.material,e.physicsAggregate=n,e.metadata.physicsAggregate=void 0}i(ir,"configurePhysicsAggregate");function sr(e,r){(Array.isArray(r)?r:[]).forEach(n=>{let o=e.getCameraById(n.cameraId);o&&(n.ssao2RenderingPipeline&&q.set(o,n.ssao2RenderingPipeline),n.vlsPostProcess&&W.set(o,n.vlsPostProcess),n.ssrRenderingPipeline&&Y.set(o,n.ssrRenderingPipeline),n.motionBlurPostProcess&&J.set(o,n.motionBlurPostProcess),n.defaultRenderingPipeline&&Z.set(o,n.defaultRenderingPipeline),n.taaRenderingPipeline&&H.set(o,n.taaRenderingPipeline))})}i(sr,"applyRenderingConfigurations");var ar=require("babylonjs");function X(e,r,t){return new Promise((n,o)=>{let s=new ar.WebRequest;s.open("GET",e),s.responseType=r,s.send(),s.addEventListener("progress",a=>{t?.({total:a.total,loaded:a.loaded})}),s.addEventListener("load",()=>{n(r==="text"?s.responseText:s.response)}),s.addEventListener("error",a=>o(a))})}i(X,"loadFile");async function N(e,r){let t=await X(e,"text",r);return JSON.parse(t)}i(N,"loadJsonFile");function ut(e,r){let t=r.getNodeByName(e);if(t)return t;let n=r.lights.filter(o=>Ae(o));for(let o of n){let s=o.lights.find(a=>a.name===e);if(s)return s}return null}i(ut,"getNodeByName");function ee(e,r){let t=r.getNodeById(e);if(t)return t;let n=r.lights.filter(o=>Ae(o));for(let o of n){let s=o.lights.find(a=>a.id===e);if(s)return s}return null}i(ee,"getNodeById");var U=require("babylonjs"),lr=require("babylonjs");function dt(e){let r=lr.Vector3.FromArray(e);return r.equals(U.Axis.X)?U.Axis.X:r.equals(U.Axis.Y)?U.Axis.Y:r.equals(U.Axis.Z)?U.Axis.Z:r}i(dt,"parseAxis");function cr(e){return e.runtimeConfiguration.forEach(r=>{r.rotationAxis&&(r.rotationAxis=dt(r.rotationAxis)),r.boneOffsetAxis&&(r.boneOffsetAxis=dt(r.boneOffsetAxis))}),e}i(cr,"parseRagdollConfiguration");function ft(e){let r={rootNodeId:e.rootNodeId,skeletonName:e.skeletonName,scalingFactor:e.scalingFactor,runtimeConfiguration:e.runtimeConfiguration.map(t=>({name:t.name,bones:t.bones,width:t.width,depth:t.depth,height:t.height,size:t.size,joint:t.joint,min:t.min,max:t.max,boxOffset:t.boxOffset,rotationAxis:t.rotationAxis?.slice(),boneOffsetAxis:t.boneOffsetAxis?.slice()}))};return cr(r)}i(ft,"copyAndParseRagdollConfiguration");function Zn(e){return new Promise(r=>{setTimeout(()=>r(),e)})}i(Zn,"waitMs");async function gt(e){for(;!e();)await Zn(150)}i(gt,"waitUntil");function yt(e){return e&&JSON.parse(JSON.stringify(e))}i(yt,"cloneJSObject");var ht=require("babylonjs"),gr=require("babylonjs"),Ce=require("babylonjs"),yr=require("babylonjs"),Sr=require("babylonjs"),hr=require("babylonjs"),z=require("babylonjs"),pr=!1,mr=null,te=[],St=new Map;function Xn(e,r){let t=(0,z._GetAudioEngine)(null);return new hr._WebAudioStaticSound(e,t,r)}i(Xn,"createSoundInstance");function ur(e){if(mr?.remove(),!te.length)return;let r=ht.Vector3.Zero();mr=e.onBeforeRenderObservable.add(()=>{let t=(0,z._GetAudioEngine)(null).listener.attachedNode;t&&(t.getWorldMatrix().getTranslationToRef(r),te.forEach(n=>{n.isEnabled(!1)&&n.autoUpdateSpatial&&n.sound?._isSpatial&&n.isPlaying()&&e.activeCamera&&ht.Vector3.Distance(r,n.getAbsolutePosition())<=n.sound.spatial.maxDistance&&n.sound.spatial.update()}))})}i(ur,"registerUpdateSoundsObserver");function dr(e){e.sound?.onDisposeObservable.addOnce(()=>{let r=te.indexOf(e);r!==-1&&te.splice(r,1)}),e.onDisposeObservable.addOnce(()=>{e.sound?.dispose()})}i(dr,"registerSoundNodeEvents");function eo(e,r){return new Promise(async(t,n)=>{if(!e.offlineProvider||!gr.Database.IDBStorageEnabled)return(0,z.CreateSoundBufferAsync)(r).then(o=>t(o)).catch(o=>n(o));e.offlineProvider.loadFile(r,o=>{(0,z.CreateSoundBufferAsync)(o).then(s=>t(s)).catch(s=>n(s))},void 0,()=>{n(null)},!0)})}i(eo,"loadSoundBuffer");function bt(e,r){if(!e.soundRelativePath||!e.sound)return;r.onSoundLoadedObservable=new yr.Observable;let t=Xn(e.soundRelativePath,{spatialAutoUpdate:!1});t._initAsync(e.sound.buffer,{spatialAutoUpdate:!0}).then(()=>{t.volume=e.volume,t._isSpatial=e.sound._isSpatial,t._isSpatial&&(t.spatial.attach(r),t.spatial.maxDistance=e.sound.spatial.maxDistance,t.spatial.panningModel=e.sound.spatial.panningModel,t.spatial.distanceModel=e.sound.spatial.distanceModel),r.sound=t,r.soundRelativePath=e.soundRelativePath,r.autoUpdateSpatial=e.autoUpdateSpatial,te.push(r),ur(r.getScene()),r.onSoundLoadedObservable.notifyObservers(r)}),dr(r),fr(r,t)}i(bt,"configureSourceNodeFrom");function fr(e,r){Object.defineProperty(e,"volume",{get:i(()=>r.volume,"get"),set:i(t=>{r.volume=t},"set")}),Object.defineProperty(e,"playbackRate",{get:i(()=>r.playbackRate,"get"),set:i(t=>{r.playbackRate=t},"set")}),e.isPaused=()=>r.state===Ce.SoundState.Paused,e.isPlaying=()=>r.state===Ce.SoundState.Started,e.isStopped=()=>r.state===Ce.SoundState.Stopped,e.pause=()=>r.pause(),e.resume=()=>r.resume(),e.stop=t=>r.stop(t),e.play=t=>r.play(t),e.setVolume=(t,n)=>r.setVolume(t,n),e.getClassName=()=>"SoundNode",e.setSoundSpatial=t=>new Promise(n=>{r._isSpatial=t,setTimeout(()=>{t&&r.spatial.attach(e),n()})}),e.cloneAsync=async(t,n,o)=>new Promise(s=>{let a=e.clone(t,n,o);bt(e,a),a.onSoundLoadedObservable.addOnce(()=>{setTimeout(()=>s(a))})})}i(fr,"configureSoundNodePrototype");function br(){pr||(pr=!0,(0,Sr.AddParser)("SoundNode",(e,r,t,n)=>{e.transformNodes?.forEach(o=>{if(!o.isSoundNode)return;let s=t.transformNodes?.find(a=>a.id===o.id);if(s&&o.soundRelativePath){let a=`${n}${o.soundRelativePath}`;r.addPendingData(a),St.has(a)||St.set(a,eo(r,a)),St.get(a).then(l=>{(0,z.CreateSoundAsync)(o.soundRelativePath,l,{spatialAutoUpdate:!1}).then(p=>{if(r.removePendingData(a),s.isDisposed())return p.dispose();p.volume=o.volume,p._isSpatial=o.isSpatial,o.isSpatial&&(p.spatial.attach(s),p.spatial.maxDistance=o.maxDistance,p.spatial.panningModel=o.panningModel,p.spatial.distanceModel=o.distanceModel),s.sound=p,s.soundRelativePath=o.soundRelativePath,s.autoUpdateSpatial=o.autoUpdateSpatial,te.push(s),dr(s),fr(s,p),ur(r)})})}})}))}i(br,"registerAudioParser");function re(e){let r=new Set;[...e.transformNodes,...e.meshes].forEach(n=>{if(n.metadata?.isStaticGroup){let o=n.getDescendants(!1);o.push(n),o.forEach(s=>{if(($(s)||k(s)&&!s.isWorldMatrixFrozen)&&s.freezeWorldMatrix(),$(s)){let a=s.material;a&&!a.isFrozen&&!r.has(a)&&(r.add(a),a.onBindObservable.addOnce(()=>{a.freeze()}))}})}})}i(re,"configureTransformNodes");var ue=class{constructor(r,t){this.entries=r;this.namingId=t}entries;namingId;static{i(this,"AdvancedAssetContainerInstantiatedEntries")}get rootNodes(){return this.entries.rootNodes}get skeletons(){return this.entries.skeletons}get animationGroups(){return this.entries.animationGroups}dispose(){this.entries.dispose()}getRootNodeByName(r){let t=`${r}-${this.namingId}`;return this.entries.rootNodes.find(n=>n.name===t)??null}getNodeByName(r){let t=`${r}-${this.namingId}`;for(let n of this.entries.rootNodes){let o=this._recursivelyGetNodeByName(t,n);if(o)return o}return null}_recursivelyGetNodeByName(r,t){if(t.name===r)return t;for(let n of t.getDescendants(!0)){let o=this._recursivelyGetNodeByName(r,n);if(o)return o}return null}getScriptByClassByObjectName(r,t){let n=this.getNodeByName(r);if(n){let o=ne(n,t);if(o?.length===1)return o[0]}return null}};var Pt=require("babylonjs"),de=class{static{i(this,"AdvancedAssetContainer")}container;_rootUrl;_scriptsMap;_originalDescendants=[];_nodesMap=new Map;_animationGroupsMap=new Map;constructor(r,t,n){this.container=r,this._rootUrl=t,this._scriptsMap=n,r.populateRootNodes(),r.rootNodes.forEach(o=>{this._originalDescendants.push(o,...o.getDescendants(!1))}),r.animationGroups.forEach(o=>{this._animationGroupsMap.set(o.name,o)}),this._originalDescendants.forEach(o=>{this._nodesMap.set(o,{node:o,metadata:yt(o.metadata)})})}removeDefault(){this.container.getNodes().forEach(r=>{R.get(r)?.forEach(n=>{Ie(r,n)})}),this.container.removeAllFromScene()}getRootNodeByName(r){return this.container.rootNodes.find(t=>t.name===r)??null}getScriptByClassByObjectName(r,t){let n=this.container.getNodes();for(let o of n)if(o.name===r){let s=ne(o,t);if(s?.length===1)return s[0]}return null}instantiate(r){let t=Pt.Tools.RandomId(),n=i(l=>l,"nameFunction"),o=this.container.instantiateModelsToScene(n,!1,{...r,predicate:i(l=>(l.name=`${l.name}@editor-tools@${t}_${l.id}`,r?.predicate?.(l)??!0),"predicate")}),s=new ue(o,t);[...this.container.transformNodes,...this.container.meshes,...this.container.lights,...this.container.cameras,...this.container.animationGroups,...this.container.skeletons].forEach(l=>{let p=l.name.split("@editor-tools@");l.name=p[0]}),o.animationGroups.forEach(l=>{let p=l.name.split("@editor-tools@");l.name=`${p[0]}-${t}`});let c=[];return o.rootNodes.forEach(l=>{c.push(l,...l.getDescendants(!1))}),c.forEach(l=>{let p=l.name.split("@editor-tools@"),m=p[1].split("_").pop();l.name=`${p[0]}-${t}`;let u=this._originalDescendants.find(f=>f.id===m);j(u)&&k(l)&&bt(u,l),l.id=Pt.Tools.RandomId(),l.metadata=yt(this._nodesMap.get(u).metadata),l.metadata??={},l.metadata.originalId=m,c.forEach(f=>{f.metadata.scripts?.forEach(g=>{Object.keys(g.values||{}).forEach(y=>{let P=g.values[y];if(P.type==="entity"){P.value===m&&(P.value=l.id),P.value===u.name&&(P.value=l.name);let A=this._animationGroupsMap.get(P.value);A&&(P.value=`${A.name}-${t}`)}})})})}),c.forEach(l=>{F(this.container.scene,l,this._scriptsMap,this._rootUrl)}),re(this.container.scene),s}};var Pr=require("babylonjs"),xr=require("babylonjs");async function Ar(e,r,t){let n=t.iblIntensity,o=t.environmentIntensity,a=e.split("/").pop().replace(".scene",".babylon"),c=await(0,xr.LoadAssetContainerAsync)(a,t,{rootUrl:r,pluginExtension:".babylon"});return Pr.SceneLoaderFlags.ForceFullSceneLoadingForIncremental&&t.meshes.forEach(l=>D(l)&&l._checkDelayState()),c.addAllToScene(),t.iblIntensity=n,t.environmentIntensity=o,re(t),c}i(Ar,"preloadSceneScriptAsset");async function vr(e,r){return N(`${r}${e}`)}i(vr,"preloadCommonScriptAsset");var O=new Map,fe=new Map;function to(e,r){fe.has(e)&&console.warn(`A parser for the extension '${e}' was already registered. It will be overwritten.`),fe.set(e,r)}i(to,"registerScriptAssetParser");async function xt(e,r,t){[r,...r.transformNodes,...r.meshes,...r.lights,...r.cameras].filter(c=>c.metadata?.scripts?.length).map(c=>c.metadata.scripts).flat().forEach(c=>{if(t[c.key]?.default?._SceneAssets?.forEach(p=>{O.get(p.sceneName)||O.set(p.sceneName,null)}),c.values)for(let p in c.values){if(!c.values.hasOwnProperty(p))continue;let m=c.values[p];m.type==="asset"&&m.value&&!O.get(m.value)&&O.set(m.value,null)}});let s=0;for(let c of O.values())c===null&&++s;if(s===0)return s;let a=[];return O.forEach((c,l)=>{O.get(l)||a.push(new Promise(async p=>{try{let m=l.split(".").pop();switch(m){case"scene":let u=await Ar(l,e,r);r.onDisposeObservable.addOnce(()=>{u.dispose(),O.delete(l)}),O.set(l,new de(u,e,t));break;default:if(fe.has(m)){let f=fe.get(m);O.set(l,await f({key:l,rootUrl:e,scene:r}));break}else O.set(l,await vr(l,e));break}}catch(m){console.error(m)}p()}))}),await Promise.all(a),s}i(xt,"_preloadScriptsAssets");var Cr=require("babylonjs"),Ee=require("babylonjs"),Ir=require("babylonjs"),Te=require("babylonjs"),Er=require("babylonjs"),Tr=require("babylonjs-gui");function At(e,r,t,n,o){let s=n.constructor;if(!s)return;s._NodesFromScene?.forEach(l=>{n[l.propertyKey.toString()]=ut(l.nodeName,e)}),s._ComponentsFromScene?.length&&e.getEngine().onBeginFrameObservable.addOnce(()=>{s._ComponentsFromScene?.forEach(l=>{let p=[];if([e,...e.transformNodes,...e.meshes,...e.lights,...e.cameras].forEach(u=>{let f=vt(u,l.componentConstructor);f&&p.push(f)}),p.length>1)throw new Error(`Multiple components of type ${s._ComponentsFromScene[0].componentConstructor.name} found in scene for property "${s._ComponentsFromScene[0].propertyKey.toString()}".`);n[l.propertyKey.toString()]=p[0]??null})}),s._NodesFromDescendants?.forEach(l=>{let p=r.getDescendants?.(l.directDescendantsOnly,m=>m.name===l.nodeName)[0];n[l.propertyKey.toString()]=p??null}),s._AnimationGroups?.forEach(l=>{n[l.propertyKey.toString()]=e.getAnimationGroupByName(l.animationGroupName)}),s._SoundsFromScene?.forEach(l=>{let p=ut(l.soundName,e);p&&j(p)&&(n[l.propertyKey.toString()]=p??null)}),(s._GuiFromAsset??[]).map(async l=>{let p=`${o}assets/${l.pathInAssets}`;try{let m=await N(p),u=Tr.AdvancedDynamicTexture.CreateFullscreenUI(m.name,!0,e);u.parseSerializedObject(m.content,!1),n[l.propertyKey.toString()]=u,l.onGuiCreated?.(n,u)}catch(m){throw console.error(`Failed to load GUI from asset: ${p}`),m}}),s._ParticleSystemsFromScene?.forEach(l=>{let p=e.particleSystems?.find(m=>m.name!==l.particleSystemName?!1:l.directDescendantsOnly?m.emitter===r:m);n[l.propertyKey.toString()]=p}),(s._VisibleInInspector??[]).forEach(l=>{let p=l.propertyKey.toString(),m=t.values;if(!m)throw new Error(`No values found for script with key "${t.key}".`);if(m.hasOwnProperty(p)&&m[p].hasOwnProperty("value")){let u=m[p].value;switch(l.configuration.type){case"number":case"boolean":case"keymap":case"string":n[p]=u;break;case"vector2":n[p]=Te.Vector2.FromArray(u);break;case"vector3":n[p]=Te.Vector3.FromArray(u);break;case"color3":n[p]=Ee.Color3.FromArray(u);break;case"color4":n[p]=Ee.Color4.FromArray(u);break;case"entity":switch(l.configuration.entityType){case"node":case"sound":n[p]=ee(u,e)??null;break;case"animationGroup":n[p]=e.getAnimationGroupByName(u)??null;break;case"particleSystem":n[p]=e.particleSystems?.find(g=>g.id===u)??null;break}break;case"texture":u&&(n[p]=Ir.Texture.Parse(u,e,o));break;case"asset":if(u){let g=l.configuration.assetType,S=O.get(u);switch(g){case"json":case"gui":case"scene":case"navmesh":case"cinematic":n[p]=S;break;case"ragdoll":n[p]=ft(S);break;case"nodeParticleSystemSet":let y=Er.NodeParticleSystemSet.Parse(S);n[p]=y;break;case"material":n[p]=Cr.Material.Parse(S,e,o);break}}}}});let a=null,c=null;if(s._PointerEvents?.length){if(s._PointerEvents.find(m=>m.options.mode==="attachedMeshOnly")&&!$(r))throw new Error('@onPointerEvent with mode "attachedMeshOnly" can only be used on scripts attached to meshes (extends AbstractMesh).');if(s._PointerEvents.find(m=>m.options.mode!=="global")&&!Q(r))throw new Error('@onPointerEvent with mode different from "global" can be used only on scripts attached to Node: Mesh, Light, Camera, TransformNode.');a=e.onPointerObservable.add(m=>{let u=null;s._PointerEvents.forEach(f=>{if(!f.eventTypes.includes(m.type))return;let g=f.propertyKey.toString();if(f.options.mode==="global")return n[g]?.(m);u=m.pickInfo,u||(u=e.pick(e.pointerX,e.pointerY,y=>y.isVisible&&y.isPickable&&y.isEnabled(!0)&&!y._masterMesh,!1));let S=u.pickedMesh;if(S&&(f.options.mode==="attachedMeshOnly"&&S===r||f.options.mode==="includeDescendants"&&Q(r)&&[r,...r.getDescendants(!1)].find(A=>A===S)))return n[g]?.(m)})})}if(s._KeyboardEvents?.length&&(c=e.onKeyboardObservable.add(l=>{s._KeyboardEvents.forEach(p=>{p.eventTypes.includes(l.type)&&n[p.propertyKey.toString()]?.(l)})})),s._SpritesFromSpriteManager?.length){let l=r;if(!k(l)||!l.isSpriteManager)return console.error("@spriteFromSpriteManager decorator can only be used on SpriteManagerNode.");if(!l.spriteManager)return console.error(`SpriteManagerNode "${l.name}" has no sprite manager assigned.`);s._SpritesFromSpriteManager?.forEach(p=>{let m=l.spriteManager?.sprites.find(u=>u.name===p.spriteName)||null;n[p.propertyKey.toString()]=m})}if(s._AnimationsFromSprite?.length){if(!Be(r))return console.error("@animationFromSprite decorator can only be used in scripts attached on Sprite.");let l=r.metadata?.spriteAnimations;if(!l?.length)return console.error(`Sprite "${r.name}" has no sprite animations assigned.`);s._AnimationsFromSprite.forEach(p=>{let m=l.find(u=>u.name===p.animationName);m?n[p.propertyKey.toString()]=m??null:console.warn(`Sprite animation named "${p.animationName}" not found on sprite "${r.name}".`)})}return s._SceneAssets?.forEach(l=>{n[l.propertyKey.toString()]=O.get(l.sceneName)}),{observers:{pointerObserver:a,keyboardObserver:c}}}i(At,"applyDecorators");function F(e,r,t,n){r.metadata?.scripts&&(r.metadata.scripts?.forEach(o=>{if(!o.enabled)return;let s=t[o.key];if(!s)return;let a=s,c={};if(s.default){a=new s.default(r);let l=At(e,r,o,a,n);Object.assign(c,l?.observers??{})}a.onStart&&(c.onStartObserver=e.onBeforeRenderObservable.addOnce(()=>a.onStart(r))),a.onUpdate&&(c.onUpdateObserver=e.onBeforeRenderObservable.add(()=>a.onUpdate(r))),Ct(r,a,o.key,c)}),r.metadata.scripts=void 0)}i(F,"_applyScriptsForObject");function ro(e,r,t){if(t??=e.getScene?.(),!t)throw new Error("Cannot apply script on object: no scene available.");let n=new r(e),o={};return At(t,e,{values:{}},n,""),n.onStart&&(o.onStartObserver=t.onBeforeRenderObservable.addOnce(()=>n.onStart())),n.onUpdate&&t.onBeforeRenderObservable.add(()=>n.onUpdate()),Ct(e,n,"runtime",o),n}i(ro,"applyScriptOnObject");var R=new Map;function Ct(e,r,t,n){let o={key:t,observers:n,instance:r};R.has(e)?R.get(e).push(o):R.set(e,[o]),(Q(e)||Ve(e)||_e(e)||j(e))&&e.onDisposeObservable.addOnce((()=>{R.get(e)?.slice()?.forEach(a=>{Ie(e,a)}),R.delete(e)}))}i(Ct,"_registerScriptInstance");function Ie(e,r){r.observers.onStartObserver?.remove(),r.observers.onUpdateObserver?.remove(),r.observers.pointerObserver?.remove(),r.observers.keyboardObserver?.remove();try{r.instance.onStop?.(e)}catch(o){console.error(`Failed to call onStop for script ${r.key} on object ${e}`,o)}let t=R.get(e),n=t?.indexOf(r)??-1;n!==-1&&t?.splice(n,1)}i(Ie,"_removeRegisteredScriptInstance");function ne(e,r){return R.get(e)?.filter(o=>o.instance.constructor===r)?.map(o=>o.instance)??null}i(ne,"getAllScriptsByClassForObject");function vt(e,r){return ne(e,r)?.[0]??null}i(vt,"getScriptByClassForObject");var Or=!1;function no(e){Or=e}i(no,"setUseKtx2CompressedTextures");function ge(){return Or}i(ge,"isUsingKtx2CompressedTextures");function Oe(e){return`${e.substring(0,e.lastIndexOf("."))}.ktx2`}i(Oe,"_getKtx2TextureName");function oo(e){e.setCompressedTextureExclusions([".env",".hdr",".dds"]),e.setTextureFormatToUse(["-dxt.ktx","-astc.ktx","-pvrtc.ktx","-etc1.ktx","-etc2.ktx"])}i(oo,"configureEngineToUseCompressedTextures");function De(e,r){e._excludedCompressedTextures&&!e._excludedCompressedTextures?.includes(r)&&e._excludedCompressedTextures?.push(r)}i(De,"addExcludedCompressedTexture");function io(e,r,t){r.loadingTexturesQuality!==e&&(r.loadingTexturesQuality=e,r.textures.forEach(n=>{if(!ce(n)||!n.url)return;let o=Me(n,r);!o||n.url.includes(o)||n.updateURL(t+o)}))}i(io,"applyTexturesQuality");function Me(e,r){if(r.loadingTexturesQuality==="high"||!e.metadata?.baseSize)return e.name;let t=e.metadata.baseSize.width,n=e.metadata.baseSize.height,o=t===M(t)||n===M(n),s="";switch(r.loadingTexturesQuality){case"medium":let f=t*.66>>0,g=n*.66>>0;o&&(f=M(f),g=M(g)),s=`_${f}_${g}`;break;case"low":case"very-low":let S=t*.33>>0,y=n*.33>>0;o&&(S=M(S),y=M(y)),s=`_${S}_${y}`;break}let a=e.name;if(!a||!s)return e.name;let c=a.split("/"),l=c.pop();if(!l)return e.name;let p=l.split(".").pop(),u=`${l.replace(`.${p}`,"")}${s}.${p}`;return c.push(u),c.join("/")}i(Me,"getTextureUrl");var It=require("babylonjs"),Dr=!1;function Mr(){if(Dr)return;Dr=!0;let e=It.SerializationHelper._TextureParser;It.SerializationHelper._TextureParser=(r,t,n)=>{ge()&&(r.name&&(r.name=Oe(r.name)),r.url&&(r.url=Oe(r.url)));let o=Me(r,t);if(!o)return e(r,t,n);let s=r.name;r.name=o;let a=e(r,t,n);return a&&(a.name=s),a}}i(Mr,"registerTextureParser");var Nr=require("babylonjs"),Fr=require("babylonjs"),we=require("babylonjs"),Rr=require("babylonjs"),wr=!1;function _r(){if(wr)return;wr=!0,(0,Rr.RegisterShadowGeneratorSceneComponent)(Fr.ShadowGenerator);let e=(0,we.GetParser)(Nr.SceneComponentConstants.NAME_SHADOWGENERATOR);(0,we.AddParser)("ShadowGeneratorEditorPlugin",(r,t,n,o)=>{let s=new Map;r.shadowGenerators?.forEach(a=>{if(s.set(a.id,a.mapSize),t.loadingShadowsQuality!=="high"){switch(t.loadingShadowsQuality){case"medium":a.mapSize=a.mapSize*.5;break;case"low":a.mapSize=a.mapSize*.25;break;case"very-low":a.mapSize=a.mapSize*.125;break}a.mapSize=Math.max(128,M(a.mapSize))}}),e?.(r,t,n,o),t.lights.forEach(a=>{let c=a.getShadowGenerator();if(c?.getShadowMap()){let p=c.id,m=s.get(p);m&&(c.originalMapSize=m)}})})}i(_r,"registerShadowGeneratorParser");var Br=require("babylonjs"),Gr=require("babylonjs"),Kr=require("babylonjs"),Et=require("babylonjs"),kr=require("babylonjs");function Lr(e,r){r?.fogEnabled!==void 0&&(e.fogEnabled=r?.fogEnabled),r?.blendMode!==void 0&&(e.blendMode=r?.blendMode),r?.disableDepthWrite!==void 0&&(e.disableDepthWrite=r?.disableDepthWrite),r?.pixelPerfect!==void 0&&(e.pixelPerfect=r?.pixelPerfect),r?.useLogarithmicDepth!==void 0&&(e.useLogarithmicDepth=r?.useLogarithmicDepth),r?.metadata!==void 0&&(e.metadata=r?.metadata);for(let t of r?.sprites??[]){let n=Gr.Sprite.Parse(t,e);n.uniqueId=t.uniqueId,n.metadata=t.metadata}}i(Lr,"parseSerializedSpriteManager");var Vr=!1;function zr(){Vr||(Vr=!0,(0,kr.AddParser)("SpriteManagerNode",(e,r,t,n)=>{e.transformNodes?.forEach(o=>{if(!o.isSpriteManager)return;let s=t.transformNodes?.find(c=>c.id===o.id);if(!s)return;let a=r.getEngine();if(s.isSpriteManager=o.isSpriteManager,o.atlasJsonRelativePath){let c=`${n}${o.atlasJsonRelativePath}`;r.addPendingData(c);let l=new Kr.WebRequest;l.open("GET",c),l.send(),l.addEventListener("load",()=>{r.removePendingData(c);let p=JSON.parse(l.responseText),m=`${Br.Tools.GetFolderPath(c)}${p.meta.image}`;De(a,m);let u=new Et.SpriteManager(s.name,m,1e3,64,r,void 0,void 0,!0,p);s.spriteManager=u,s.getClassName=()=>"SpriteManagerNode",o.spriteManager&&Lr(u,o.spriteManager)})}else if(o.spriteManager?.textureUrl){De(a,o.spriteManager.textureUrl);let c=`${n}${o.spriteManager.textureUrl}`,l=new Et.SpriteManager(s.name,c,1e3,{width:o.spriteManager.cellWidth,height:o.spriteManager.cellHeight},r,void 0,void 0,!1);s.spriteManager=l,s.getClassName=()=>"SpriteManagerNode",o.spriteManager&&Lr(l,o.spriteManager)}})}))}i(zr,"registerSpriteManagerParser");var jr=require("babylonjs"),Ur=require("babylonjs"),$r=!1;function Qr(){$r||($r=!0,(0,Ur.AddParser)("MorphTargetManagerEditorPlugin",(e,r,t,n)=>{e.morphTargetManagers.forEach(o=>{let a=t.meshes.find(p=>p.id===o.meshId)?.morphTargetManager;if(!a||o.targets.find(p=>!p.delayLoadingFile))return;let l=[];o.targets.forEach(p=>{if(!p.delayLoadingFile)return l.push(Promise.resolve(null));let m=`${n}${p.delayLoadingFile}`;r.addPendingData(m);let u=new jr.WebRequest;u.responseType="arraybuffer",u.open("GET",m),u.send(),l.push(new Promise(f=>{u.addEventListener("load",()=>{r.removePendingData(m),f(u.response)})}))}),Promise.all(l).then(p=>{for(let m=0,u=a.numTargets;m<u;++m){let f=a.getTarget(m),g=o.targets[m],S=p[m];if(g.positionsCount){let y=new Float32Array(S,g.positionsOffset,g.positionsCount);f._positions=y,f.setPositions(y)}if(g.normalsCount){let y=new Float32Array(S,g.normalsOffset,g.normalsCount);f._normals=y,f.setNormals(y)}if(g.tangentsCount){let y=new Float32Array(S,g.tangentsOffset,g.tangentsCount);f._tangents=y,f.setTangents(y)}if(g.uvsCount){let y=new Float32Array(S,g.uvsOffset,g.uvsCount);f._uvs=y,f.setUVs(y)}if(g.uv2sCount){let y=new Float32Array(S,g.uv2sOffset,g.uv2sCount);f._uv2s=y,f.setUV2s(y)}}for(let m=0,u=a.numTargets;m<u;++m)a.getTarget(m)._onDataLayoutChanged.notifyObservers()})})}))}i(Qr,"registerMorphTargetManagerParser");var Yr=require("babylonjs"),Hr=require("babylonjs"),Wr=!1;function qr(){Wr||(Wr=!0,(0,Yr.AddParser)("NodeParticleSystemSetEditorPlugin",(e,r,t,n)=>{e.meshes?.forEach(o=>{if(!o.isNodeParticleSystemMesh)return;let s=t.meshes?.find(a=>a.id===o.id);s&&(o.nodeParticleSystemSet.blocks?.forEach(a=>{a.url&&(a.url=`${n}${a.url}`)}),s.nodeParticleSystemSet=Hr.NodeParticleSystemSet.Parse(o.nodeParticleSystemSet),s.nodeParticleSystemSet.id=o.nodeParticleSystemSet.id,s.nodeParticleSystemSet.uniqueId=o.uniqueId,r.addPendingData(o.id),s.nodeParticleSystemSet.buildAsync(r,!1).then(a=>{r.removePendingData(o.id),s.particleSystemSet=a,a.systems.forEach(c=>{if(Le(c)){let l=c._sizeCreation.process;l&&(c._sizeCreation.process=(p,m)=>{l(p,m),p.scale.x*=100,p.scale.y*=100})}}),a.emitterNode=s,a.start()}))})}))}i(qr,"registerNodeParticleSystemSetParser");var Jr=require("babylonjs");function Zr(e,r){r??=new Jr.ClusteredLightContainer("Clustered Light Container",[],e);let t=e.metadata?.clusteredLight;return t&&(t.lights.length>0&&(r.horizontalTiles=t.horizontalTiles,r.verticalTiles=t.verticalTiles,r.depthSlices=t.depthSlices,r.maxRange=t.maxRange),t.lights.forEach(n=>{let o=e.getLightById(n);o&&r?.addLight(o)})),r}i(Zr,"configureLights");function Tt(e){if(!Array.isArray(e.frames)){let r=[];for(let t of Object.keys(e.frames))r.push({filename:t,...e.frames[t]});e.frames=r}}i(Tt,"normalizeAtlasJson");function so(e,r,t){let o=(e.metadata?.spriteAnimations??[]).find(s=>s.name===r);if(!o)return console.error(`Animation with name "${r}" not found on sprite.`);e.playAnimation(o.from,o.to,o.loop,o.delay,t)}i(so,"playSpriteAnimationFromName");var en=require("babylonjs"),tn=require("babylonjs"),rn=require("babylonjs"),nn=require("babylonjs"),Ot=require("babylonjs"),oe=require("babylonjs"),on=require("babylonjs"),Xr=!1;function sn(){Xr||(Xr=!0,(0,on.AddParser)("SpriteMapNode",(e,r,t,n)=>{e.transformNodes?.forEach(o=>{if(!o.isSpriteMap)return;let s=t.transformNodes?.find(l=>l.id===o.id);if(!s)return;s.isSpriteMap=o.isSpriteMap;let a=`${n}${o.atlasJsonRelativePath}`;r.addPendingData(a);let c=new rn.WebRequest;c.open("GET",a),c.send(),c.addEventListener("load",()=>{r.removePendingData(a);let l=JSON.parse(c.responseText);Tt(l);let p=`${en.Tools.GetFolderPath(a)}${l.meta.image}`,m=new Ot.Texture(p,r,!1,!1,Ot.Texture.NEAREST_NEAREST,null,null,null,!1,tn.Engine.TEXTUREFORMAT_RGBA),u=new nn.SpriteMap(s.name,l,m,{layerCount:o.options.layerCount,stageSize:oe.Vector2.FromArray(o.options.stageSize??[10,1]),outputSize:oe.Vector2.FromArray(o.options.outputSize??[100,100]),colorMultiply:oe.Vector3.FromArray(o.options.colorMultiply??[1,1,1]),flipU:!0},r);o.getClassName=()=>"SpriteMapNode",o.tiles.forEach(g=>{for(let S=0,y=g.repeatCount.x+1;S<y;++S)for(let P=0,A=g.repeatCount.y+1;P<A;++P){let v=S*(g.repeatOffset.x+1),h=P*(g.repeatOffset.y+1);u.changeTiles(g.layer,new oe.Vector2(g.position.x+v,(u.options.stageSize?.y??0)-1-g.position.y-h),g.tile)}});let f=u._output;f.parent=s,s.spriteMap=u})})}))}i(sn,"registerSpriteMapParser");var cn=require("babylonjs"),Dt=require("babylonjs"),pn=require("babylonjs"),mn=require("babylonjs"),an=new Map;async function ln(e,r){let t=e.getWaitingItemsCount();for(;!e.isDisposed&&(!e.isReady()||e.getWaitingItemsCount()>0);){await new Promise(o=>setTimeout(o,150));let n=t-e.getWaitingItemsCount();n===t&&e.textures.forEach(o=>{o.delayLoadState===Dt.Constants.DELAYLOADSTATE_NONE&&(o.delayLoadState=Dt.Constants.DELAYLOADSTATE_LOADED)}),r(n/t)}}i(ln,"waitForWaitingItems");async function ao(e,r,t,n,o){t.loadingQuality=o?.quality??"high",t.loadingTexturesQuality=o?.texturesQuality??t.loadingQuality,t.loadingShadowsQuality=o?.shadowsQuality??t.loadingQuality,t.loadingLodsQuality=o?.lodsQuality??t.loadingQuality,br(),Mr(),_r(),Qr(),sn(),zr(),qr();let s=an.get(t)??{};if(an.set(t,s),await(0,pn.AppendSceneAsync)(`${e}${r}`,t,{pluginExtension:".babylon",onProgress:i(c=>{let l=Math.min(c.loaded/c.total*.5);o?.onProgress?.(l)},"onProgress")}),await ln(t,c=>{o?.onProgress?.(.5+c*.25)}),!o?.skipAssetsPreload){let c=0;do c=await xt(e,t,n);while(c!==0&&!t.isDisposed)}mn.SceneLoaderFlags.ForceFullSceneLoadingForIncremental&&t.meshes.forEach(c=>D(c)&&c._checkDelayState());let a=Zr(t,s.clusteredLightContainer);s.clusteredLightContainer=a,await ln(t,c=>{o?.onProgress?.(.75+c*.25)}),o?.onProgress?.(1),ke(t),ze(t.loadingLodsQuality,t),$e(t),ve(t),t.metadata?.rendering&&(sr(t,t.metadata.rendering),t.activeCamera&&mt(t.activeCamera,e,o?.postProcessConfiguration)),t.metadata?.physicsGravity&&t.getPhysicsEngine()?.setGravity(cn.Vector3.FromArray(t.metadata?.physicsGravity)),F(t,t,n,e),t.transformNodes.forEach(c=>{F(t,c,n,e)}),t.meshes.forEach(c=>{ir(c),F(t,c,n,e)}),t.lights.forEach(c=>{F(t,c,n,e)}),t.cameras.forEach(c=>{F(t,c,n,e)}),t.spriteManagers?.forEach(c=>{c.sprites.forEach(l=>{F(t,l,n,e)})}),re(t)}i(ao,"loadScene");var un=require("babylonjs");async function lo(e,r,t){let n=await N(e+r),s=un.Tools.Instantiate(n.customType).Parse(n,t,e);return s.id=n.id,s.uniqueId=n.uniqueId,s}i(lo,"loadMaterialFromFile");function co(e){return Promise.all(e.materials.map(async r=>{let t=r.getBindedMeshes();await Promise.all(t.map(async n=>{le(n)||await r.forceCompilationAsync(n,{clipPlane:!!e.clipPlane,useInstances:n.hasInstances})}))}))}i(co,"forceCompileAllSceneMaterials");var B=require("babylonjs");function ye(e){if(!isNaN(parseFloat(e))&&isFinite(e))return B.Animation.ANIMATIONTYPE_FLOAT;switch(e?.getClassName?.()){case"Vector2":return B.Animation.ANIMATIONTYPE_VECTOR2;case"Vector3":return B.Animation.ANIMATIONTYPE_VECTOR3;case"Quaternion":return B.Animation.ANIMATIONTYPE_QUATERNION;case"Color3":return B.Animation.ANIMATIONTYPE_COLOR3;case"Color4":return B.Animation.ANIMATIONTYPE_COLOR4;case"Size":return B.Animation.ANIMATIONTYPE_SIZE;case"Matrix":return B.Animation.ANIMATIONTYPE_MATRIX}return null}i(ye,"getAnimationTypeForObject");var dn=require("babylonjs");function po(e){return function(r,t){let n=r.constructor;n._NodesFromScene??=[],n._NodesFromScene.push({propertyKey:t,nodeName:e})}}i(po,"nodeFromScene");function mo(e){return function(r,t){let n=r.constructor;n._ComponentsFromScene??=[],n._ComponentsFromScene.push({propertyKey:t,componentConstructor:e})}}i(mo,"componentFromScene");function uo(e,r=!1){return function(t,n){let o=t.constructor;o._NodesFromDescendants??=[],o._NodesFromDescendants.push({propertyKey:n,nodeName:e,directDescendantsOnly:r})}}i(uo,"nodeFromDescendants");function fo(e){return function(r,t){let n=r.constructor;n._AnimationGroups??=[],n._AnimationGroups.push({animationGroupName:e,propertyKey:t})}}i(fo,"animationGroupFromScene");function go(e){return function(r,t){let n=r.constructor;n._SceneAssets??=[],n._SceneAssets.push({sceneName:e,propertyKey:t})}}i(go,"sceneAsset");function yo(e,r){return function(t,n){let o=t.constructor;o._GuiFromAsset??=[],o._GuiFromAsset.push({propertyKey:n,pathInAssets:e,onGuiCreated:r})}}i(yo,"guiFromAsset");function So(e){return function(r,t){let n=r.constructor;n._SoundsFromScene??=[],n._SoundsFromScene.push({propertyKey:t,soundName:e})}}i(So,"soundFromScene");function ho(e,r=!1){return function(t,n){let o=t.constructor;o._ParticleSystemsFromScene??=[],o._ParticleSystemsFromScene.push({propertyKey:n,particleSystemName:e,directDescendantsOnly:r})}}i(ho,"particleSystemFromScene");function bo(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"boolean"}})}}i(bo,"visibleAsBoolean");function Po(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"string"}})}}i(Po,"visibleAsString");function xo(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"number"}})}}i(xo,"visibleAsNumber");function Ao(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"vector2"}})}}i(Ao,"visibleAsVector2");function vo(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"vector3"}})}}i(vo,"visibleAsVector3");function Co(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"color3"}})}}i(Co,"visibleAsColor3");function Io(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"color4"}})}}i(Io,"visibleAsColor4");function Eo(e,r,t){return function(n,o){let s=n.constructor;s._VisibleInInspector??=[],s._VisibleInInspector.push({label:r,propertyKey:o,configuration:{...t,entityType:e,type:"entity"}})}}i(Eo,"visibleAsEntity");function To(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"texture"}})}}i(To,"visibleAsTexture");function Oo(e,r){return function(t,n){let o=t.constructor;o._VisibleInInspector??=[],o._VisibleInInspector.push({label:e,propertyKey:n,configuration:{...r,type:"keymap"}})}}i(Oo,"visibleAsKeyMap");function Do(e,r,t){return function(n,o){let s=n.constructor;s._VisibleInInspector??=[],s._VisibleInInspector.push({label:r,propertyKey:o,configuration:{...t,assetType:e,type:"asset"}})}}i(Do,"visibleAsAsset");function Mo(e,r){return function(t,n){let o=t.constructor;o._PointerEvents??=[],o._PointerEvents.push({propertyKey:n,options:{mode:"global",...r??{}},eventTypes:Array.isArray(e)?e:[e]})}}i(Mo,"onPointerEvent");function wo(e){return function(r,t){let n=r.constructor;n._KeyboardEvents??=[],n._KeyboardEvents.push({propertyKey:t,eventTypes:Array.isArray(e)?e:[e]})}}i(wo,"onKeyboardEvent");function No(e){return function(r,t){let n=r.constructor;n._SpritesFromSpriteManager??=[],n._SpritesFromSpriteManager.push({propertyKey:t,spriteName:e})}}i(No,"spriteFromSpriteManager");function Fo(e){return function(r,t){let n=r.constructor;n._AnimationsFromSprite??=[],n._AnimationsFromSprite.push({propertyKey:t,animationName:e})}}i(Fo,"animationFromSprite");var Ne=require("babylonjs");function ed(e,r){let t;return e===Ne.Animation.ANIMATIONTYPE_FLOAT?t=r.value:t=r.value.clone(),{value:t,frame:r.frame,interpolation:r.interpolation,inTangent:e===Ne.Animation.ANIMATIONTYPE_FLOAT?r.inTangent:r.inTangent?.clone(),outTangent:e===Ne.Animation.ANIMATIONTYPE_FLOAT?r.outTangent:r.outTangent?.clone()}}i(ed,"cloneKey");function Fe(e,r){let t=r.split("."),n=e;for(let o=0;o<t.length;++o)n=n[t[o]];return n}i(Fe,"getPropertyValue");function Mt(e,r,t){let n=null;e.onAnimationGroupPlayObservable.add(()=>{n=r.onAfterAnimationsObservable.add(()=>{t()})}),e.onAnimationGroupPauseObservable.add(()=>{n&&(r.onAfterAnimationsObservable.remove(n),n=null)}),e.onAnimationGroupEndObservable.add(()=>{n&&(r.onAfterAnimationsObservable.remove(n),n=null)})}i(Mt,"registerAfterAnimationCallback");var G=require("babylonjs"),Re=require("babylonjs"),L=require("babylonjs");function Ro(e,r){return{name:e.name,framesPerSecond:e.framesPerSecond,outputFramesPerSecond:e.outputFramesPerSecond,tracks:e.tracks.map(t=>{let n=null,o=null;if(t.node?(n=ee(t.node,r),n||(n=r.particleSystems?.find(a=>a.id===t.node)??null)):t.defaultRenderingPipeline?n=pe():t.volumetricLightScattering&&(n=je()),t.propertyPath){let a=Fe(n,t.propertyPath);o=ye(a)}let s=null;return t.sound&&(s=ee(t.sound,r)),{node:n,sound:s,propertyPath:t.propertyPath,defaultRenderingPipeline:t.defaultRenderingPipeline,volumetricLightScattering:t.volumetricLightScattering,animationGroupWeight:t.animationGroupWeight,animationGroup:t.animationGroup?r.getAnimationGroupByName(t.animationGroup):null,animationGroups:t.animationGroups,sounds:t.sounds,soundVolume:wt(t.soundVolume??[],G.Animation.ANIMATIONTYPE_FLOAT),keyFrameEvents:t.keyFrameEvents?.map(a=>{let c={...a};switch(a.data?.type){case"set-enabled":c.data={type:"set-enabled",value:a.data.value,node:ee(a.data.node,r)};break;case"apply-impulse":c.data={type:"apply-impulse",radius:a.data.radius,mesh:r.getMeshById(a.data.mesh),force:L.Vector3.FromArray(a.data.force),contactPoint:L.Vector3.FromArray(a.data.contactPoint)};break}return c}),keyFrameAnimations:n&&o!==null&&wt(t.keyFrameAnimations??[],o)}})}}i(Ro,"parseCinematic");function _(e,r){if(e===null)return null;if(e!==void 0)switch(r){case G.Animation.ANIMATIONTYPE_FLOAT:return e;case G.Animation.ANIMATIONTYPE_VECTOR2:return L.Vector2.FromArray(e);case G.Animation.ANIMATIONTYPE_VECTOR3:return L.Vector3.FromArray(e);case G.Animation.ANIMATIONTYPE_QUATERNION:return L.Quaternion.FromArray(e);case G.Animation.ANIMATIONTYPE_COLOR3:return Re.Color3.FromArray(e);case G.Animation.ANIMATIONTYPE_COLOR4:return Re.Color4.FromArray(e);case G.Animation.ANIMATIONTYPE_MATRIX:return L.Matrix.FromArray(e)}}i(_,"parseCinematicKeyValue");function wt(e,r){return e?.map(t=>{let n=t.type==="key"?t:null;if(n)return{...n,value:_(n.value,r),inTangent:_(n.inTangent,r),outTangent:_(n.outTangent,r)};let o=t.type==="cut"?t:null;if(o)return{...o,key1:{...o.key1,value:_(o.key1.value,r),inTangent:_(o.key1.inTangent,r),outTangent:_(o.key1.outTangent,r)},key2:{...o.key2,value:_(o.key2.value,r),inTangent:_(o.key2.inTangent,r),outTangent:_(o.key2.outTangent,r)}};throw new Error(`Unknown key frame type: ${t.type}`)})}i(wt,"parseKeyFrameAnimations");function fn(e,r){e.onEventObservable.notifyObservers(r.eventName)}i(fn,"handleApplyEvent");function gn(e){e.node?.setEnabled(e.value)}i(gn,"handleSetEnabledEvent");var Nt=require("babylonjs"),yn=Nt.Vector3.Zero();function Sn(e,r){let t=r.mesh?[r.mesh]:e.meshes.filter(n=>n.physicsAggregate);r.radius&&(t=t.filter(n=>{let o=n.getBoundingInfo().boundingBox.centerWorld;return Nt.Vector3.Distance(o,r.contactPoint)<=r.radius})),t.forEach(n=>{if(n.physicsAggregate?.body){let o=r.contactPoint.subtract(n.getBoundingInfo().boundingBox.centerWorld);o.multiplyInPlace(r.force),n.physicsAggregate.body.setLinearVelocity(yn),n.physicsAggregate.body.setAngularVelocity(yn),n.physicsAggregate.body.applyImpulse(o.negateInPlace(),r.contactPoint)}})}i(Sn,"handleApplyImpulseEvent");var hn=require("babylonjs"),bn=require("babylonjs"),Se=class extends bn.AnimationGroup{static{i(this,"Cinematic")}onEventObservable=new hn.Observable;onEvent(r,t){this.onEventObservable.add(n=>{r===n&&t()})}};function Ft(e){return e.type==="key"}i(Ft,"isCinematicKey");function ie(e){return e.type==="cut"}i(ie,"isCinematicKeyCut");function _o(e){return e.type==="event"}i(_o,"isCinematicKeyEvent");function Lo(e){return e.type==="group"}i(Lo,"isCinematicGroup");function Vo(e){return e.type==="sound"}i(Vo,"isCinematicSound");var C=require("babylonjs"),se=require("babylonjs");function Bo(e,r,t){let n=new Se(e.name,r);return e.tracks.forEach(o=>{let s=o.animationGroup;if(s&&o.animationGroups?.length){let f=s.clone(`${s.name}-cinematic-temp`),g=r.animationGroups.indexOf(f);g!==-1&&r.animationGroups.splice(g,1),n.onAnimationEndObservable.add(()=>{s.stop(),f.stop()});let S=o.animationGroups.reduce((v,h)=>Math.min(v,h.frame),Number.MAX_VALUE)??0,y=o.animationGroups.reduce((v,h)=>Math.max(v,h.frame+h.endFrame),0)??0,P={frame:S},A=new C.Animation(f.name,"frame",60,C.Animation.ANIMATIONTYPE_FLOAT,C.Animation.ANIMATIONLOOPMODE_CYCLE,!1);if(A.setKeys([{frame:S,value:0},{frame:y,value:y}]),o.animationGroups.forEach(v=>{A.addEvent(new se.AnimationEvent(v.frame,()=>{let h=v.repeatCount??0;if(f.to=v.endFrame,f.speedRatio=v.speed,f.stop(),f.play(h>0),f.from!==v.startFrame&&f.goToFrame(v.startFrame),h){let w=0;f.onAnimationGroupLoopObservable.add(()=>{++w,w>h&&f.stop()})}}))}),n.addTargetedAnimation(A,P),(o.animationGroupWeight?.length??0)>=2&&o.animationGroupWeight.find(h=>ie(h)?h.key1.value!==1||h.key2.value!==1:h.value!==1)){let h={weight:0},w=new C.Animation(`${f.name}-weights`,"weight",60,C.Animation.ANIMATIONTYPE_FLOAT,C.Animation.ANIMATIONLOOPMODE_CYCLE,!1),K=[];o.animationGroupWeight.forEach(ae=>{ie(ae)?(K.push(ae.key1),K.push(ae.key2)):K.push(ae)}),w.setKeys(K),n.addTargetedAnimation(w,h),Mt(n,r,()=>{f.weight=h.weight})}}let a=o.sound;if(!t?.ignoreSounds&&a&&a.sound?.buffer&&o.sounds?.length){let f={dummy:0,volume:0},g=new C.Animation(a.name,"dummy",60,C.Animation.ANIMATIONTYPE_FLOAT,C.Animation.ANIMATIONLOOPMODE_CYCLE,!1),S=0;if(o.sounds?.forEach(y=>{let P=y.endFrame-y.startFrame;S=Math.max(S,y.frame+P),g.addEvent(new se.AnimationEvent(y.frame,A=>{let h=(A-y.frame+y.startFrame)/e.framesPerSecond;a.play({startOffset:h})},!1)),g.addEvent(new se.AnimationEvent(y.frame+P,()=>{a.stop()}))}),g.setKeys([{frame:0,value:0},{frame:S,value:S}]),n.addTargetedAnimation(g,f),(o.soundVolume?.length??0)>=2){let y=new C.Animation(a.name,"volume",60,C.Animation.ANIMATIONTYPE_FLOAT,C.Animation.ANIMATIONLOOPMODE_CYCLE,!1),P=[];o.soundVolume.forEach(A=>{ie(A)?(P.push(A.key1),P.push(A.key2)):P.push(A)}),y.setKeys(P),n.addTargetedAnimation(y,f),Mt(n,r,()=>{a.volume=f.volume})}}if(o.keyFrameEvents){let f={dummy:0},g=new C.Animation("events","dummy",60,C.Animation.ANIMATIONTYPE_FLOAT,C.Animation.ANIMATIONLOOPMODE_CYCLE,!1),S=0;o.keyFrameEvents?.forEach(y=>{S=Math.max(S,y.frame),g.addEvent(new se.AnimationEvent(y.frame,()=>{switch(y.data?.type){case"event":fn(n,y.data);break;case"set-enabled":gn(y.data);break;case"apply-impulse":Sn(r,y.data);break}}))}),g.setKeys([{frame:0,value:0},{frame:S+1,value:S+1}]),n.addTargetedAnimation(g,f)}let c=o.defaultRenderingPipeline?pe():o.node;if(!c||!o.propertyPath||!o.keyFrameAnimations)return;let l=Fe(c,o.propertyPath),p=ye(l);if(p===null)return;let m=new C.Animation(o.propertyPath,o.propertyPath,60,p,C.Animation.ANIMATIONLOOPMODE_CYCLE,!1),u=[];o.keyFrameAnimations?.forEach(f=>{if(Ft(f))return u.push(f);ie(f)&&(u.push(f.key1),u.push(f.key2),xe(c)&&o.propertyPath==="position"&&m.addEvent(new se.AnimationEvent(f.key1.frame,()=>{let g=nt();if(!g)return;let S=g.motionStrength;g.motionStrength=0,requestAnimationFrame(()=>{g.motionStrength=S})})))}),m.setKeys(u),n.addTargetedAnimation(m,c)}),n.normalize(),n}i(Bo,"generateCinematicAnimationGroup");async function Rt(e,r){return new Promise((t,n)=>{let o=indexedDB.open(e,1);o.addEventListener("error",()=>n()),o.addEventListener("blocked",()=>n()),o.addEventListener("upgradeneeded",()=>{try{r(o.result)}catch(s){n(s)}}),o.addEventListener("success",()=>{t(o.result)})})}i(Rt,"openIndexDB");function he(e,r,t){return new Promise(n=>{let s=e.transaction(r).objectStore(r).get(t);s.addEventListener("error",()=>{n(null)}),s.addEventListener("success",()=>{n(s.result??null)})})}i(he,"getFromIndexDB");async function V(e,r,t){let o=e.transaction(r,"readwrite").objectStore(r).put(t);await new Promise((s,a)=>{o.addEventListener("error",()=>a()),o.addEventListener("success",()=>s())})}i(V,"putInIndexDB");var Pn=require("babylonjs");function Go(e){Pn.AbstractEngine.OfflineProviderFactory=(r,t,n=!1)=>new be(e,r,t,n)}i(Go,"setupOfflineProvider");async function _t(e,r){let t=await new Promise(n=>{let o=new be(e,r,s=>n(s?o:null),!1)});return await t?.open(),t}i(_t,"createAndOpenDatabase");var be=class{static{i(this,"Database")}enableSceneOffline=!0;enableTexturesOffline=!0;name;_database=null;_manifestVersion=null;_loadFilePromises=new Map;constructor(r,t,n,o){this.name=r,o?n(!1):this._checkManifest(t,n)}async _checkManifest(r,t){try{let n=await N(`${r}.manifest?${Date.now()}`);this._manifestVersion=n.version,t(!0)}catch{this.enableSceneOffline=!1,this.enableTexturesOffline=!1,t(!1)}}async open(r,t){try{this._database=await Rt(this.name,n=>{n.createObjectStore("files",{keyPath:"url"}),n.createObjectStore("images",{keyPath:"url"}),n.createObjectStore("versions",{keyPath:"url"})}),r?.()}catch{t?.()}}close(){this._database?.close(),this._database=null,this._loadFilePromises.clear()}async loadImage(r,t){if(!this._database){t.src=r;return}let n=null;await gt(()=>this._manifestVersion!==null);let o=this._loadFilePromises.get(r);if(o)return o.then(a=>{a!==null?t.src=a:t.src=r});let s=new Promise(async a=>{if(await this._getFileVersionForUrl(r)!==this._manifestVersion?(n=await X(r,"blob"),await Promise.all([V(this._database,"images",{url:r,data:n}),V(this._database,"versions",{url:r,version:this._manifestVersion})])):n=(await he(this._database,"images",r))?.data??null,n!==null){let l=URL.createObjectURL(n);t.src=l}else t.src=r;a(t.src)});this._loadFilePromises.set(r,s)}async saveImage(r){if(!this._database)throw new Error("Database is not available");let t=await X(r,"blob");await Promise.all([V(this._database,"images",{url:r,data:t}),V(this._database,"versions",{url:r,version:this._manifestVersion})])}async isFileMatchingVersion(r){return await this._getFileVersionForUrl(r)===this._manifestVersion}async loadFile(r,t,n,o,s){if(!this._database)return o?.();let a=null;await gt(()=>this._manifestVersion!==null);let c=this._loadFilePromises.get(r);if(c)return c.then(p=>{p!==null?t(p):o?.()});let l=new Promise(async p=>{await this._getFileVersionForUrl(r)!==this._manifestVersion?(a=await X(r,s?"arraybuffer":"text",n),await Promise.all([V(this._database,"files",{url:r,data:a}),V(this._database,"versions",{url:r,version:this._manifestVersion})])):a=(await he(this._database,"files",r))?.data??null,a!==null?t(a):o?.(),p(a)});this._loadFilePromises.set(r,l)}async saveFile(r,t,n){if(!this._database)throw new Error("Database is not available");let o=await X(r,t?"arraybuffer":"text",n);await Promise.all([V(this._database,"files",{url:r,data:o}),V(this._database,"versions",{url:r,version:this._manifestVersion})])}async _getFileVersionForUrl(r){return(await he(this._database,"versions",r))?.version??null}};var xn=["mp3","wav"],An=["babylonbinarymeshdata"],Ko=["ktx","ktx2","jpg","jpeg","png","bmp","webp"],vn=["babylon","json"],Lt=["jpg","jpeg","png","bmp","webp"],Cn=["bin","ktx","ktx2",...An,...xn],ko=[...vn,...Lt,...Cn];async function zo(e,r,t){let n=[],o=await N(`${r}scenes-used-files.json`),s=[];if(t?.scenesFilter){s=t.scenesFilter.map(u=>typeof u=="string"?{sceneName:u,disableSounds:!1,disableTextures:!1,disableGeometries:!1}:u);for(let[u,f]of Object.entries(o))s.find(g=>g.sceneName===u)||delete o[u]}let a=0,c=0,l=t?.engine?.textureFormatInUse?t?.engine?.texturesSupported[0]:null,p=Object.values(o).reduce((u,f)=>u+f.length,0);function m(u){++c,t?.onProgress?.(c/p),u?.()}i(m,"notifyProgress");for(let[u,f]of Object.entries(o)){let g=u.replace(".scene",".babylon"),S=await _t(e,`${r}${g}`);if(!S)continue;let y=s.find(P=>P.sceneName===u);for(let P=0,A=f.length;P<A;++P){let v=f[P],h=v.split(".").pop()?.toLowerCase();if(!h){m();continue}if(An.includes(h)&&y?.disableGeometries){m();continue}if(Ko.includes(h)&&y?.disableTextures){m();continue}if(xn.includes(h)&&y?.disableSounds){m();continue}if(Lt.includes(h)&&y?.disableTextures){m();continue}if(h==="ktx")if(l){if(!v.endsWith(l)){m();continue}}else{m();continue}if(h==="ktx2"&&!ge()){m();continue}if(n.length>300){try{await Promise.all(n)}catch{}n.splice(0,n.length)}let w=`${r}${v}`;ko.includes(h)&&n.push(new Promise(async K=>{if(await S.isFileMatchingVersion(w))return m(K);try{Lt.includes(h)?t?.disableImages||(await S.saveImage(w),++a):Cn.includes(h)?(await S.saveFile(w,!0),++a):vn.includes(h)&&(await S.saveFile(w,!1),++a)}catch{}m(K)}))}await Promise.all(n),S.close()}return await Promise.all(n),{loadedCount:a,processedFilesCount:c}}i(zo,"preloadAssetsToDatabase");0&&(module.exports={AdvancedAssetContainer,AdvancedAssetContainerInstantiatedEntries,Cinematic,Database,NodeParticleSystemSet,_applyScriptsForObject,_getKtx2TextureName,_preloadScriptsAssets,_registerScriptInstance,_removeRegisteredScriptInstance,addExcludedCompressedTexture,animationFromSprite,animationGroupFromScene,applyMeshesLODQuality,applyRenderingConfigurationForCamera,applyScriptOnObject,applyShadowsQuality,applyTexturesQuality,componentFromScene,configureEngineToUseCompressedTextures,configureMeshDistanceOrScreenCoverage,configureShadowMapRefreshRate,configureShadowMapRenderListPredicate,copyAndParseRagdollConfiguration,createAndOpenDatabase,createDefaultRenderingPipeline,createMotionBlurPostProcess,createSSAO2RenderingPipeline,createSSRRenderingPipeline,createTAARenderingPipeline,createVLSPostProcess,defaultPipelineCameraConfigurations,disposeDefaultRenderingPipeline,disposeMotionBlurPostProcess,disposeSSAO2RenderingPipeline,disposeSSRRenderingPipeline,disposeTAARenderingPipeline,disposeVLSPostProcess,forceCompileAllSceneMaterials,generateCinematicAnimationGroup,getAllScriptsByClassForObject,getAnimationTypeForObject,getDefaultRenderingPipeline,getFromIndexDB,getMotionBlurPostProcess,getPowerOfTwoUntil,getSSAO2RenderingPipeline,getSSRRenderingPipeline,getScriptByClassForObject,getTAARenderingPipeline,getTextureUrl,getVLSPostProcess,guiFromAsset,isAbstractMesh,isAnyParticleSystem,isArcRotateCamera,isBone,isCamera,isCinematicGroup,isCinematicKey,isCinematicKeyCut,isCinematicKeyEvent,isCinematicSound,isClusteredLightContainer,isDecalMesh,isDirectionalLight,isFreeCamera,isGPUParticleSystem,isGaussianSplattingMesh,isGroundMesh,isHemisphericLight,isInstancedMesh,isLight,isMesh,isNode,isNodeFromStaticGroup,isParticleSystem,isPointLight,isScene,isSoundNode,isSpotLight,isSprite,isTexture,isTransformNode,isUsingKtx2CompressedTextures,loadMaterialFromFile,loadScene,motionBlurPostProcessCameraConfigurations,nodeFromDescendants,nodeFromScene,normalizeAtlasJson,onKeyboardEvent,onPointerEvent,openIndexDB,parseCinematic,parseCinematicKeyValue,parseDefaultRenderingPipeline,parseKeyFrameAnimations,parseMotionBlurPostProcess,parseRagdollConfiguration,parseSSAO2RenderingPipeline,parseSSRRenderingPipeline,parseTAARenderingPipeline,parseVLSPostProcess,particleSystemFromScene,playSpriteAnimationFromName,preloadAssetsToDatabase,putInIndexDB,registerScriptAssetParser,saveRenderingConfigurationForCamera,sceneAsset,scriptAssetsCache,scriptAssetsParsers,scriptsDictionary,serializeDefaultRenderingPipeline,serializeMotionBlurPostProcess,serializeSSAO2RenderingPipeline,serializeSSRRenderingPipeline,serializeTAARenderingPipeline,serializeVLSPostProcess,setDefaultRenderingPipelineRef,setMotionBlurPostProcessRef,setSSAO2RenderingPipelineRef,setSSRRenderingPipelineRef,setStaticDecalsEnabled,setTAARenderingPipelineRef,setUseKtx2CompressedTextures,setVLSPostProcessRef,setupOfflineProvider,soundFromScene,spriteFromSpriteManager,ssaoRenderingPipelineCameraConfigurations,ssrRenderingPipelineCameraConfigurations,taaRenderingPipelineCameraConfigurations,visibleAsAsset,visibleAsBoolean,visibleAsColor3,visibleAsColor4,visibleAsEntity,visibleAsKeyMap,visibleAsNumber,visibleAsString,visibleAsTexture,visibleAsVector2,visibleAsVector3,vlsPostProcessCameraConfigurations});
1
+ var je=Object.defineProperty;var yn=Object.getOwnPropertyDescriptor;var bn=Object.getOwnPropertyNames;var xn=Object.prototype.hasOwnProperty;var a=(t,e)=>je(t,"name",{value:e,configurable:!0});var Cn=(t,e)=>{for(var i in e)je(t,i,{get:e[i],enumerable:!0})},Ln=(t,e,i,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of bn(e))!xn.call(t,r)&&r!==i&&je(t,r,{get:()=>e[r],enumerable:!(o=yn(e,r))||o.enumerable});return t};var Dn=t=>Ln(je({},"__esModule",{value:!0}),t);var ls={};Cn(ls,{AdvancedAssetContainer:()=>ze,AdvancedAssetContainerInstantiatedEntries:()=>Be,Cinematic:()=>We,Database:()=>$e,NodeParticleSystemSet:()=>an.NodeParticleSystemSet,VolumetricDebugMode:()=>xo,VolumetricDepthSource:()=>ui,VolumetricDitherMode:()=>ni,VolumetricFogMode:()=>ai,VolumetricLightingRenderingPipeline:()=>q,VolumetricShadowKind:()=>mi,VolumetricShadowMode:()=>Oo,VolumetricStepDistribution:()=>bo,VolumetricTransmittanceMode:()=>hi,_applyScriptsForObject:()=>B,_getKtx2TextureName:()=>ft,_preloadScriptsAssets:()=>Vi,_registerScriptInstance:()=>Gi,_removeRegisteredScriptInstance:()=>mt,addExcludedCompressedTexture:()=>ut,animationFromSprite:()=>Qa,animationGroupFromScene:()=>Ma,applyMeshesLODQuality:()=>It,applyRagdollJointLimits:()=>va,applyRenderingConfigurationForCamera:()=>_i,applyScriptOnObject:()=>Ca,applyShadowsQuality:()=>An,applyTexturesQuality:()=>_a,canUseHdr:()=>ga,componentFromScene:()=>Aa,computeVolumetricBudget:()=>Me,computeVolumetricShapeKey:()=>jn,configureEngineToUseCompressedTextures:()=>Da,configureMeshDistanceOrScreenCoverage:()=>At,configureShadowMapRefreshRate:()=>qe,configureShadowMapRenderListPredicate:()=>Mt,copyAndParseRagdollConfiguration:()=>Oi,createAndOpenDatabase:()=>Yi,createDefaultRenderingPipeline:()=>yo,createMotionBlurPostProcess:()=>fo,createSSAO2RenderingPipeline:()=>mo,createSSRRenderingPipeline:()=>so,createTAARenderingPipeline:()=>co,createVLSPostProcess:()=>no,createVolumetricLightingPrePassConfiguration:()=>gi,createVolumetricLightingRenderingPipeline:()=>Xo,defaultPipelineCameraConfigurations:()=>ve,disposeDefaultRenderingPipeline:()=>Qt,disposeMotionBlurPostProcess:()=>jt,disposeSSAO2RenderingPipeline:()=>Wt,disposeSSRRenderingPipeline:()=>Gt,disposeTAARenderingPipeline:()=>Ht,disposeVLSPostProcess:()=>Vt,disposeVolumetricLightingRenderingPipeline:()=>Ci,ensureVolumetricLightConfiguration:()=>Lo,forceCompileAllSceneMaterials:()=>Ea,generateCinematicAnimationGroup:()=>os,getAllScriptsByClassForObject:()=>Pe,getAllVolumetricCandidateLights:()=>Eo,getAnimationTypeForObject:()=>Ue,getDefaultRenderingPipeline:()=>Ie,getDefaultVolumetricLightConfiguration:()=>oi,getDefaultVolumetricLightingConfiguration:()=>Qe,getFromIndexDB:()=>Xe,getHdrTextureType:()=>$,getMotionBlurPostProcess:()=>Kt,getPowerOfTwoUntil:()=>N,getSSAO2RenderingPipeline:()=>Nn,getSSRRenderingPipeline:()=>Mn,getScriptByClassForObject:()=>Ni,getTAARenderingPipeline:()=>Vn,getTextureUrl:()=>gt,getVLSPostProcess:()=>Rt,getVolumetricGeometryBufferDepthTexture:()=>Si,getVolumetricGeometryBufferRenderer:()=>Ve,getVolumetricLightConfiguration:()=>li,getVolumetricLightRange:()=>tt,getVolumetricLightSteps:()=>si,getVolumetricLightWorldDirection:()=>Re,getVolumetricLightWorldPosition:()=>et,getVolumetricLightingRenderingPipeline:()=>ma,getVolumetricPrePassDepthTexture:()=>vi,getVolumetricPrePassRenderer:()=>ye,guiFromAsset:()=>Va,isAbstractMesh:()=>re,isAnyParticleSystem:()=>wt,isArcRotateCamera:()=>On,isBone:()=>_n,isCamera:()=>Ze,isCascadedShadowGenerator:()=>Dt,isCinematicGroup:()=>ts,isCinematicKey:()=>ji,isCinematicKeyCut:()=>Oe,isCinematicKeyEvent:()=>es,isCinematicSound:()=>is,isClusteredLightContainer:()=>pe,isDecalMesh:()=>Ji,isDirectionalLight:()=>ie,isFreeCamera:()=>wn,isGPUParticleSystem:()=>En,isGaussianSplattingMesh:()=>Et,isGroundMesh:()=>Pn,isHemisphericLight:()=>Ye,isInstancedMesh:()=>Te,isLight:()=>Qi,isMesh:()=>F,isNode:()=>me,isNodeFromStaticGroup:()=>Tt,isParticleSystem:()=>Pt,isPointLight:()=>Ct,isScene:()=>_t,isShadowGenerator:()=>Lt,isSoundNode:()=>ae,isSpotLight:()=>ne,isSprite:()=>Ot,isTexture:()=>Ae,isTransformNode:()=>te,isUsingKtx2CompressedTextures:()=>ke,isVolumetricLightEnabled:()=>Hn,isVolumetricLightSupported:()=>Zn,isVolumetricLightingSupported:()=>da,loadMaterialFromFile:()=>Oa,loadScene:()=>wa,markVolumetricLightsDirty:()=>fa,maxVolumetricArrayLights:()=>K,maxVolumetricDirectionalLights:()=>ri,maxVolumetricShadowSlots:()=>E,motionBlurPostProcessCameraConfigurations:()=>ge,nodeFromDescendants:()=>Ia,nodeFromScene:()=>Ta,normalizeAtlasJson:()=>zi,normalizeVolumetricLightConfiguration:()=>Co,normalizeVolumetricLightingConfiguration:()=>Se,onKeyboardEvent:()=>Ya,onPointerEvent:()=>Za,openIndexDB:()=>Zi,parseCinematic:()=>Ja,parseCinematicKeyValue:()=>k,parseDefaultRenderingPipeline:()=>ei,parseKeyFrameAnimations:()=>$i,parseMotionBlurPostProcess:()=>Yt,parseRagdollConfiguration:()=>Qo,parseSSAO2RenderingPipeline:()=>$t,parseSSRRenderingPipeline:()=>zt,parseTAARenderingPipeline:()=>Ut,parseVLSPostProcess:()=>Nt,parseVolumetricLightingRenderingPipeline:()=>Di,particleSystemFromScene:()=>Na,playSpriteAnimationFromName:()=>Pa,preloadAssetsToDatabase:()=>ss,putInIndexDB:()=>W,registerScriptAssetParser:()=>xa,resolveVolumetricDepthSource:()=>it,resolveVolumetricShadowSlot:()=>To,saveRenderingConfigurationForCamera:()=>ua,sceneAsset:()=>Ra,scriptAssetsCache:()=>I,scriptAssetsParsers:()=>He,scriptsDictionary:()=>H,selectVolumetricLights:()=>di,serializeDefaultRenderingPipeline:()=>Jt,serializeMotionBlurPostProcess:()=>Zt,serializeSSAO2RenderingPipeline:()=>Xt,serializeSSRRenderingPipeline:()=>Bt,serializeTAARenderingPipeline:()=>kt,serializeVLSPostProcess:()=>Ft,serializeVolumetricLightingRenderingPipeline:()=>Li,setDefaultRenderingPipelineRef:()=>zn,setMotionBlurPostProcessRef:()=>Bn,setSSAO2RenderingPipelineRef:()=>Gn,setSSRRenderingPipelineRef:()=>Rn,setStaticDecalsEnabled:()=>Tn,setTAARenderingPipelineRef:()=>Fn,setUseKtx2CompressedTextures:()=>La,setVLSPostProcessRef:()=>In,setVolumetricLightingRenderingPipelineRef:()=>ha,setupOfflineProvider:()=>rs,soundFromScene:()=>Fa,spriteFromSpriteManager:()=>qa,ssaoRenderingPipelineCameraConfigurations:()=>ue,ssrRenderingPipelineCameraConfigurations:()=>de,supportsVolumetricFloatDepthTexture:()=>Io,taaRenderingPipelineCameraConfigurations:()=>fe,visibleAsAsset:()=>ja,visibleAsBoolean:()=>Ga,visibleAsColor3:()=>Ua,visibleAsColor4:()=>Wa,visibleAsEntity:()=>Xa,visibleAsKeyMap:()=>Ka,visibleAsNumber:()=>za,visibleAsString:()=>Ba,visibleAsTexture:()=>$a,visibleAsVector2:()=>Ha,visibleAsVector3:()=>ka,vlsPostProcessCameraConfigurations:()=>he,volumetricLightMetadataKey:()=>se,volumetricLightingPrePassConfigurationName:()=>Ao,volumetricLightingRenderingPipelineCameraConfigurations:()=>xe});module.exports=Dn(ls);function re(t){switch(t.getClassName?.()){case"Mesh":case"LineMesh":case"GroundMesh":case"InstancedMesh":return!0}return!1}a(re,"isAbstractMesh");function F(t){switch(t.getClassName?.()){case"Mesh":case"GroundMesh":return!0}return!1}a(F,"isMesh");function Te(t){return t.getClassName?.()==="InstancedMesh"}a(Te,"isInstancedMesh");function _n(t){return t.getClassName?.()==="Bone"}a(_n,"isBone");function Pn(t){return t.getClassName?.()==="GroundMesh"}a(Pn,"isGroundMesh");function te(t){return t.getClassName?.()==="TransformNode"}a(te,"isTransformNode");function Ae(t){return t?.getClassName?.()==="Texture"}a(Ae,"isTexture");function Ze(t){switch(t.getClassName?.()){case"Camera":case"FreeCamera":case"TargetCamera":case"EditorCamera":case"ArcRotateCamera":case"UniversalCamera":return!0}return!1}a(Ze,"isCamera");function wn(t){switch(t.getClassName?.()){case"FreeCamera":case"UniversalCamera":return!0}return!1}a(wn,"isFreeCamera");function On(t){return t.getClassName?.()==="ArcRotateCamera"}a(On,"isArcRotateCamera");function Ct(t){return t.getClassName?.()==="PointLight"}a(Ct,"isPointLight");function ie(t){return t.getClassName?.()==="DirectionalLight"}a(ie,"isDirectionalLight");function ne(t){return t.getClassName?.()==="SpotLight"}a(ne,"isSpotLight");function Ye(t){return t.getClassName?.()==="HemisphericLight"}a(Ye,"isHemisphericLight");function Qi(t){switch(t.getClassName?.()){case"Light":case"PointLight":case"SpotLight":case"DirectionalLight":case"HemisphericLight":return!0}return!1}a(Qi,"isLight");function Lt(t){return t.getClassName?.()==="ShadowGenerator"}a(Lt,"isShadowGenerator");function Dt(t){return t.getClassName?.()==="CascadedShadowGenerator"}a(Dt,"isCascadedShadowGenerator");function pe(t){return t.getClassName?.()==="ClusteredLightContainer"}a(pe,"isClusteredLightContainer");function me(t){return re(t)||te(t)||Qi(t)||Ze(t)}a(me,"isNode");function _t(t){return t.getClassName?.()==="Scene"}a(_t,"isScene");function Pt(t){return t.getClassName?.()==="ParticleSystem"}a(Pt,"isParticleSystem");function En(t){return t.getClassName?.()==="GPUParticleSystem"}a(En,"isGPUParticleSystem");function wt(t){switch(t.getClassName?.()){case"ParticleSystem":case"GPUParticleSystem":return!0}return!1}a(wt,"isAnyParticleSystem");function Ot(t){return t.getClassName?.()==="Sprite"}a(Ot,"isSprite");function ae(t){return t.getClassName?.()==="SoundNode"}a(ae,"isSoundNode");function Et(t){return t.getClassName?.()==="GaussianSplattingMesh"}a(Et,"isGaussianSplattingMesh");function Tt(t){let e=t;for(;e;){if(e.metadata?.isStaticGroup)return!0;e=e.parent}return!1}a(Tt,"isNodeFromStaticGroup");function At(t){t.meshes.forEach(e=>{F(e)&&e.getLODLevels().forEach(i=>{i.mesh&&(i.mesh.originalDistanceOrScreenCoverage=i.distanceOrScreenCoverage)})})}a(At,"configureMeshDistanceOrScreenCoverage");function It(t,e){e.meshes.forEach(i=>{F(i)&&i.getLODLevels().forEach(o=>{if(o.mesh?.originalDistanceOrScreenCoverage)switch(t){case"very-low":o.distanceOrScreenCoverage=o.mesh.originalDistanceOrScreenCoverage*.125;break;case"low":o.distanceOrScreenCoverage=o.mesh.originalDistanceOrScreenCoverage*.25;break;case"medium":o.distanceOrScreenCoverage=o.mesh.originalDistanceOrScreenCoverage*.5;break;case"high":o.distanceOrScreenCoverage=o.mesh.originalDistanceOrScreenCoverage;break}})})}a(It,"applyMeshesLODQuality");function Ji(t){return(t.metadata?.decal??null)!==null}a(Ji,"isDecalMesh");function Tn(t,e){e.meshes.forEach(i=>{Ji(i)&&Tt(i)&&i.setEnabled(t)})}a(Tn,"setStaticDecalsEnabled");function N(t){let e=1;for(;e<=t;)e<<=1;return e>>1}a(N,"getPowerOfTwoUntil");var eo=require("babylonjs"),to=require("babylonjs");function Mt(t){t.lights.forEach(e=>{let i=e.getShadowGenerator()?.getShadowMap();i&&(i.renderListPredicate=o=>Et(o)?!1:eo.Vector3.Distance(o.getAbsolutePosition(),e.getAbsolutePosition())<=e.range)})}a(Mt,"configureShadowMapRenderListPredicate");async function qe(t){t.executeWhenReady(()=>{t.lights.forEach(e=>{let i=e.getShadowGenerator()?.getShadowMap();i&&(i.refreshRate=e.metadata?.refreshRate??to.RenderTargetTexture.REFRESHRATE_RENDER_ONEVERYFRAME)})})}a(qe,"configureShadowMapRefreshRate");function An(t,e){e.lights.forEach(i=>{let o=i.getShadowGenerator(),r=o?.getShadowMap();if(o?.originalMapSize){let n=o.originalMapSize;switch(t){case"medium":n=n*.5;break;case"low":n=n*.25;break;case"very-low":n=n*.125;break}n=Math.max(128,N(n)),r?.getSize().width!==n&&r.resize(n)}}),qe(e)}a(An,"applyShadowsQuality");var io=require("babylonjs"),oo=require("babylonjs"),ro=require("babylonjs"),w=null,he=new Map;function Rt(){return w}a(Rt,"getVLSPostProcess");function In(t){w=t}a(In,"setVLSPostProcessRef");function Vt(t){w&&t.activeCamera&&(w.dispose(t.activeCamera),w=null)}a(Vt,"disposeVLSPostProcess");function no(t,e,i){return e??=t.meshes.find(o=>F(o)),w=new ro.VolumetricLightScatteringPostProcess("VolumetricLightScatteringPostProcess",1,t.activeCamera,e,100,oo.Texture.BILINEAR_SAMPLINGMODE,t.getEngine(),!1),w.samples=i?.msaaSamples??1,w}a(no,"createVLSPostProcess");function Ft(){return w?{meshId:w.mesh?.id,exposure:w.exposure,decay:w.decay,weight:w.weight,density:w.density,invert:w.invert,useCustomMeshPosition:w.useCustomMeshPosition,customMeshPosition:w.customMeshPosition.asArray()}:null}a(Ft,"serializeVLSPostProcess");function Nt(t,e,i){let o=null;if(e.meshId){let n=t.getMeshById(e.meshId);n&&F(n)&&(o=n)}let r=w??no(t,o,i);return r.samples=i?.msaaSamples??1,r.exposure=e.exposure,r.decay=e.decay,r.weight=e.weight,r.density=e.density,r.invert=e.invert,r.useCustomMeshPosition=e.useCustomMeshPosition,r.customMeshPosition.copyFrom(io.Vector3.FromArray(e.customMeshPosition)),r}a(Nt,"parseVLSPostProcess");var ao=require("babylonjs"),D=null,de=new Map;function Mn(){return D}a(Mn,"getSSRRenderingPipeline");function Rn(t){D=t}a(Rn,"setSSRRenderingPipelineRef");function Gt(){D&&(D.dispose(),D=null)}a(Gt,"disposeSSRRenderingPipeline");function so(t,e,i){return D=new ao.SSRRenderingPipeline("SSRRenderingPipeline",t,[e],void 0,$(t.getEngine())),D.samples=i?.msaaSamples??1,D}a(so,"createSSRRenderingPipeline");function Bt(){return D?{samples:D.samples,step:D.step,thickness:D.thickness,strength:D.strength,reflectionSpecularFalloffExponent:D.reflectionSpecularFalloffExponent,maxSteps:D.maxSteps,maxDistance:D.maxDistance,roughnessFactor:D.roughnessFactor,reflectivityThreshold:D.reflectivityThreshold,blurDispersionStrehgth:D.blurDispersionStrength,clipToFrustum:D.clipToFrustum,enableSmoothReflections:D.enableSmoothReflections,enableAutomaticThicknessComputation:D.enableAutomaticThicknessComputation,attenuateFacingCamera:D.attenuateFacingCamera,attenuateScreenBorders:D.attenuateScreenBorders,attenuateIntersectionDistance:D.attenuateIntersectionDistance,attenuateBackfaceReflection:D.attenuateBackfaceReflection,blurDownsample:D.blurDownsample,selfCollisionNumSkip:D.selfCollisionNumSkip,ssrDownsample:D.ssrDownsample,backfaceDepthTextureDownsample:D.backfaceDepthTextureDownsample}:null}a(Bt,"serializeSSRRenderingPipeline");function zt(t,e,i,o){let r=D??so(t,e,o);return r.samples=o?.msaaSamples??1,r.step=i.step,r.thickness=i.thickness,r.strength=i.strength,r.reflectionSpecularFalloffExponent=i.reflectionSpecularFalloffExponent,r.maxSteps=i.maxSteps,r.maxDistance=i.maxDistance,r.roughnessFactor=i.roughnessFactor,r.reflectivityThreshold=i.reflectivityThreshold,r.blurDispersionStrength=i.blurDispersionStrehgth,r.clipToFrustum=i.clipToFrustum,r.enableSmoothReflections=i.enableSmoothReflections,r.enableAutomaticThicknessComputation=i.enableAutomaticThicknessComputation,r.attenuateFacingCamera=i.attenuateFacingCamera,r.attenuateScreenBorders=i.attenuateScreenBorders,r.attenuateIntersectionDistance=i.attenuateIntersectionDistance,r.attenuateBackfaceReflection=i.attenuateBackfaceReflection,r.blurDownsample=i.blurDownsample,r.selfCollisionNumSkip=i.selfCollisionNumSkip,r.ssrDownsample=i.ssrDownsample,r.backfaceDepthTextureDownsample=i.backfaceDepthTextureDownsample,r}a(zt,"parseSSRRenderingPipeline");var lo=require("babylonjs"),T=null,fe=new Map;function Vn(){return T}a(Vn,"getTAARenderingPipeline");function Fn(t){T=t}a(Fn,"setTAARenderingPipelineRef");function Ht(){T&&(T.dispose(),T=null)}a(Ht,"disposeTAARenderingPipeline");function co(t,e,i){return T=new lo.TAARenderingPipeline("TAARenderingPipeline",t,[e],$(t.getEngine())),T.msaaSamples=i?.msaaSamples??1,T}a(co,"createTAARenderingPipeline");function kt(){return T?{factor:T.factor,samples:T.samples,clampHistory:T.clampHistory,reprojectHistory:T.reprojectHistory,disableOnCameraMove:T.disableOnCameraMove}:null}a(kt,"serializeTAARenderingPipeline");function Ut(t,e,i,o){let r=T??co(t,e,o);return r.msaaSamples=o?.msaaSamples??1,r.factor=i.factor,r.clampHistory=i.clampHistory,r.reprojectHistory=i.reprojectHistory,r.disableOnCameraMove=i.disableOnCameraMove,r}a(Ut,"parseTAARenderingPipeline");var po=require("babylonjs"),P=null,ue=new Map;function Nn(){return P}a(Nn,"getSSAO2RenderingPipeline");function Gn(t){P=t}a(Gn,"setSSAO2RenderingPipelineRef");function Wt(){P&&(P.dispose(),P=null)}a(Wt,"disposeSSAO2RenderingPipeline");function mo(t,e,i){return P=new po.SSAO2RenderingPipeline("SSAO2RenderingPipeline",t,1,[e],void 0,$(t.getEngine())),P.textureSamples=1,P}a(mo,"createSSAO2RenderingPipeline");function Xt(){return P?{radius:P.radius,totalStrength:P.totalStrength,samples:P.samples,maxZ:P.maxZ,minZAspect:P.minZAspect,epsilon:P.epsilon,textureSamples:P.textureSamples,bypassBlur:P.bypassBlur,bilateralSamples:P.bilateralSamples,bilateralSoften:P.bilateralSoften,bilateralTolerance:P.bilateralTolerance,expensiveBlur:P.expensiveBlur}:null}a(Xt,"serializeSSAO2RenderingPipeline");function $t(t,e,i,o){let r=P??mo(t,e,o);return r.textureSamples=1,r.radius=i.radius,r.totalStrength=i.totalStrength,r.samples=i.samples,r.maxZ=i.maxZ,r.minZAspect=i.minZAspect,r.epsilon=i.epsilon,r.bypassBlur=i.bypassBlur,r.bilateralSamples=i.bilateralSamples,r.bilateralSoften=i.bilateralSoften,r.bilateralTolerance=i.bilateralTolerance,r.expensiveBlur=i.expensiveBlur,r}a($t,"parseSSAO2RenderingPipeline");var ho=require("babylonjs"),A=null,ge=new Map;function Kt(){return A}a(Kt,"getMotionBlurPostProcess");function Bn(t){A=t}a(Bn,"setMotionBlurPostProcessRef");function jt(){A&&(A.dispose(),A=null)}a(jt,"disposeMotionBlurPostProcess");function fo(t,e,i){return A=new ho.MotionBlurPostProcess("MotionBlurPostProcess",t,1,e,void 0,void 0,void 0,$(t.getEngine())),A.samples=i?.msaaSamples??1,A.motionStrength=1,A.isObjectBased=!0,A}a(fo,"createMotionBlurPostProcess");function Zt(){return A?{isObjectBased:A.isObjectBased,motionStrength:A.motionStrength,motionBlurSamples:A.motionBlurSamples}:null}a(Zt,"serializeMotionBlurPostProcess");function Yt(t,e,i,o){let r=A??fo(t,e,o);return r.samples=o?.msaaSamples??1,r.isObjectBased=i.isObjectBased,r.motionStrength=i.motionStrength,r.motionBlurSamples=i.motionBlurSamples,r}a(Yt,"parseMotionBlurPostProcess");var uo=require("babylonjs"),qt=require("babylonjs"),go=require("babylonjs"),vo=require("babylonjs"),So=require("babylonjs"),u=null,ve=new Map;function Ie(){return u}a(Ie,"getDefaultRenderingPipeline");function zn(t){u=t}a(zn,"setDefaultRenderingPipelineRef");function Qt(){u&&(u.dispose(),u=null)}a(Qt,"disposeDefaultRenderingPipeline");function yo(t,e,i){return u=new So.DefaultRenderingPipeline("DefaultRenderingPipeline",!0,t,[e]),u.samples=i?.msaaSamples??1,u.depthOfField.lensSize=512,u.depthOfField.fStop=.25,u.depthOfField.focusDistance=55e3,u}a(yo,"createDefaultRenderingPipeline");function Jt(){return u?{samples:u.samples,fxaaEnabled:u.fxaaEnabled,imageProcessingEnabled:u.imageProcessingEnabled,exposure:u.imageProcessing?.exposure,contrast:u.imageProcessing?.contrast,fromLinearSpace:u.imageProcessing?.fromLinearSpace,toneMappingEnabled:u.imageProcessing?.toneMappingEnabled,toneMappingType:u.imageProcessing?.toneMappingType,ditheringEnabled:u.imageProcessing?.ditheringEnabled,ditheringIntensity:u.imageProcessing?.ditheringIntensity,bloomEnabled:u.bloomEnabled,bloomThreshold:u.bloomThreshold,bloomWeight:u.bloomWeight,bloomScale:u.bloomScale,bloomKernel:u.bloomKernel,sharpenEnabled:u.sharpenEnabled,sharpenEdgeAmount:u.sharpen.edgeAmount,sharpenColorAmount:u.sharpen.colorAmount,grainEnabled:u.grainEnabled,grainIntensity:u.grain.intensity,grainAnimated:u.grain.animated,depthOfFieldEnabled:u.depthOfFieldEnabled,depthOfFieldBlurLevel:u.depthOfFieldBlurLevel,lensSize:u.depthOfField.lensSize,fStop:u.depthOfField.fStop,focusDistance:u.depthOfField.focusDistance,focalLength:u.depthOfField.focalLength,vignetteEnabled:u.imageProcessing?.vignetteEnabled,vignetteColor:u.imageProcessing?.vignetteColor.asArray(),vignetteWeight:u.imageProcessing?.vignetteWeight,chromaticAberrationEnabled:u.chromaticAberrationEnabled,aberrationAmount:u.chromaticAberration.aberrationAmount,radialIntensity:u.chromaticAberration.radialIntensity,direction:u.chromaticAberration.direction.asArray(),centerPosition:u.chromaticAberration.centerPosition.asArray(),glowLayerEnabled:u.glowLayerEnabled,glowLayerIntensity:u.glowLayer?.intensity,glowLayerBlurKernelSize:u.glowLayer?.blurKernelSize,colorGradingEnabled:u.imageProcessing.colorGradingEnabled,colorGradingTexture:u.imageProcessing.colorGradingTexture?.serialize(),colorGradingWithGreenDepth:u.imageProcessing.imageProcessingConfiguration.colorGradingWithGreenDepth,colorCurvesEnabled:u.imageProcessing.colorCurvesEnabled,globalHue:u.imageProcessing.colorCurves?.globalHue,globalDensity:u.imageProcessing.colorCurves?.globalDensity,globalExposure:u.imageProcessing.colorCurves?.globalExposure,globalSaturation:u.imageProcessing.colorCurves?.globalSaturation,highlightsHue:u.imageProcessing.colorCurves?.highlightsHue,highlightsDensity:u.imageProcessing.colorCurves?.highlightsDensity,highlightsExposure:u.imageProcessing.colorCurves?.highlightsExposure,highlightsSaturation:u.imageProcessing.colorCurves?.highlightsSaturation,midtonesHue:u.imageProcessing.colorCurves?.midtonesHue,midtonesDensity:u.imageProcessing.colorCurves?.midtonesDensity,midtonesExposure:u.imageProcessing.colorCurves?.midtonesExposure,midtonesSaturation:u.imageProcessing.colorCurves?.midtonesSaturation,shadowsHue:u.imageProcessing.colorCurves?.shadowsHue,shadowsDensity:u.imageProcessing.colorCurves?.shadowsDensity,shadowsExposure:u.imageProcessing.colorCurves?.shadowsExposure,shadowsSaturation:u.imageProcessing.colorCurves?.shadowsSaturation}:null}a(Jt,"serializeDefaultRenderingPipeline");function ei(t,e,i,o,r){let n=u??yo(t,e,r);if(n.samples=r?.msaaSamples??1,n.fxaaEnabled=i.fxaaEnabled,n.imageProcessingEnabled=i.imageProcessingEnabled,n.imageProcessing){if(n.imageProcessing.exposure=i.exposure,n.imageProcessing.contrast=i.contrast,n.imageProcessing.fromLinearSpace=i.fromLinearSpace,n.imageProcessing.toneMappingEnabled=i.toneMappingEnabled,n.imageProcessing.toneMappingType=i.toneMappingType,n.imageProcessing.ditheringEnabled=i.ditheringEnabled,n.imageProcessing.ditheringIntensity=i.ditheringIntensity,n.imageProcessing.vignetteEnabled=i.vignetteEnabled??!1,n.imageProcessing.vignetteColor=uo.Color4.FromArray(i.vignetteColor??[0,0,0]),n.imageProcessing.vignetteWeight=i.vignetteWeight??.3,n.imageProcessing.colorGradingEnabled=i.colorGradingEnabled??!1,n.imageProcessing.imageProcessingConfiguration.colorGradingWithGreenDepth=i.colorGradingWithGreenDepth??!0,i.colorGradingTexture){let l=null;if(i.colorGradingTexture.customType==="BABYLON.ColorGradingTexture"){let p=o+i.colorGradingTexture.name;l=new vo.ColorGradingTexture(p,t),l.level=i.colorGradingTexture.level}else{let p=go.Texture.Parse(i.colorGradingTexture,t,o);Ae(p)&&(l=p)}n.imageProcessing.colorGradingTexture=l}n.imageProcessing.colorCurvesEnabled=i.colorCurvesEnabled??!1,n.imageProcessing.colorCurves&&(n.imageProcessing.colorCurves.globalHue=i.globalHue??30,n.imageProcessing.colorCurves.globalDensity=i.globalDensity??0,n.imageProcessing.colorCurves.globalExposure=i.globalExposure??0,n.imageProcessing.colorCurves.globalSaturation=i.globalSaturation??0,n.imageProcessing.colorCurves.highlightsHue=i.highlightsHue??30,n.imageProcessing.colorCurves.highlightsDensity=i.highlightsDensity??0,n.imageProcessing.colorCurves.highlightsExposure=i.highlightsExposure??0,n.imageProcessing.colorCurves.highlightsSaturation=i.highlightsSaturation??0,n.imageProcessing.colorCurves.midtonesHue=i.midtonesHue??30,n.imageProcessing.colorCurves.midtonesDensity=i.midtonesDensity??0,n.imageProcessing.colorCurves.midtonesExposure=i.midtonesExposure??0,n.imageProcessing.colorCurves.midtonesSaturation=i.midtonesSaturation??0,n.imageProcessing.colorCurves.shadowsHue=i.shadowsHue??30,n.imageProcessing.colorCurves.shadowsDensity=i.shadowsDensity??0,n.imageProcessing.colorCurves.shadowsExposure=i.shadowsExposure??0,n.imageProcessing.colorCurves.shadowsSaturation=i.shadowsSaturation??0)}return n.bloomEnabled=i.bloomEnabled,n.bloomThreshold=i.bloomThreshold,n.bloomWeight=i.bloomWeight,n.bloomScale=i.bloomScale,n.bloomKernel=i.bloomKernel,n.sharpenEnabled=i.sharpenEnabled,n.sharpen.edgeAmount=i.sharpenEdgeAmount,n.sharpen.colorAmount=i.sharpenColorAmount,n.grainEnabled=i.grainEnabled,n.grain.intensity=i.grainIntensity,n.grain.animated=i.grainAnimated,n.depthOfFieldEnabled=i.depthOfFieldEnabled,n.depthOfFieldBlurLevel=i.depthOfFieldBlurLevel,n.depthOfField.lensSize=i.lensSize,n.depthOfField.fStop=i.fStop,n.depthOfField.focusDistance=i.focusDistance,n.depthOfField.focalLength=i.focalLength,n.chromaticAberrationEnabled=i.chromaticAberrationEnabled??!1,n.chromaticAberration.aberrationAmount=i.aberrationAmount??10,n.chromaticAberration.radialIntensity=i.radialIntensity??1,n.chromaticAberration.direction=qt.Vector2.FromArray(i.direction??[0,0]),n.chromaticAberration.centerPosition=qt.Vector2.FromArray(i.centerPosition??[0,0]),n.glowLayerEnabled=i.glowLayerEnabled??!1,n.glowLayer&&(n.glowLayer.intensity=i.glowLayerIntensity??1,n.glowLayer.blurKernelSize=i.glowLayerBlurKernelSize??32),n}a(ei,"parseDefaultRenderingPipeline");var se="volumetricLighting",E=8,K=256,ri=4,bo=(i=>(i[i.Linear=0]="Linear",i[i.Exponential=1]="Exponential",i))(bo||{}),ni=(o=>(o[o.None=0]="None",o[o.Bayer=1]="Bayer",o[o.InterleavedGradientNoise=2]="InterleavedGradientNoise",o))(ni||{}),ai=(o=>(o[o.Exponential=0]="Exponential",o[o.ExponentialSquared=1]="ExponentialSquared",o[o.Linear=2]="Linear",o))(ai||{}),xo=(r=>(r[r.None=0]="None",r[r.Scattering=1]="Scattering",r[r.Transmittance=2]="Transmittance",r[r.LightCount=3]="LightCount",r))(xo||{});function oi(){return{enabled:!1,volumeIntensity:1,anisotropy:.35,useCustomColor:!1,color:[1,1,1],castVolumetricShadows:!0,shadowDarkness:1,rangeMultiplier:1,priority:0}}a(oi,"getDefaultVolumetricLightConfiguration");function Qe(){return{steps:40,lightSteps:0,resolutionScale:.5,stepDistribution:1,ditherMode:2,ditherStrength:1,temporalJitter:!1,fogMode:0,fogDensity:5e-4,fogStart:0,fogEnd:2e3,fogColor:[1,1,1],albedo:1,maxDistance:1e4,heightFogEnabled:!1,heightFogBaseHeight:0,heightFogFalloff:.01,intensity:1.5,lightExtinctionEnabled:!0,lightExtinctionClamp:1e3,extinctionAmount:0,ambientColor:[1,1,1],ambientIntensity:0,screenSpaceShadows:!0,screenSpaceShadowSteps:6,screenSpaceShadowBias:.02,screenSpaceShadowMaxDistance:2e3,screenSpaceShadowThickness:4,blurPasses:2,blurRadius:3,blurDepthThreshold:.02,upsampleDepthThreshold:.02,maxLights:128,maxShadowedLights:4,pcfTaps:4,selectionRefreshRate:2,debugMode:0}}a(Qe,"getDefaultVolumetricLightingConfiguration");function si(t){return t.lightSteps>0?t.lightSteps:Math.max(4,Math.min(64,Math.round(t.steps*.3)))}a(si,"getVolumetricLightSteps");function y(t,e,i,o){let r=typeof t=="number"&&isFinite(t)?t:e;return Math.min(o,Math.max(i,r))}a(y,"normalizeNumber");function ti(t,e){return!Array.isArray(t)||t.length<3?e.slice():[y(t[0],e[0],0,100),y(t[1],e[1],0,100),y(t[2],e[2],0,100)]}a(ti,"normalizeColor");function Co(t){let e=oi();return!t||typeof t!="object"?e:{enabled:t.enabled??e.enabled,volumeIntensity:y(t.volumeIntensity,e.volumeIntensity,0,1e3),anisotropy:y(t.anisotropy,e.anisotropy,-.95,.95),useCustomColor:t.useCustomColor??e.useCustomColor,color:ti(t.color,e.color),castVolumetricShadows:t.castVolumetricShadows??e.castVolumetricShadows,shadowDarkness:y(t.shadowDarkness,e.shadowDarkness,0,1),rangeMultiplier:y(t.rangeMultiplier,e.rangeMultiplier,0,100),priority:y(t.priority,e.priority,-1e3,1e3)}}a(Co,"normalizeVolumetricLightConfiguration");function Se(t){let e=Qe();return!t||typeof t!="object"?e:{steps:Math.round(y(t.steps,e.steps,4,256)),lightSteps:Math.round(y(t.lightSteps,e.lightSteps,0,128)),resolutionScale:y(t.resolutionScale,e.resolutionScale,.1,1),stepDistribution:Math.round(y(t.stepDistribution,e.stepDistribution,0,1)),ditherMode:Math.round(y(t.ditherMode,e.ditherMode,0,2)),ditherStrength:y(t.ditherStrength,e.ditherStrength,0,1),temporalJitter:t.temporalJitter??e.temporalJitter,fogMode:Math.round(y(t.fogMode,e.fogMode,0,2)),fogDensity:y(t.fogDensity,e.fogDensity,0,100),fogStart:y(t.fogStart,e.fogStart,0,1e6),fogEnd:Math.max(y(t.fogEnd,e.fogEnd,0,1e7),y(t.fogStart,e.fogStart,0,1e6)+.001),fogColor:ti(t.fogColor,e.fogColor),albedo:y(t.albedo,e.albedo,0,1),maxDistance:y(t.maxDistance,e.maxDistance,1,1e6),heightFogEnabled:t.heightFogEnabled??e.heightFogEnabled,heightFogBaseHeight:y(t.heightFogBaseHeight,e.heightFogBaseHeight,-1e6,1e6),heightFogFalloff:y(t.heightFogFalloff,e.heightFogFalloff,0,10),intensity:y(t.intensity,e.intensity,0,100),lightExtinctionEnabled:t.lightExtinctionEnabled??e.lightExtinctionEnabled,lightExtinctionClamp:y(t.lightExtinctionClamp,e.lightExtinctionClamp,0,1e6),extinctionAmount:y(t.extinctionAmount,e.extinctionAmount,0,1),ambientColor:ti(t.ambientColor,e.ambientColor),ambientIntensity:y(t.ambientIntensity,e.ambientIntensity,0,100),screenSpaceShadows:t.screenSpaceShadows??e.screenSpaceShadows,screenSpaceShadowSteps:Math.round(y(t.screenSpaceShadowSteps,e.screenSpaceShadowSteps,1,32)),screenSpaceShadowBias:y(t.screenSpaceShadowBias,e.screenSpaceShadowBias,0,1),screenSpaceShadowMaxDistance:y(t.screenSpaceShadowMaxDistance,e.screenSpaceShadowMaxDistance,1,1e7),screenSpaceShadowThickness:y(t.screenSpaceShadowThickness,e.screenSpaceShadowThickness,.01,1e3),blurPasses:Math.round(y(t.blurPasses,e.blurPasses,0,2)),blurRadius:Math.round(y(t.blurRadius,e.blurRadius,1,6)),blurDepthThreshold:y(t.blurDepthThreshold,e.blurDepthThreshold,1e-4,1),upsampleDepthThreshold:y(t.upsampleDepthThreshold,e.upsampleDepthThreshold,1e-4,1),maxLights:Math.round(y(t.maxLights,e.maxLights,0,K)),maxShadowedLights:Math.round(y(t.maxShadowedLights,e.maxShadowedLights,0,E)),pcfTaps:y(t.pcfTaps,e.pcfTaps,1,4)>=4?4:1,selectionRefreshRate:Math.round(y(t.selectionRefreshRate,e.selectionRefreshRate,1,60)),debugMode:Math.round(y(t.debugMode,e.debugMode,0,3))}}a(Se,"normalizeVolumetricLightingConfiguration");var ii=new WeakSet;function Lo(t){t.metadata??={};let e=t.metadata[se];if(!e||typeof e!="object")return t.metadata[se]=Co(null),ii.add(t.metadata[se]),t.metadata[se];if(ii.has(e))return e;let i=oi();return Object.keys(i).forEach(o=>{e[o]===void 0&&(e[o]=i[o])}),ii.add(e),e}a(Lo,"ensureVolumetricLightConfiguration");function li(t){let e=t.metadata?.[se];return e&&typeof e=="object"?Lo(t):null}a(li,"getVolumetricLightConfiguration");function Hn(t){return t.metadata?.[se]?.enabled===!0}a(Hn,"isVolumetricLightEnabled");var Je=require("babylonjs"),wo=require("babylonjs"),pi=require("babylonjs"),j=require("babylonjs"),mi=(o=>(o[o.Texture2D=0]="Texture2D",o[o.Sampler2DShadow=1]="Sampler2DShadow",o[o.Cube=2]="Cube",o))(mi||{}),Oo=(o=>(o[o.Standard=0]="Standard",o[o.Esm=1]="Esm",o[o.CloseEsm=2]="CloseEsm",o))(Oo||{}),hi=(o=>(o[o.Analytic=0]="Analytic",o[o.AnalyticHeight=1]="AnalyticHeight",o[o.Numeric=2]="Numeric",o))(hi||{}),Do=10,kn=4,Un=22,Wn=32,Xn=.15;function Me(t,e){let i=t.getCaps(),o=i.maxFragmentUniformVectors||224,r=t.isWebGPU?Math.floor(o/4):o,n=Math.max(224,r)-Wn,l=Math.max(8,i.maxTexturesImageUnits||16)-1,p=l>=2,s=p?Un:0,c=Math.max(0,Math.min(E,e.maxShadowedLights,l-(p?1:0),Math.floor((n-s)/Do))),m=Math.max(0,Math.min(K,e.maxLights,Math.floor((n-s-c*Do)/kn)));return{maxShadowSlots:c,maxArrayLights:m,maxDirectionalLights:Math.min(ri,m),allowCsm:p}}a(Me,"computeVolumetricBudget");function Eo(t){let e=[];return t.lights.forEach(i=>{pe(i)?i.lights.forEach(o=>{e.push({light:o,isClustered:!0})}):e.push({light:i,isClustered:!1})}),e}a(Eo,"getAllVolumetricCandidateLights");function To(t,e){let i=t.getShadowGenerator(e.activeCamera)??t.getShadowGenerator();if(!i||!Lt(i))return null;let o=i.getShadowMapForRendering();if(!o?.isReady())return null;let r=i.getShadowMap()?.getSize().width??1024,n=o.textureType===pi.Constants.TEXTURETYPE_UNSIGNED_BYTE,l=!ie(t),p=t.needCube?.()===!0;switch(i.filter){case j.ShadowGenerator.FILTER_PCF:case j.ShadowGenerator.FILTER_PCSS:return{generator:i,kind:p?2:1,mode:0,packed:n,mapSize:r,local:l};case j.ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP:case j.ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP:return{generator:i,kind:p?2:0,mode:1,packed:n,mapSize:r,local:l};case j.ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP:case j.ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP:return{generator:i,kind:p?2:0,mode:2,packed:n,mapSize:r,local:l};default:return{generator:i,kind:p?2:0,mode:0,packed:n,mapSize:r,local:l}}}a(To,"resolveVolumetricShadowSlot");function et(t,e){let i=t;return i.computeTransformedInformation?.()&&i.transformedPosition?e.copyFrom(i.transformedPosition):i.position?e.copyFrom(i.position):e.copyFromFloats(0,0,0),e}a(et,"getVolumetricLightWorldPosition");function Re(t,e){let i=t;return i.computeTransformedInformation?.()&&i.transformedDirection?e.copyFrom(i.transformedDirection):i.direction?e.copyFrom(i.direction):e.copyFromFloats(0,0,1),e.normalize()}a(Re,"getVolumetricLightWorldDirection");function tt(t,e,i){let o=t.range>0&&t.range<Number.MAX_VALUE?t.range:i.maxDistance;return Math.max(.001,Math.min(o*e.rangeMultiplier,34e37))}a(tt,"getVolumetricLightRange");var ci=new Je.Vector3,_o=new Je.Vector3;function $n(t,e,i){if(et(t,i),!ne(t))return e;let o=Math.cos(t.angle*.5);if(o<=.5)return e;let r=e/(2*o);return Re(t,_o),i.addInPlace(_o.scaleInPlace(r)),r}a($n,"computeVolumetricLightBounds");function Kn(t,e,i){for(let o=0;o<i.length;++o)if(i[o].dotCoordinate(t)<=-e)return!1;return!0}a(Kn,"isSphereInFrustum");function Po(t){return(t.local?64:0)+t.kind*16+t.mode*4+(t.packed?1:0)}a(Po,"getShadowSlotSignature");function di(t,e,i,o,r){let n={candidateCount:0,culledCount:0,shadowedCount:0,unshadowedCount:0,droppedCount:0,perLight:new Map},l=wo.Frustum.GetPlanes(t.getTransformMatrix()),p=e.globalPosition,s=[];Eo(t).forEach(({light:v,isClustered:C})=>{let V=li(v);if(!V?.enabled)return;if(n.candidateCount++,Ye(v)||!v.isEnabled()||v.intensity<=0||V.volumeIntensity<=0){n.perLight.set(v.uniqueId,{state:"disabled",slot:-1,reason:Ye(v)?"Hemispheric lights have no position nor direction and can't produce light shafts.":"The light is disabled or its intensity is zero."});return}let X=ie(v),ce=V.priority*1e3;if(X)ce+=1e6;else{let Ke=Math.min(tt(v,V,i),i.maxDistance),xt=$n(v,Ke,ci);if(!Kn(ci,xt,l)){n.culledCount++,n.perLight.set(v.uniqueId,{state:"culled",slot:-1,reason:"The light is outside of the frustum of the camera and doesn't reach it."});return}let Sn=Math.max(1,Je.Vector3.Distance(ci,p)-xt);ce+=V.volumeIntensity*v.intensity*Math.min(4,xt/Sn)}s.push({light:v,config:V,isClustered:C,typeId:v.getTypeID(),score:ce})}),s.sort((v,C)=>C.score-v.score);let c=new Map;r?.shadowed.forEach((v,C)=>{c.set(v.candidate.light.uniqueId,C)});let m=[],h=[],d=new Map,f=null;s.forEach(v=>{let{light:C,config:V}=v;if(!V.castVolumetricShadows){d.set(C.uniqueId,"occlusion is disabled on this light."),h.push(v);return}if(v.isClustered){d.set(C.uniqueId,"clustered lighting doesn't support shadow maps."),h.push(v);return}if(!C.shadowEnabled||!t.shadowsEnabled){d.set(C.uniqueId,"shadows are disabled on this light or on the scene."),h.push(v);return}let X=C.getShadowGenerator(t.activeCamera)??C.getShadowGenerator();if(!X){d.set(C.uniqueId,"the light has no shadow generator."),h.push(v);return}if(Dt(X)&&o.allowCsm){let Ke=X.getShadowMapForRendering();if(!f&&Ke?.isReady()){f={candidate:v,generator:X,cascades:X.numCascades,kind:X.filter===j.ShadowGenerator.FILTER_PCF||X.filter===j.ShadowGenerator.FILTER_PCSS?1:0,packed:Ke.textureType===pi.Constants.TEXTURETYPE_UNSIGNED_BYTE};return}d.set(C.uniqueId,f?"another light already uses the single cascaded shadow map slot.":"its cascaded shadow map is not ready yet."),h.push(v);return}let ce=To(C,t);if(!ce){d.set(C.uniqueId,"the shadow map of the light is not ready yet."),h.push(v);return}m.push({candidate:v,shadow:ce})});function S(v){let C=v.candidate.score;return c.get(v.candidate.light.uniqueId)===void 0?C:C+Math.abs(C)*Xn}a(S,"getHysteresisScore");function g(v){return c.get(v.candidate.light.uniqueId)??Number.MAX_SAFE_INTEGER}a(g,"getPreviousSlot"),m.sort((v,C)=>{let V=S(C)-S(v);return V!==0?V:g(v)-g(C)});let b=m.slice(0,o.maxShadowSlots);b.sort((v,C)=>Po(v.shadow)-Po(C.shadow)||g(v)-g(C)),m.slice(o.maxShadowSlots).forEach(v=>{d.set(v.candidate.light.uniqueId,"the shadowed lights budget is full."),h.push(v.candidate)}),h.sort((v,C)=>C.score-v.score);let L=[],_=[],x=[];h.forEach(v=>{ie(v.light)?L.length<o.maxDirectionalLights?L.push(v):x.push({candidate:v,reason:`Not rendered: at most ${o.maxDirectionalLights} directional light(s) without a shadow map can take part in the effect.`}):_.push(v)});let R=Math.max(0,o.maxArrayLights-L.length);_.slice(R).forEach(v=>{x.push({candidate:v,reason:'Not rendered: the lights budget is full. Raise "Max Lights" or lower the priority of the other lights.'})});let G=L.concat(_.slice(0,R));if(b.forEach((v,C)=>{n.shadowedCount++,n.perLight.set(v.candidate.light.uniqueId,{state:"shadowed",slot:C,reason:`Casting volumetric shadows using slot ${C+1} of ${o.maxShadowSlots}.`})}),f){let v=f;n.shadowedCount++,n.perLight.set(v.candidate.light.uniqueId,{state:"shadowed",slot:-1,reason:`Casting volumetric shadows using its ${v.cascades} shadow cascades.`})}return G.forEach(v=>{n.unshadowedCount++;let C=v.config.castVolumetricShadows?"Occluded using the depth buffer":"Not occluded by the geometry",V=d.get(v.light.uniqueId)??"the light has no shadow map.";n.perLight.set(v.light.uniqueId,{state:"unshadowed",slot:-1,reason:`${C}: ${V}`})}),x.forEach(({candidate:v,reason:C})=>{n.droppedCount++,n.perLight.set(v.light.uniqueId,{state:"dropped",slot:-1,reason:C})}),{shadowed:b,unshadowed:G,directionalCount:L.length,csm:f,stats:n}}a(di,"selectVolumetricLights");function jn(t,e,i){let o=t.shadowed.map(n=>`${n.shadow.kind}.${n.shadow.mode}.${n.shadow.packed?1:0}.${n.shadow.local?1:0}`).join("|"),r=t.csm?`${t.csm.kind}.${t.csm.cascades}.${t.csm.packed?1:0}`:"-";return[e.steps,i.lightSteps,e.stepDistribution,e.ditherMode,e.temporalJitter?1:0,e.heightFogEnabled?1:0,e.lightExtinctionEnabled?1:0,e.pcfTaps,e.blurRadius,e.debugMode,e.screenSpaceShadows?e.screenSpaceShadowSteps:0,i.fogMode,i.transmittance,i.depthMode,i.ldrEncode?1:0,i.reverseDepth?1:0,i.ndcHalfZ?1:0,i.linearDepthPacked?1:0,i.arrayLightCapacity,t.directionalCount,o,r].join(",")}a(jn,"computeVolumetricShapeKey");function Zn(t){return Ct(t)||ne(t)||ie(t)}a(Zn,"isVolumetricLightSupported");var fi=require("babylonjs"),Yn=0,ui=(o=>(o[o.DepthRenderer=0]="DepthRenderer",o[o.GeometryBuffer=1]="GeometryBuffer",o[o.PrePass=2]="PrePass",o))(ui||{}),Ao="volumetricLighting";function gi(){return{name:Ao,enabled:!1,texturesRequired:[fi.Constants.PREPASS_DEPTH_TEXTURE_TYPE]}}a(gi,"createVolumetricLightingPrePassConfiguration");function ye(t){return t.prePassRenderer??null}a(ye,"getVolumetricPrePassRenderer");function Ve(t){return t.geometryBufferRenderer??null}a(Ve,"getVolumetricGeometryBufferRenderer");function Io(t){let e=t.getCaps();return e.textureFloat&&e.textureFloatLinearFiltering||e.textureHalfFloat&&e.textureHalfFloatLinearFiltering}a(Io,"supportsVolumetricFloatDepthTexture");function it(t){return Io(t.getEngine())?ye(t)?.isSupported?2:Ve(t)?.isSupported?1:0:0}a(it,"resolveVolumetricDepthSource");function vi(t){let e=t.getIndex(fi.Constants.PREPASS_DEPTH_TEXTURE_TYPE);return e===void 0||e<0?null:t.getRenderTarget()?.textures?.[e]??null}a(vi,"getVolumetricPrePassDepthTexture");function Si(t){if(!t.enableDepth)return null;let e=t.getTextureIndex(Yn);return e<0?null:t.getGBuffer()?.textures?.[e]??null}a(Si,"getVolumetricGeometryBufferDepthTexture");var ot=`
2
+ fn volUnpack(color: vec4f) -> f32 {
3
+ let bitShift = vec4f(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
4
+ return dot(color, bitShift);
5
+ }
6
+ `,qn=`
7
+ // Loads the texel under the given coordinates rather than filtering: the 32 bits float textures of the prepass
8
+ // renderer are not filterable on WebGPU. @see the GLSL version.
9
+ fn volSampleDepth(uv: vec2f) -> f32 {
10
+ let size = vec2i(textureDimensions(depthSampler));
11
+ let coordinates = min(vec2i(uv * vec2f(size)), size - 1);
12
+
13
+ #ifdef VOL_DEPTH_PACKED
14
+ return volUnpack(textureLoad(depthSampler, coordinates, 0));
15
+ #else
16
+ return textureLoad(depthSampler, coordinates, 0).r;
17
+ #endif
18
+ }
19
+
20
+ // Converts the raw value stored in the depth map into a distance along the view axis, in scene units.
21
+ fn volLinearDepth(d: f32) -> f32 {
22
+ #ifdef VOL_DEPTH_VIEWZ
23
+ // The view space Z is stored directly, negative in a right handed scene. The sky is cleared to 0.
24
+ let viewZ = abs(d);
25
+ return select(viewZ, uniforms.volCameraMinMaxZ.y, viewZ <= 0.0);
26
+ #else
27
+ // The depth renderer stores "(clipZ + minZ) / (minZ + maxZ)", which is affine in the view space Z
28
+ // for both the perspective and the orthographic projections. "volDepthUnpack" holds the two
29
+ // coefficients of the exact inverse, computed on the CPU from the projection matrix of the scene.
30
+ return uniforms.volDepthUnpack.x * d + uniforms.volDepthUnpack.y;
31
+ #endif
32
+ }
33
+ `;function yi(t){return`
34
+ // Returns the distance along the view axis, in scene units, of the texel at the given coordinates.
35
+ fn volReadLinearDepth(coordinates: vec2i) -> f32 {
36
+ #ifdef VOL_LINEAR_DEPTH_PACKED
37
+ return volUnpack(textureLoad(${t}, coordinates, 0)) * uniforms.volCameraMinMaxZ.y;
38
+ #else
39
+ return textureLoad(${t}, coordinates, 0).r;
40
+ #endif
41
+ }
42
+
43
+ // Returns the texel of the linear depth under the center of the given texel of the scattering buffer.
44
+ // @see the GLSL version.
45
+ fn volScatterToDepthTexel(scatterTexel: vec2i, depthSize: vec2i) -> vec2i {
46
+ return min(vec2i((vec2f(scatterTexel) + 0.5) * uniforms.volDepthRatio), depthSize - 1);
47
+ }
48
+ `}a(yi,"buildLinearDepthHelpers");function Qn(){return`
49
+ varying vUV: vec2f;
50
+
51
+ var textureSamplerSampler: sampler;
52
+ var textureSampler: texture_2d<f32>;
53
+ var depthSampler: texture_2d<f32>;
54
+
55
+ uniform volCameraMinMaxZ: vec2f;
56
+ uniform volDepthUnpack: vec2f;
57
+
58
+ ${ot}
59
+ ${qn}
60
+
61
+ fn volPack(depth: f32) -> vec4f {
62
+ let bitShift = vec4f(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0);
63
+ let bitMask = vec4f(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
64
+
65
+ var result = fract(depth * bitShift);
66
+ result -= result.xxyz * bitMask;
67
+
68
+ return result;
69
+ }
70
+
71
+ @fragment
72
+ fn main(input: FragmentInputs) -> FragmentOutputs {
73
+ let viewZ = volLinearDepth(volSampleDepth(input.vUV));
74
+
75
+ #ifdef VOL_LINEAR_DEPTH_PACKED
76
+ fragmentOutputs.color = volPack(clamp(viewZ / uniforms.volCameraMinMaxZ.y, 0.0, 0.9999999));
77
+ #else
78
+ fragmentOutputs.color = vec4f(viewZ, 0.0, 0.0, 1.0);
79
+ #endif
80
+ }
81
+ `}a(Qn,"buildVolumetricLightingLinearDepthShaderWGSL");function Mo(t,e){return`
82
+ let chordLength = t1 - t0;
83
+
84
+ // The point of the view ray closest to the light splits the chord in two halves over which both the
85
+ // attenuation and the phase function are monotonic, which is where stratified samples do best.
86
+ var closest = clamp(dot(data.xyz, volRayDir), t0, t1);
87
+ if (closest - t0 < 0.02 * chordLength) {
88
+ closest = t0;
89
+ } else if (t1 - closest < 0.02 * chordLength) {
90
+ closest = t1;
91
+ }
92
+
93
+ let count = volLocalSampleCount(chordLength, falloff.x, tEnd - tStart);
94
+
95
+ var firstCount = clamp(i32(f32(count) * (closest - t0) / chordLength + 0.5), 1, count - 1);
96
+ if (closest <= t0) {
97
+ firstCount = 0;
98
+ } else if (closest >= t1) {
99
+ firstCount = count;
100
+ }
101
+
102
+ let firstWidth = (closest - t0) / f32(max(firstCount, 1));
103
+ let secondWidth = (t1 - closest) / f32(max(count - firstCount, 1));
104
+ let stratum = volStratumOffset(${t});
105
+
106
+ var result = vec3f(0.0);
107
+
108
+ for (var k: i32 = 0; k < VOL_LOCAL_MAX_STEPS; k++) {
109
+ if (k >= count) {
110
+ break;
111
+ }
112
+
113
+ let inFirstHalf = k < firstCount;
114
+ let width = select(secondWidth, firstWidth, inFirstHalf);
115
+ let t = select(closest + width * (f32(k - firstCount) + stratum), t0 + width * (f32(k) + stratum), inFirstHalf);
116
+
117
+ let position = volRayDir * t;
118
+ let sigmaT = volExtinctionAt(uniforms.volCameraPosition.y + position.y, t);
119
+
120
+ let lightSample = volEvalLocalLight(data, diffuse, direction, falloff, position);
121
+ var contribution = lightSample.xyz;
122
+ let distanceToLight = lightSample.w;
123
+
124
+ if (contribution.r + contribution.g + contribution.b > 0.0) {
125
+ ${e}
126
+ result += contribution * (volCombinedTransmittance(t, sigmaT, distanceToLight) * sigmaT * width);
127
+ }
128
+ }
129
+
130
+ return vec4f(result, 1.0);
131
+ `}a(Mo,"buildLocalLightIntegrationWGSL");function Jn(t){let e=[],i=[],o=[];for(let r=0;r<t;++r)e.push(`
132
+ #if VOL_SHADOW_SLOT_COUNT > {X}
133
+ #if VOL_SHADOW_KIND{X} == 2
134
+ var volShadowSampler{X}Sampler: sampler;
135
+ var volShadowSampler{X}: texture_cube<f32>;
136
+ #elif VOL_SHADOW_KIND{X} == 1
137
+ var volShadowSampler{X}Sampler: sampler_comparison;
138
+ var volShadowSampler{X}: texture_depth_2d;
139
+ #else
140
+ var volShadowSampler{X}Sampler: sampler;
141
+ var volShadowSampler{X}: texture_2d<f32>;
142
+ #endif
143
+
144
+ // Returns the shadowing of a point given its position relative to the camera and, for the 2d shadow maps, its
145
+ // position in the clip space of the light. @see the GLSL version.
146
+ fn volShadow{X}(position: vec3f, clip: vec4f) -> f32 {
147
+ let info = uniforms.volShadowInfo[{X}];
148
+ let edge = uniforms.volShadowLightFalloff[{X}].z;
149
+
150
+ #if VOL_SHADOW_KIND{X} == 2
151
+ // Cube shadow map of a point light. It stores the radial distance to the light.
152
+ var toFragment = position - uniforms.volShadowLightData[{X}].xyz;
153
+ let depth = clamp((length(toFragment) + info.z) / info.w, 0.0, 1.0);
154
+
155
+ toFragment = normalize(toFragment);
156
+ toFragment.y = -toFragment.y;
157
+
158
+ #ifdef VOL_SHADOW_PACKED{X}
159
+ let shadowMapSample = volUnpack(textureSampleLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, toFragment, 0.0));
160
+ #else
161
+ let shadowMapSample = textureSampleLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, toFragment, 0.0).x;
162
+ #endif
163
+
164
+ #if VOL_SHADOW_MODE{X} == 1
165
+ // Exponential shadow map, same encoding as the 2d case. "info.y" holds the depth scale.
166
+ return 1.0 - clamp(exp(min(87.0, info.y * depth)) * shadowMapSample, 0.0, 1.0 - info.x);
167
+ #elif VOL_SHADOW_MODE{X} == 2
168
+ return clamp(exp(min(87.0, -info.y * (depth - shadowMapSample))), info.x, 1.0);
169
+ #else
170
+ return select(1.0, info.x, depth > shadowMapSample);
171
+ #endif
172
+ #else
173
+ let clipSpace = clip.xyz / clip.w;
174
+
175
+ // "getTransformMatrix" gives the world to light clip space matrix without the [-1, 1] -> [0, 1] bias.
176
+ #if VOL_SHADOW_KIND{X} == 1
177
+ var uvDepth = 0.5 * clipSpace + vec3f(0.5);
178
+ #ifdef VOL_NDC_HALF_Z
179
+ uvDepth.z = clipSpace.z;
180
+ #endif
181
+
182
+ // Same guard as "computeShadowWithPCF1": past the far plane of the shadow map the hardware
183
+ // comparison would fail against every texel a caster wrote, reporting the sample as occluded
184
+ // while the surfaces at the same distance are lit by the material path.
185
+ let pcfDepthMetric = volDepthMetric(clip, info.zw);
186
+ if (pcfDepthMetric < 0.0 || pcfDepthMetric > 1.0 || uvDepth.x < 0.0 || uvDepth.x > 1.0 || uvDepth.y < 0.0 || uvDepth.y > 1.0) {
187
+ return 1.0;
188
+ }
189
+
190
+ // Hardware comparison sampling. "info.y" holds the inverse of the size of the shadow map.
191
+ #if VOL_PCF_TAPS == 4
192
+ let shadow = 0.25 * (
193
+ textureSampleCompareLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, uvDepth.xy + vec2f(-0.5 * info.y, -0.5 * info.y), uvDepth.z) +
194
+ textureSampleCompareLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, uvDepth.xy + vec2f( 0.5 * info.y, -0.5 * info.y), uvDepth.z) +
195
+ textureSampleCompareLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, uvDepth.xy + vec2f(-0.5 * info.y, 0.5 * info.y), uvDepth.z) +
196
+ textureSampleCompareLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, uvDepth.xy + vec2f( 0.5 * info.y, 0.5 * info.y), uvDepth.z)
197
+ );
198
+ #else
199
+ let shadow = textureSampleCompareLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, uvDepth.xy, uvDepth.z);
200
+ #endif
201
+
202
+ return volFallOff(mix(info.x, 1.0, shadow), clipSpace.xy, edge);
203
+ #else
204
+ let uv = 0.5 * clipSpace.xy + vec2f(0.5);
205
+ if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
206
+ return 1.0;
207
+ }
208
+
209
+ let depthMetric = clamp(volDepthMetric(clip, info.zw), 0.0, 1.0);
210
+
211
+ #ifdef VOL_SHADOW_PACKED{X}
212
+ let shadowMapSample = volUnpack(textureSampleLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, uv, 0.0));
213
+ #else
214
+ let shadowMapSample = textureSampleLevel(volShadowSampler{X}, volShadowSampler{X}Sampler, uv, 0.0).x;
215
+ #endif
216
+
217
+ #if VOL_SHADOW_MODE{X} == 1
218
+ // Exponential shadow map. "info.y" holds the depth scale of the generator.
219
+ return volFallOff(1.0 - clamp(exp(min(87.0, info.y * depthMetric)) * shadowMapSample, 0.0, 1.0 - info.x), clipSpace.xy, edge);
220
+ #elif VOL_SHADOW_MODE{X} == 2
221
+ // Close exponential shadow map.
222
+ return volFallOff(clamp(exp(min(87.0, -info.y * (depthMetric - shadowMapSample))), info.x, 1.0), clipSpace.xy, edge);
223
+ #else
224
+ return select(1.0, volFallOff(info.x, clipSpace.xy, edge), depthMetric > shadowMapSample);
225
+ #endif
226
+ #endif
227
+ #endif
228
+ }
229
+
230
+ #if VOL_SHADOW_LOCAL{X} == 1
231
+ // Point or spot light casting volumetric shadows: integrated over its own volume, like the others.
232
+ fn volIntegrateShadowSlot{X}(tStart: f32, tEnd: f32) -> vec4f {
233
+ let data = uniforms.volShadowLightData[{X}];
234
+ let direction = uniforms.volShadowLightDirection[{X}];
235
+ let falloff = uniforms.volShadowLightFalloff[{X}];
236
+
237
+ let chord = volLightChord(data, direction, falloff.x);
238
+ let t0 = max(chord.x, tStart);
239
+ let t1 = min(chord.y, tEnd);
240
+
241
+ if (t1 <= t0) {
242
+ return vec4f(0.0);
243
+ }
244
+
245
+ let diffuse = uniforms.volShadowLightDiffuse[{X}];
246
+
247
+ // The light clip space position of the points of the view ray is affine in their distance to the camera.
248
+ let clipOrigin = uniforms.volShadowMatrix[{X}] * vec4f(uniforms.volCameraPosition, 1.0);
249
+ let clipDirection = uniforms.volShadowMatrix[{X}] * vec4f(volRayDir, 0.0);
250
+ ${Mo("f32({X}) + 0.5","contribution *= mix(1.0, volShadow{X}(position, clipOrigin + clipDirection * t), falloff.w);")}
251
+ }
252
+ #endif
253
+ #endif
254
+ `.replace(/\{X\}/g,r.toString())),i.push(`
255
+ #if VOL_SHADOW_SLOT_COUNT > {X}
256
+ #if VOL_SHADOW_LOCAL{X} == 0
257
+ {
258
+ // Recomputed rather than kept affine to keep fewer registers alive across the march. @see the GLSL version.
259
+ let shadow = volShadow{X}(position, uniforms.volShadowMatrix[{X}] * vec4f(uniforms.volCameraPosition + position, 1.0));
260
+ scattering += volEvalDirectionalLight(uniforms.volShadowLightData[{X}], uniforms.volShadowLightDiffuse[{X}]) * mix(1.0, shadow, uniforms.volShadowLightFalloff[{X}].w);
261
+ stepLights += 1.0;
262
+ }
263
+ #endif
264
+ #endif
265
+ `.replace(/\{X\}/g,r.toString())),o.push(`
266
+ #if VOL_SHADOW_SLOT_COUNT > {X}
267
+ #if VOL_SHADOW_LOCAL{X} == 1
268
+ lightResult = volIntegrateShadowSlot{X}(tStart, tEnd);
269
+ accumulated += lightResult.xyz;
270
+ evaluatedLights += lightResult.w;
271
+ #endif
272
+ #endif
273
+ `.replace(/\{X\}/g,r.toString()));return`
274
+ varying vUV: vec2f;
275
+
276
+ // Full resolution linear depth of the scene, written by the linear depth pass.
277
+ var textureSampler: texture_2d<f32>;
278
+
279
+ // Ratio between the resolution of the linear depth and the resolution of the scattering buffer.
280
+ uniform volDepthRatio: vec2f;
281
+
282
+ uniform volInverseViewProjection: mat4x4f;
283
+ uniform volCameraPosition: vec3f;
284
+ uniform volCameraForward: vec3f;
285
+ uniform volCameraMinMaxZ: vec2f;
286
+ uniform volFrameIndex: f32;
287
+
288
+ uniform volFogInfos: vec4f;
289
+ uniform volFogColor: vec3f;
290
+ uniform volLinearFogEps: f32;
291
+ uniform volMedium: vec4f;
292
+
293
+ #ifdef VOL_SCREEN_SHADOWS
294
+ uniform volViewProjection: mat4x4f;
295
+ uniform volScreenShadowParams: vec4f;
296
+ #endif
297
+ uniform volAmbient: vec3f;
298
+
299
+ // (maximum distance, dithering strength, light extinction clamp, number of point and spot lights in the arrays)
300
+ uniform volParams: vec4f;
301
+
302
+ #if VOL_MAX_ARRAY_LIGHTS > 0
303
+ uniform volLightData: array<vec4f, VOL_MAX_ARRAY_LIGHTS>;
304
+ uniform volLightDiffuse: array<vec4f, VOL_MAX_ARRAY_LIGHTS>;
305
+ uniform volLightDirection: array<vec4f, VOL_MAX_ARRAY_LIGHTS>;
306
+ uniform volLightFalloff: array<vec4f, VOL_MAX_ARRAY_LIGHTS>;
307
+ #endif
308
+
309
+ #if VOL_SHADOW_SLOT_COUNT > 0
310
+ uniform volShadowLightData: array<vec4f, VOL_SHADOW_SLOT_COUNT>;
311
+ uniform volShadowLightDiffuse: array<vec4f, VOL_SHADOW_SLOT_COUNT>;
312
+ uniform volShadowLightDirection: array<vec4f, VOL_SHADOW_SLOT_COUNT>;
313
+ uniform volShadowLightFalloff: array<vec4f, VOL_SHADOW_SLOT_COUNT>;
314
+ uniform volShadowInfo: array<vec4f, VOL_SHADOW_SLOT_COUNT>;
315
+ uniform volShadowMatrix: array<mat4x4f, VOL_SHADOW_SLOT_COUNT>;
316
+ #endif
317
+
318
+ #ifdef VOL_CSM
319
+ uniform volCsmLightData: vec4f;
320
+ uniform volCsmLightDiffuse: vec4f;
321
+ uniform volCsmLightDirection: vec4f;
322
+ uniform volCsmLightFalloff: vec4f;
323
+ uniform volCsmInfo: vec4f;
324
+ uniform volCsmMatrices: array<mat4x4f, VOL_CSM_CASCADES>;
325
+
326
+ #if VOL_CSM_KIND == 1
327
+ var volCsmSamplerSampler: sampler_comparison;
328
+ var volCsmSampler: texture_depth_2d_array;
329
+ #else
330
+ var volCsmSamplerSampler: sampler;
331
+ var volCsmSampler: texture_2d_array<f32>;
332
+ #endif
333
+ #endif
334
+
335
+ // Values shared by every function of the pass, computed once per pixel. Every position the raymarching
336
+ // manipulates is relative to the camera, which keeps the precision of the lights far from the origin.
337
+ var<private> volRayDir: vec3f;
338
+ var<private> volCosForward: f32;
339
+ var<private> volNoise: f32;
340
+ var<private> volJitter: f32;
341
+
342
+ #ifdef VOL_SCREEN_SHADOWS
343
+ var<private> volDepthSize: vec2i;
344
+ var<private> volClipOrigin: vec4f;
345
+ var<private> volClipDirection: vec4f;
346
+ #endif
347
+
348
+ ${ot}
349
+ ${yi("textureSampler")}
350
+
351
+ fn volMod(x: f32, y: f32) -> f32 {
352
+ return x - y * floor(x / y);
353
+ }
354
+
355
+ fn volFallOff(value: f32, clipSpaceXY: vec2f, frustumEdgeFalloff: f32) -> f32 {
356
+ let mask = smoothstep(1.0 - frustumEdgeFalloff, 1.00000012, clamp(dot(clipSpaceXY, clipSpaceXY), 0.0, 1.0));
357
+ return mix(value, 1.0, mask);
358
+ }
359
+
360
+ // Reproduces the depth metric computed by the "shadowsVertex" include of Babylon.js: the raw clip space
361
+ // Z is used, without the perspective divide, so the comparison matches what the shadow map stores.
362
+ fn volDepthMetric(clip: vec4f, depthValues: vec2f) -> f32 {
363
+ #ifdef VOL_REVERSE_DEPTH
364
+ return (-clip.z + depthValues.x) / depthValues.y;
365
+ #else
366
+ return (clip.z + depthValues.x) / depthValues.y;
367
+ #endif
368
+ }
369
+
370
+ // Henyey-Greenstein phase function, normalised to 1 for an isotropic medium. @see the GLSL version.
371
+ fn volPhaseHG(c: f32, g: f32) -> f32 {
372
+ let g2 = g * g;
373
+ let d = max(1.0 + g2 - 2.0 * g * c, 1e-4);
374
+ return (1.0 - g2) / (d * sqrt(d));
375
+ }
376
+
377
+ fn volBayer4(p: vec2f) -> f32 {
378
+ let p1 = vec2f(volMod(floor(p.x), 2.0), volMod(floor(p.y), 2.0));
379
+ let p2 = vec2f(volMod(floor(p.x * 0.5), 2.0), volMod(floor(p.y * 0.5), 2.0));
380
+
381
+ let b1 = 2.0 * p1.x + 3.0 * p1.y - 4.0 * p1.x * p1.y;
382
+ let b2 = 2.0 * p2.x + 3.0 * p2.y - 4.0 * p2.x * p2.y;
383
+
384
+ return (b1 * 4.0 + b2) / 16.0;
385
+ }
386
+
387
+ fn volInterleavedGradientNoise(p: vec2f) -> f32 {
388
+ return fract(52.9829189 * fract(dot(p, vec2f(0.06711056, 0.00583715))));
389
+ }
390
+
391
+ // Returns the offset of the samples of a light inside their strata. @see the GLSL version.
392
+ fn volStratumOffset(seed: f32) -> f32 {
393
+ #if VOL_DITHER == 0
394
+ return 0.5;
395
+ #else
396
+ return mix(0.5, fract(volNoise + seed * 0.618034), uniforms.volParams.y);
397
+ #endif
398
+ }
399
+
400
+ // sigma(t) = -d/dt ln(T(t)), the exact analytic derivative of the optical depth. @see the GLSL version.
401
+ fn volFogExtinction(t: f32) -> f32 {
402
+ #if VOL_FOG_MODE == 2
403
+ return select(1.0 / max(uniforms.volFogInfos.z - t, uniforms.volLinearFogEps), 0.0, t < uniforms.volFogInfos.y);
404
+ #elif VOL_FOG_MODE == 1
405
+ return 2.0 * uniforms.volFogInfos.w * uniforms.volFogInfos.w * t;
406
+ #else
407
+ return uniforms.volFogInfos.w;
408
+ #endif
409
+ }
410
+
411
+ // "height" is the absolute altitude of the sample, "t" its distance to the camera.
412
+ fn volExtinctionAt(height: f32, t: f32) -> f32 {
413
+ var sigma = volFogExtinction(t);
414
+
415
+ #ifdef VOL_HEIGHT_FOG
416
+ sigma *= exp(-max(0.0, height - uniforms.volMedium.y) * uniforms.volMedium.z);
417
+ #endif
418
+
419
+ return sigma;
420
+ }
421
+
422
+ // Transmittance of the medium between the camera and the point of the view ray at the distance "t".
423
+ // @see the GLSL version.
424
+ #if VOL_TRANSMITTANCE == 1
425
+ fn volHeightSegment(s1: f32, s2: f32) -> f32 {
426
+ let y0 = uniforms.volCameraPosition.y - uniforms.volMedium.y;
427
+ let h1 = y0 + s1 * volRayDir.y;
428
+ let h2 = y0 + s2 * volRayDir.y;
429
+
430
+ if (h1 + h2 <= 0.0) {
431
+ return s2 - s1;
432
+ }
433
+
434
+ let e1 = exp(-uniforms.volMedium.z * max(h1, 0.0));
435
+ let e2 = exp(-uniforms.volMedium.z * max(h2, 0.0));
436
+ let slope = uniforms.volMedium.z * volRayDir.y;
437
+
438
+ return select((e1 - e2) / slope, 0.5 * (e1 + e2) * (s2 - s1), abs(slope * (s2 - s1)) < 1e-4);
439
+ }
440
+
441
+ fn volOpticalDepth(t: f32) -> f32 {
442
+ let crossing = select(-1.0, (uniforms.volMedium.y - uniforms.volCameraPosition.y) / volRayDir.y, abs(volRayDir.y) > 1e-6);
443
+
444
+ var opticalLength = 0.0;
445
+ if (crossing > 0.0 && crossing < t) {
446
+ opticalLength = volHeightSegment(0.0, crossing) + volHeightSegment(crossing, t);
447
+ } else {
448
+ opticalLength = volHeightSegment(0.0, t);
449
+ }
450
+
451
+ return uniforms.volFogInfos.w * opticalLength;
452
+ }
453
+
454
+ fn volTransmittance(t: f32) -> f32 {
455
+ return exp(-volOpticalDepth(t));
456
+ }
457
+ #elif VOL_TRANSMITTANCE == 2
458
+ var<private> volOpticalDepths: array<f32, VOL_TRANSMITTANCE_SAMPLES + 1>;
459
+ var<private> volOpticalDepthStart: f32;
460
+ var<private> volOpticalDepthScale: f32;
461
+
462
+ fn volBuildOpticalDepths(tStart: f32, tEnd: f32) {
463
+ let stepSize = (tEnd - tStart) / f32(VOL_TRANSMITTANCE_SAMPLES);
464
+
465
+ volOpticalDepthStart = tStart;
466
+ volOpticalDepthScale = 1.0 / stepSize;
467
+
468
+ var previous = volExtinctionAt(uniforms.volCameraPosition.y + volRayDir.y * tStart, tStart);
469
+ var opticalDepth = previous * tStart;
470
+
471
+ volOpticalDepths[0] = opticalDepth;
472
+
473
+ for (var i: i32 = 1; i <= VOL_TRANSMITTANCE_SAMPLES; i++) {
474
+ let t = tStart + stepSize * f32(i);
475
+ let sigma = volExtinctionAt(uniforms.volCameraPosition.y + volRayDir.y * t, t);
476
+
477
+ opticalDepth += 0.5 * (previous + sigma) * stepSize;
478
+ volOpticalDepths[i] = opticalDepth;
479
+ previous = sigma;
480
+ }
481
+ }
482
+
483
+ fn volOpticalDepth(t: f32) -> f32 {
484
+ let x = clamp((t - volOpticalDepthStart) * volOpticalDepthScale, 0.0, f32(VOL_TRANSMITTANCE_SAMPLES));
485
+ let i = min(i32(x), VOL_TRANSMITTANCE_SAMPLES - 1);
486
+
487
+ return mix(volOpticalDepths[i], volOpticalDepths[i + 1], x - f32(i));
488
+ }
489
+
490
+ fn volTransmittance(t: f32) -> f32 {
491
+ return exp(-volOpticalDepth(t));
492
+ }
493
+ #elif VOL_FOG_MODE == 2
494
+ fn volTransmittance(t: f32) -> f32 {
495
+ return clamp((uniforms.volFogInfos.z - t) / max(uniforms.volFogInfos.z - uniforms.volFogInfos.y, uniforms.volLinearFogEps), 0.0, 1.0);
496
+ }
497
+ #else
498
+ fn volOpticalDepth(t: f32) -> f32 {
499
+ #if VOL_FOG_MODE == 1
500
+ let x = t * uniforms.volFogInfos.w;
501
+ return x * x;
502
+ #else
503
+ return t * uniforms.volFogInfos.w;
504
+ #endif
505
+ }
506
+
507
+ fn volTransmittance(t: f32) -> f32 {
508
+ return exp(-volOpticalDepth(t));
509
+ }
510
+ #endif
511
+
512
+ // Transmittance of the medium to the point at the distance "t", combined with the attenuation of the light on
513
+ // its way to that point. @see the GLSL version.
514
+ fn volCombinedTransmittance(t: f32, sigmaT: f32, distanceToLight: f32) -> f32 {
515
+ #ifdef VOL_LIGHT_EXTINCTION
516
+ let lightOpticalDepth = sigmaT * min(distanceToLight, uniforms.volParams.z);
517
+
518
+ #ifdef VOL_OPTICAL_DEPTH
519
+ return exp(-(volOpticalDepth(t) + lightOpticalDepth));
520
+ #else
521
+ return volTransmittance(t) * exp(-lightOpticalDepth);
522
+ #endif
523
+ #else
524
+ return volTransmittance(t);
525
+ #endif
526
+ }
527
+
528
+ #ifdef VOL_SCREEN_SHADOWS
529
+ // Walks a segment going from a point of the medium towards a light through the depth buffer. The segment is
530
+ // given in clip space, where it is affine. @see the GLSL version.
531
+ fn volScreenShadow(clipStart: vec4f, clipDelta: vec4f, depthStart: f32, depthDelta: f32) -> f32 {
532
+ for (var i: i32 = 1; i <= VOL_SCREEN_SHADOW_STEPS; i++) {
533
+ let u = (f32(i) + volJitter) * (1.0 / f32(VOL_SCREEN_SHADOW_STEPS + 1));
534
+
535
+ let clip = clipStart + clipDelta * u;
536
+ if (clip.w <= 0.0) {
537
+ continue;
538
+ }
539
+
540
+ let uv = (clip.xy / clip.w) * 0.5 + 0.5;
541
+ if (uv.x < 0.0 || uv.x >= 1.0 || uv.y < 0.0 || uv.y >= 1.0) {
542
+ continue;
543
+ }
544
+
545
+ let sceneDepth = volReadLinearDepth(vec2i(uv * vec2f(volDepthSize)));
546
+
547
+ let depthDifference = depthStart + depthDelta * u - sceneDepth;
548
+ let bias = max(uniforms.volScreenShadowParams.y * sceneDepth, uniforms.volCameraMinMaxZ.x);
549
+
550
+ if (depthDifference > bias && depthDifference < uniforms.volScreenShadowParams.z * sceneDepth) {
551
+ return 0.0;
552
+ }
553
+ }
554
+
555
+ return 1.0;
556
+ }
557
+
558
+ // Occlusion of a point or a spot light, seen from the point of the view ray at the distance "t".
559
+ fn volScreenShadowToLight(t: f32, lightClip: vec4f, lightDepth: f32, distanceToLight: f32) -> f32 {
560
+ let clipStart = volClipOrigin + volClipDirection * t;
561
+ let depthStart = t * volCosForward;
562
+ let fraction = min(1.0, uniforms.volScreenShadowParams.x / max(distanceToLight, 1e-4));
563
+
564
+ return volScreenShadow(clipStart, (lightClip - clipStart) * fraction, depthStart, (lightDepth - depthStart) * fraction);
565
+ }
566
+ #endif
567
+
568
+ // Evaluates the in-scattered radiance coming from a directional light, without any shadowing.
569
+ fn volEvalDirectionalLight(data: vec4f, diffuse: vec4f) -> vec3f {
570
+ return diffuse.rgb * volPhaseHG(dot(volRayDir, data.xyz), diffuse.a);
571
+ }
572
+
573
+ // Evaluates the in-scattered radiance coming from a point or a spot light at the given position, relative to
574
+ // the camera, without any shadowing nor extinction. Returns the radiance in "xyz" and the distance to the light in "w".
575
+ fn volEvalLocalLight(data: vec4f, diffuse: vec4f, direction: vec4f, falloff: vec4f, position: vec3f) -> vec4f {
576
+ let toLight = data.xyz - position;
577
+ let distanceToLight = max(length(toLight), 1e-4);
578
+ let lightVector = toLight / distanceToLight;
579
+
580
+ // Same linear attenuation as "computeLighting" in the "lightsFragmentFunctions" include.
581
+ var attenuation = max(0.0, 1.0 - distanceToLight / falloff.x);
582
+
583
+ if (data.w == 2.0) {
584
+ let cosAngle = max(0.0, dot(direction.xyz, -lightVector));
585
+ attenuation *= select(0.0, max(0.0, pow(cosAngle, falloff.y)), cosAngle >= direction.w);
586
+ }
587
+
588
+ if (attenuation <= 0.0) {
589
+ return vec4f(0.0, 0.0, 0.0, distanceToLight);
590
+ }
591
+
592
+ return vec4f(diffuse.rgb * (attenuation * volPhaseHG(dot(volRayDir, lightVector), diffuse.a)), distanceToLight);
593
+ }
594
+
595
+ // Returns the part of the view ray crossing the cone of a spot light, cut by the sphere of its range.
596
+ // @see the GLSL version.
597
+ fn volConeChord(apex: vec3f, axis: vec3f, cosAngle: f32, range: f32, sphere: vec2f) -> vec2f {
598
+ if (cosAngle <= 1e-3) {
599
+ return sphere;
600
+ }
601
+
602
+ let origin = apex * (-1.0 / range);
603
+ let dv = dot(volRayDir, axis);
604
+ let ov = dot(origin, axis);
605
+ let cos2 = cosAngle * cosAngle;
606
+
607
+ let a = dv * dv - cos2;
608
+ let b = dv * ov - cos2 * dot(volRayDir, origin);
609
+ let c = ov * ov - cos2 * dot(origin, origin);
610
+
611
+ if (abs(a) < 1e-4) {
612
+ return sphere;
613
+ }
614
+
615
+ let discriminant = b * b - a * c;
616
+ var cone = vec2f(0.0);
617
+
618
+ if (a < 0.0) {
619
+ if (discriminant <= 0.0) {
620
+ return vec2f(1.0, -1.0);
621
+ }
622
+
623
+ let s = sqrt(discriminant);
624
+ cone = vec2f((-b + s) / a, (-b - s) / a);
625
+
626
+ if (dv * 0.5 * (cone.x + cone.y) + ov < 0.0) {
627
+ return vec2f(1.0, -1.0);
628
+ }
629
+ } else {
630
+ let s = sqrt(max(discriminant, 0.0));
631
+ cone = select(vec2f(-1e30, (-b - s) / a), vec2f((-b + s) / a, 1e30), dv > 0.0);
632
+ }
633
+
634
+ return vec2f(max(sphere.x, (cone.x - 0.005) * range), min(sphere.y, (cone.y + 0.005) * range));
635
+ }
636
+
637
+ // Returns the part of the view ray, as distances to the camera, crossing the volume a point or a spot light
638
+ // reaches. @see the GLSL version.
639
+ fn volLightChord(data: vec4f, direction: vec4f, range: f32) -> vec2f {
640
+ let closest = dot(data.xyz, volRayDir);
641
+ let offset = data.xyz - volRayDir * closest;
642
+ let halfChord2 = range * range - dot(offset, offset);
643
+
644
+ if (halfChord2 <= 0.0) {
645
+ return vec2f(1.0, -1.0);
646
+ }
647
+
648
+ let halfChord = sqrt(halfChord2);
649
+ var chord = vec2f(closest - halfChord, closest + halfChord);
650
+
651
+ if (data.w == 2.0) {
652
+ chord = volConeChord(data.xyz, direction.xyz, direction.w, range, chord);
653
+ }
654
+
655
+ return chord;
656
+ }
657
+
658
+ // Returns the number of samples taken over the given chord of a light. @see the GLSL version.
659
+ fn volLocalSampleCount(chordLength: f32, range: f32, rayLength: f32) -> i32 {
660
+ let count = max(f32(VOL_LIGHT_STEPS) * chordLength / (2.0 * range), f32(VOL_STEPS) * chordLength / rayLength);
661
+ return clamp(i32(ceil(count)), 2, VOL_LOCAL_MAX_STEPS);
662
+ }
663
+
664
+ ${e.join(`
665
+ `)}
666
+
667
+ #ifdef VOL_CSM
668
+ // The parts of the view ray inside the box of each cascade, and the clip space position of the view ray in the
669
+ // current cascade. @see the GLSL version.
670
+ var<private> volCsmEntries: vec4f;
671
+ var<private> volCsmExits: vec4f;
672
+ var<private> volCsmCurrent: i32;
673
+ var<private> volCsmClipOrigin: vec4f;
674
+ var<private> volCsmClipDirection: vec4f;
675
+
676
+ // Returns the part of the view ray inside the box of a cascade. @see the GLSL version.
677
+ fn volCsmBoxInterval(origin: vec4f, direction: vec4f) -> vec2f {
678
+ #ifdef VOL_NDC_HALF_Z
679
+ let boxMin = vec3f(-0.96, -0.96, 0.0);
680
+ #else
681
+ let boxMin = vec3f(-0.96, -0.96, -1.0);
682
+ #endif
683
+ let boxMax = vec3f(0.96, 0.96, 1.0);
684
+
685
+ let safeDirection = select(vec3f(1e-9), direction.xyz, abs(direction.xyz) > vec3f(1e-9));
686
+ let inverseDirection = 1.0 / safeDirection;
687
+ let t0 = (boxMin - origin.xyz) * inverseDirection;
688
+ let t1 = (boxMax - origin.xyz) * inverseDirection;
689
+ let tMin = min(t0, t1);
690
+ let tMax = max(t0, t1);
691
+
692
+ return vec2f(max(max(tMin.x, tMin.y), tMin.z), min(min(tMax.x, tMax.y), tMax.z));
693
+ }
694
+
695
+ fn volPrepareCsm() {
696
+ volCsmEntries = vec4f(1e30);
697
+ volCsmExits = vec4f(-1e30);
698
+
699
+ for (var cascade: i32 = 0; cascade < VOL_CSM_CASCADES; cascade++) {
700
+ let interval = volCsmBoxInterval(uniforms.volCsmMatrices[cascade] * vec4f(uniforms.volCameraPosition, 1.0), uniforms.volCsmMatrices[cascade] * vec4f(volRayDir, 0.0));
701
+ volCsmEntries[cascade] = interval.x;
702
+ volCsmExits[cascade] = interval.y;
703
+ }
704
+
705
+ volCsmCurrent = -1;
706
+ }
707
+
708
+ // Returns the shadowing of the point of the view ray at the distance "t" from the camera.
709
+ fn volCsmShadow(t: f32) -> f32 {
710
+ // The first cascade containing the sample is the most detailed one.
711
+ var cascade: i32 = -1;
712
+ for (var i: i32 = VOL_CSM_CASCADES - 1; i >= 0; i--) {
713
+ if (t >= volCsmEntries[i] && t <= volCsmExits[i]) {
714
+ cascade = i;
715
+ }
716
+ }
717
+
718
+ if (cascade < 0) {
719
+ return 1.0;
720
+ }
721
+
722
+ if (cascade != volCsmCurrent) {
723
+ volCsmCurrent = cascade;
724
+ volCsmClipOrigin = uniforms.volCsmMatrices[cascade] * vec4f(uniforms.volCameraPosition, 1.0);
725
+ volCsmClipDirection = uniforms.volCsmMatrices[cascade] * vec4f(volRayDir, 0.0);
726
+ }
727
+
728
+ // The projection of a directional light is orthographic, "w" is always 1.
729
+ let clip = volCsmClipOrigin + volCsmClipDirection * t;
730
+ let clipSpace = clip.xyz;
731
+
732
+ #if VOL_CSM_KIND == 1
733
+ var uvDepth = 0.5 * clipSpace + vec3f(0.5);
734
+ #ifdef VOL_NDC_HALF_Z
735
+ uvDepth.z = clipSpace.z;
736
+ #endif
737
+
738
+ let shadow = textureSampleCompareLevel(volCsmSampler, volCsmSamplerSampler, uvDepth.xy, cascade, uvDepth.z);
739
+ return volFallOff(mix(uniforms.volCsmInfo.x, 1.0, shadow), clipSpace.xy, uniforms.volCsmLightFalloff.z);
740
+ #else
741
+ let uv = 0.5 * clipSpace.xy + vec2f(0.5);
742
+ let depthMetric = clamp(volDepthMetric(clip, uniforms.volCsmInfo.zw), 0.0, 1.0);
743
+
744
+ #ifdef VOL_CSM_PACKED
745
+ let shadowMapSample = volUnpack(textureSampleLevel(volCsmSampler, volCsmSamplerSampler, uv, cascade, 0.0));
746
+ #else
747
+ let shadowMapSample = textureSampleLevel(volCsmSampler, volCsmSamplerSampler, uv, cascade, 0.0).x;
748
+ #endif
749
+
750
+ return select(1.0, volFallOff(uniforms.volCsmInfo.x, clipSpace.xy, uniforms.volCsmLightFalloff.z), depthMetric > shadowMapSample);
751
+ #endif
752
+ }
753
+ #endif
754
+
755
+ #if VOL_GLOBAL_LIGHT_COUNT > 0
756
+ // Marches the whole view ray for the lights that reach all of it: the directional lights. Returns the
757
+ // in-scattered radiance in "xyz" and the number of lights evaluated in "w".
758
+ fn volMarchGlobalLights(tStart: f32, tEnd: f32) -> vec4f {
759
+ #if VOL_DIRECTIONAL_LIGHT_COUNT > 0
760
+ #ifdef VOL_SCREEN_SHADOWS
761
+ // The occlusion search of a directional light always walks the same direction over the same distance,
762
+ // only its starting point moves along the view ray.
763
+ var directionClip: array<vec4f, VOL_DIRECTIONAL_LIGHT_COUNT>;
764
+ var directionDepth: array<f32, VOL_DIRECTIONAL_LIGHT_COUNT>;
765
+
766
+ for (var li: i32 = 0; li < VOL_DIRECTIONAL_LIGHT_COUNT; li++) {
767
+ let traced = uniforms.volLightData[li].xyz * uniforms.volScreenShadowParams.x;
768
+ directionClip[li] = uniforms.volViewProjection * vec4f(traced, 0.0);
769
+ directionDepth[li] = dot(traced, uniforms.volCameraForward);
770
+ }
771
+ #endif
772
+ #endif
773
+
774
+ #if VOL_DISTRIBUTION == 1
775
+ let ratio = pow(tEnd / tStart, 1.0 / f32(VOL_STEPS));
776
+ #else
777
+ let uniformStep = (tEnd - tStart) / f32(VOL_STEPS);
778
+ #endif
779
+
780
+ var result = vec3f(0.0);
781
+ var evaluatedLights = 0.0;
782
+ var segmentStart = tStart;
783
+
784
+ for (var i: i32 = 0; i < VOL_STEPS; i++) {
785
+ #if VOL_DISTRIBUTION == 1
786
+ let segmentEnd = segmentStart * ratio;
787
+ #else
788
+ let segmentEnd = segmentStart + uniformStep;
789
+ #endif
790
+
791
+ let segmentBegin = segmentStart;
792
+ let dt = segmentEnd - segmentBegin;
793
+
794
+ // The jitter picks the sample inside its own segment, so the marched interval stays exactly
795
+ // [tStart, tEnd] whatever the dithering does.
796
+ let t = segmentBegin + dt * volJitter;
797
+ segmentStart = segmentEnd;
798
+
799
+ let position = volRayDir * t;
800
+ let sigmaT = volExtinctionAt(uniforms.volCameraPosition.y + position.y, t);
801
+
802
+ if (sigmaT <= 1e-6) {
803
+ continue;
804
+ }
805
+
806
+ // The transmittance at the START of the segment: the factor below accounts for the extinction
807
+ // across the segment itself.
808
+ let viewTransmittance = volTransmittance(segmentBegin);
809
+ if (viewTransmittance < 0.003) {
810
+ break;
811
+ }
812
+
813
+ var scattering = vec3f(0.0);
814
+ var stepLights = 0.0;
815
+
816
+ ${i.join("")}
817
+ #ifdef VOL_CSM
818
+ {
819
+ scattering += volEvalDirectionalLight(uniforms.volCsmLightData, uniforms.volCsmLightDiffuse) * mix(1.0, volCsmShadow(t), uniforms.volCsmLightFalloff.w);
820
+ stepLights += 1.0;
821
+ }
822
+ #endif
823
+
824
+ #if VOL_DIRECTIONAL_LIGHT_COUNT > 0
825
+ for (var li: i32 = 0; li < VOL_DIRECTIONAL_LIGHT_COUNT; li++) {
826
+ var contribution = volEvalDirectionalLight(uniforms.volLightData[li], uniforms.volLightDiffuse[li]);
827
+
828
+ #ifdef VOL_SCREEN_SHADOWS
829
+ // "volLightFalloff[li].z" carries whether this light asked to be occluded by the geometry.
830
+ if (uniforms.volLightFalloff[li].z > 0.5) {
831
+ contribution *= volScreenShadow(volClipOrigin + volClipDirection * t, directionClip[li], t * volCosForward, directionDepth[li]);
832
+ }
833
+ #endif
834
+
835
+ scattering += contribution;
836
+ stepLights += 1.0;
837
+ }
838
+ #endif
839
+
840
+ evaluatedLights = max(evaluatedLights, stepLights);
841
+
842
+ // Analytic integral of the in-scattering over the segment. @see the GLSL version.
843
+ result += scattering * (viewTransmittance * (1.0 - exp(-sigmaT * dt)));
844
+ }
845
+
846
+ return vec4f(result, evaluatedLights);
847
+ }
848
+ #endif
849
+
850
+ #if VOL_LOCAL_ARRAY_LIGHTS == 1
851
+ // Integrates a point or a spot light of the arrays over the part of the view ray crossing its volume.
852
+ // Returns the in-scattered radiance in "xyz" and whether the light was evaluated in "w".
853
+ fn volIntegrateArrayLight(index: i32, tStart: f32, tEnd: f32) -> vec4f {
854
+ let data = uniforms.volLightData[index];
855
+ let direction = uniforms.volLightDirection[index];
856
+ let falloff = uniforms.volLightFalloff[index];
857
+
858
+ let chord = volLightChord(data, direction, falloff.x);
859
+ let t0 = max(chord.x, tStart);
860
+ let t1 = min(chord.y, tEnd);
861
+
862
+ if (t1 <= t0) {
863
+ return vec4f(0.0);
864
+ }
865
+
866
+ let diffuse = uniforms.volLightDiffuse[index];
867
+
868
+ #ifdef VOL_SCREEN_SHADOWS
869
+ // "falloff.z" carries whether this light asked to be occluded by the geometry.
870
+ let occluded = falloff.z > 0.5;
871
+ let lightClip = volClipOrigin + uniforms.volViewProjection * vec4f(data.xyz, 0.0);
872
+ let lightDepth = dot(data.xyz, uniforms.volCameraForward);
873
+ #endif
874
+
875
+ ${Mo("f32(index)",`#ifdef VOL_SCREEN_SHADOWS
876
+ if (occluded) {
877
+ contribution *= volScreenShadowToLight(t, lightClip, lightDepth, distanceToLight);
878
+ }
879
+ #endif`)}
880
+ }
881
+ #endif
882
+
883
+ @fragment
884
+ fn main(input: FragmentInputs) -> FragmentOutputs {
885
+ // Reconstruct the world space direction of the view ray from the UV of the pixel.
886
+ let farPoint = uniforms.volInverseViewProjection * vec4f(input.vUV * 2.0 - 1.0, 1.0, 1.0);
887
+ volRayDir = normalize(farPoint.xyz / farPoint.w - uniforms.volCameraPosition);
888
+
889
+ // The depth map stores the distance along the view axis, the ray is not aligned with it.
890
+ volCosForward = max(dot(volRayDir, uniforms.volCameraForward), 1e-4);
891
+ let pixel = fragmentInputs.position.xy;
892
+ let depthSize = vec2i(textureDimensions(textureSampler));
893
+ let viewZ = volReadLinearDepth(volScatterToDepthTexel(vec2i(pixel), depthSize));
894
+
895
+ let tEnd = min(viewZ / volCosForward, uniforms.volParams.x);
896
+ let tStart = max(uniforms.volCameraMinMaxZ.x / volCosForward, 1e-3);
897
+
898
+ var result = vec3f(0.0);
899
+ var finalTransmittance = 1.0;
900
+ var evaluatedLights = 0.0;
901
+
902
+ // WGSL has no early return from the fragment entry point, the whole integration is guarded instead.
903
+ if (tEnd > tStart) {
904
+ // Offsets the samples inside their segments to trade the banding produced by a low sample count for noise.
905
+ volNoise = 0.0;
906
+ #if VOL_DITHER == 1
907
+ volNoise = volBayer4(pixel);
908
+ #elif VOL_DITHER == 2
909
+ var ditherPosition = pixel;
910
+ #ifdef VOL_TEMPORAL_JITTER
911
+ ditherPosition += uniforms.volFrameIndex * 5.588238;
912
+ #endif
913
+ volNoise = volInterleavedGradientNoise(ditherPosition);
914
+ #endif
915
+ volJitter = volNoise * uniforms.volParams.y;
916
+
917
+ #ifdef VOL_SCREEN_SHADOWS
918
+ volDepthSize = depthSize;
919
+ volClipOrigin = uniforms.volViewProjection * vec4f(uniforms.volCameraPosition, 1.0);
920
+ volClipDirection = uniforms.volViewProjection * vec4f(volRayDir, 0.0);
921
+ #endif
922
+
923
+ #if VOL_TRANSMITTANCE == 2
924
+ volBuildOpticalDepths(tStart, tEnd);
925
+ #endif
926
+
927
+ #ifdef VOL_CSM
928
+ volPrepareCsm();
929
+ #endif
930
+
931
+ // The in-scattering of the constant ambient light has a closed form whatever the medium. @see the GLSL version.
932
+ var accumulated = uniforms.volAmbient * (volTransmittance(tStart) - volTransmittance(tEnd));
933
+ var lightResult = vec4f(0.0);
934
+
935
+ #if VOL_GLOBAL_LIGHT_COUNT > 0
936
+ lightResult = volMarchGlobalLights(tStart, tEnd);
937
+ accumulated += lightResult.xyz;
938
+ evaluatedLights += lightResult.w;
939
+ #endif
940
+
941
+ ${o.join("")}
942
+
943
+ #if VOL_LOCAL_ARRAY_LIGHTS == 1
944
+ let localEnd = VOL_DIRECTIONAL_LIGHT_COUNT + i32(uniforms.volParams.w + 0.5);
945
+
946
+ for (var i: i32 = VOL_DIRECTIONAL_LIGHT_COUNT; i < VOL_MAX_ARRAY_LIGHTS; i++) {
947
+ if (i >= localEnd) {
948
+ break;
949
+ }
950
+
951
+ lightResult = volIntegrateArrayLight(i, tStart, tEnd);
952
+ accumulated += lightResult.xyz;
953
+ evaluatedLights += lightResult.w;
954
+ }
955
+ #endif
956
+
957
+ // The scattering coefficient is a fraction of the extinction, which guarantees energy conservation.
958
+ result = accumulated * uniforms.volMedium.x * uniforms.volFogColor;
959
+ finalTransmittance = volTransmittance(tEnd);
960
+ }
961
+
962
+ #if VOL_DEBUG == 3
963
+ // From blue for no light to red for 16 lights or more evaluated by the pixel.
964
+ let ratioOfBudget = clamp(evaluatedLights / 16.0, 0.0, 1.0);
965
+ result = vec3f(ratioOfBudget, 1.0 - abs(ratioOfBudget * 2.0 - 1.0), 1.0 - ratioOfBudget);
966
+ #endif
967
+
968
+ #ifdef VOL_LDR_ENCODE
969
+ result = result / (1.0 + result);
970
+ #endif
971
+
972
+ fragmentOutputs.color = vec4f(result, finalTransmittance);
973
+ }
974
+ `}a(Jn,"buildVolumetricLightingScatteringShaderWGSL");function ea(){return`
975
+ varying vUV: vec2f;
976
+
977
+ var textureSampler: texture_2d<f32>;
978
+ var volLinearDepthSampler: texture_2d<f32>;
979
+
980
+ uniform volCameraMinMaxZ: vec2f;
981
+ uniform volDepthRatio: vec2f;
982
+ uniform volBlurDirection: vec2f;
983
+ uniform volBlurParams: vec2f;
984
+
985
+ ${ot}
986
+ ${yi("volLinearDepthSampler")}
987
+
988
+ @fragment
989
+ fn main(input: FragmentInputs) -> FragmentOutputs {
990
+ // Every tap is an exact texel compared using the depth the raymarching used for it. @see the GLSL version.
991
+ let size = vec2i(textureDimensions(textureSampler));
992
+ let depthSize = vec2i(textureDimensions(volLinearDepthSampler));
993
+ let center = vec2i(fragmentInputs.position.xy);
994
+ let direction = vec2i(uniforms.volBlurDirection);
995
+
996
+ let centerDepth = volReadLinearDepth(volScatterToDepthTexel(center, depthSize));
997
+ let inverseDepthThreshold = 1.0 / max(uniforms.volBlurParams.y * max(centerDepth, uniforms.volCameraMinMaxZ.x), 1e-4);
998
+ let sigma = max(uniforms.volBlurParams.x, 1e-4);
999
+ let inverseTwoSigma2 = 1.0 / (2.0 * sigma * sigma);
1000
+
1001
+ var result = textureLoad(textureSampler, center, 0);
1002
+ var totalWeight = 1.0;
1003
+
1004
+ for (var i: i32 = 1; i <= VOL_BLUR_RADIUS; i++) {
1005
+ let spatialWeight = exp(-f32(i * i) * inverseTwoSigma2);
1006
+
1007
+ let positive = center + direction * i;
1008
+ let negative = center - direction * i;
1009
+
1010
+ if (positive.x < size.x && positive.y < size.y) {
1011
+ let weight = spatialWeight * exp(-abs(volReadLinearDepth(volScatterToDepthTexel(positive, depthSize)) - centerDepth) * inverseDepthThreshold);
1012
+ result += textureLoad(textureSampler, positive, 0) * weight;
1013
+ totalWeight += weight;
1014
+ }
1015
+
1016
+ if (negative.x >= 0 && negative.y >= 0) {
1017
+ let weight = spatialWeight * exp(-abs(volReadLinearDepth(volScatterToDepthTexel(negative, depthSize)) - centerDepth) * inverseDepthThreshold);
1018
+ result += textureLoad(textureSampler, negative, 0) * weight;
1019
+ totalWeight += weight;
1020
+ }
1021
+ }
1022
+
1023
+ fragmentOutputs.color = result / totalWeight;
1024
+ }
1025
+ `}a(ea,"buildVolumetricLightingBlurShaderWGSL");function ta(){return`
1026
+ varying vUV: vec2f;
1027
+
1028
+ var textureSampler: texture_2d<f32>;
1029
+ var volSceneSamplerSampler: sampler;
1030
+ var volSceneSampler: texture_2d<f32>;
1031
+ var volLinearDepthSampler: texture_2d<f32>;
1032
+
1033
+ uniform volCameraMinMaxZ: vec2f;
1034
+ uniform volDepthRatio: vec2f;
1035
+ uniform volComposeParams: vec4f;
1036
+
1037
+ ${ot}
1038
+ ${yi("volLinearDepthSampler")}
1039
+
1040
+ fn volMod(x: f32, y: f32) -> f32 {
1041
+ return x - y * floor(x / y);
1042
+ }
1043
+
1044
+ fn volBayer8(p: vec2f) -> f32 {
1045
+ let p1 = vec2f(volMod(floor(p.x), 2.0), volMod(floor(p.y), 2.0));
1046
+ let p2 = vec2f(volMod(floor(p.x * 0.5), 2.0), volMod(floor(p.y * 0.5), 2.0));
1047
+ let p3 = vec2f(volMod(floor(p.x * 0.25), 2.0), volMod(floor(p.y * 0.25), 2.0));
1048
+
1049
+ let b1 = 2.0 * p1.x + 3.0 * p1.y - 4.0 * p1.x * p1.y;
1050
+ let b2 = 2.0 * p2.x + 3.0 * p2.y - 4.0 * p2.x * p2.y;
1051
+ let b3 = 2.0 * p3.x + 3.0 * p3.y - 4.0 * p3.x * p3.y;
1052
+
1053
+ return (b1 * 16.0 + b2 * 4.0 + b3) / 64.0;
1054
+ }
1055
+
1056
+ // Nearest depth upsampling. @see the GLSL version.
1057
+ fn volUpsample(uv0: vec2f, centerDepth: f32, depthSize: vec2i) -> vec4f {
1058
+ let size = vec2i(textureDimensions(textureSampler));
1059
+ let texelCoordinate = uv0 * vec2f(size) - 0.5;
1060
+ let baseCoordinate = floor(texelCoordinate);
1061
+ let fraction = texelCoordinate - baseCoordinate;
1062
+
1063
+ let base = vec2i(baseCoordinate);
1064
+ let maximum = size - vec2i(1);
1065
+
1066
+ let inverseDepthThreshold = 1.0 / max(uniforms.volComposeParams.z * max(centerDepth, uniforms.volCameraMinMaxZ.x), 1e-4);
1067
+
1068
+ var result = vec4f(0.0);
1069
+ var totalWeight = 0.0;
1070
+
1071
+ var nearestSample = vec4f(0.0);
1072
+ var nearestDistance = 1e20;
1073
+
1074
+ for (var y: i32 = 0; y < 2; y++) {
1075
+ for (var x: i32 = 0; x < 2; x++) {
1076
+ let coordinates = clamp(base + vec2i(x, y), vec2i(0), maximum);
1077
+
1078
+ let bilinearWeight = select(fraction.x, 1.0 - fraction.x, x == 0) * select(fraction.y, 1.0 - fraction.y, y == 0);
1079
+ let depthDistance = abs(volReadLinearDepth(volScatterToDepthTexel(coordinates, depthSize)) - centerDepth);
1080
+
1081
+ let tap = textureLoad(textureSampler, coordinates, 0);
1082
+
1083
+ if (depthDistance < nearestDistance) {
1084
+ nearestDistance = depthDistance;
1085
+ nearestSample = tap;
1086
+ }
1087
+
1088
+ let weight = bilinearWeight / (1e-4 + depthDistance * inverseDepthThreshold);
1089
+ result += tap * weight;
1090
+ totalWeight += weight;
1091
+ }
1092
+ }
1093
+
1094
+ // Every tap sits on the other side of a silhouette, fall back to the closest one instead of averaging.
1095
+ return select(nearestSample, result / totalWeight, totalWeight > 1e-4);
1096
+ }
1097
+
1098
+ @fragment
1099
+ fn main(input: FragmentInputs) -> FragmentOutputs {
1100
+ // The linear depth has the full resolution of the canvas. @see the GLSL version.
1101
+ let depthSize = vec2i(textureDimensions(volLinearDepthSampler));
1102
+ let centerDepth = volReadLinearDepth(min(vec2i(input.vUV * vec2f(depthSize)), depthSize - 1));
1103
+
1104
+ var volumetric = volUpsample(input.vUV, centerDepth, depthSize);
1105
+
1106
+ #ifdef VOL_LDR_ENCODE
1107
+ volumetric = vec4f(volumetric.rgb / max(vec3f(1e-4), 1.0 - volumetric.rgb), volumetric.a);
1108
+ #endif
1109
+
1110
+ // WGSL has no early return from the fragment entry point, so the debug outputs are branches instead.
1111
+ #if VOL_DEBUG == 1 || VOL_DEBUG == 3
1112
+ fragmentOutputs.color = vec4f(volumetric.rgb * uniforms.volComposeParams.x, 1.0);
1113
+ #elif VOL_DEBUG == 2
1114
+ fragmentOutputs.color = vec4f(vec3f(volumetric.a), 1.0);
1115
+ #else
1116
+ var sceneColor = textureSampleLevel(volSceneSampler, volSceneSamplerSampler, input.vUV, 0.0).rgb;
1117
+
1118
+ sceneColor *= mix(1.0, volumetric.a, uniforms.volComposeParams.y);
1119
+
1120
+ var result = sceneColor + volumetric.rgb * uniforms.volComposeParams.x;
1121
+
1122
+ // Breaks up the banding an 8 bits output would otherwise show on the smooth gradients of the shafts.
1123
+ result += (volBayer8(fragmentInputs.position.xy) - 0.5) * uniforms.volComposeParams.w;
1124
+
1125
+ fragmentOutputs.color = vec4f(result, 1.0);
1126
+ #endif
1127
+ }
1128
+ `}a(ta,"buildVolumetricLightingComposeShaderWGSL");function Ro(){return{linearDepth:Qn(),scattering:Jn(E),blur:ea(),compose:ta()}}a(Ro,"getVolumetricLightingShadersWGSL");var Z=require("babylonjs"),No=require("babylonjs"),nt="volumetricLightingLinearDepth",at="volumetricLightingScattering",st="volumetricLightingBlur",lt="volumetricLightingCompose",rt=`
1129
+ float volUnpack(vec4 color) {
1130
+ const vec4 bitShift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
1131
+ return dot(color, bitShift);
1132
+ }
1133
+ `,ia=`
1134
+ // Reads the texel under the given coordinates rather than filtering: the depth of a silhouette must not be
1135
+ // averaged with the sky, and the 32 bits float textures of the prepass renderer can't be filtered everywhere.
1136
+ float volSampleDepth(vec2 uv) {
1137
+ ivec2 size = textureSize(depthSampler, 0);
1138
+ ivec2 coordinates = min(ivec2(uv * vec2(size)), size - 1);
1139
+
1140
+ #ifdef VOL_DEPTH_PACKED
1141
+ return volUnpack(texelFetch(depthSampler, coordinates, 0));
1142
+ #else
1143
+ return texelFetch(depthSampler, coordinates, 0).r;
1144
+ #endif
1145
+ }
1146
+
1147
+ // Converts the raw value stored in the depth map into a distance along the view axis, in scene units.
1148
+ float volLinearDepth(float d) {
1149
+ #ifdef VOL_DEPTH_VIEWZ
1150
+ // The view space Z is stored directly, negative in a right handed scene. The sky is cleared to 0.
1151
+ float viewZ = abs(d);
1152
+ return (viewZ <= 0.0) ? volCameraMinMaxZ.y : viewZ;
1153
+ #else
1154
+ // The depth renderer stores "(clipZ + minZ) / (minZ + maxZ)", which is affine in the view space Z
1155
+ // for both the perspective and the orthographic projections. "volDepthUnpack" holds the two
1156
+ // coefficients of the exact inverse, computed on the CPU from the projection matrix of the scene.
1157
+ // The sky is cleared to 1, which maps back to the far plane.
1158
+ return volDepthUnpack.x * d + volDepthUnpack.y;
1159
+ #endif
1160
+ }
1161
+ `,bi=`
1162
+ // Returns the distance along the view axis, in scene units, of the texel at the given coordinates.
1163
+ float volReadLinearDepth(sampler2D s, ivec2 coordinates) {
1164
+ #ifdef VOL_LINEAR_DEPTH_PACKED
1165
+ return volUnpack(texelFetch(s, coordinates, 0)) * volCameraMinMaxZ.y;
1166
+ #else
1167
+ return texelFetch(s, coordinates, 0).r;
1168
+ #endif
1169
+ }
1170
+
1171
+ // Returns the texel of the linear depth under the center of the given texel of the scattering buffer, which
1172
+ // is the depth the raymarching used for it. At half resolution the center of a texel lies exactly on the corner
1173
+ // of four texels of the depth: "volDepthRatio", the ratio between the two resolutions, is computed on the CPU
1174
+ // so every pass rounds exactly the same way and picks the same one.
1175
+ ivec2 volScatterToDepthTexel(ivec2 scatterTexel, ivec2 depthSize) {
1176
+ return min(ivec2((vec2(scatterTexel) + 0.5) * volDepthRatio), depthSize - 1);
1177
+ }
1178
+ `;function oa(){return`precision highp float;
1179
+ precision highp int;
1180
+
1181
+ varying vec2 vUV;
1182
+
1183
+ uniform sampler2D textureSampler;
1184
+ uniform highp sampler2D depthSampler;
1185
+
1186
+ uniform vec2 volCameraMinMaxZ;
1187
+ uniform vec2 volDepthUnpack;
1188
+
1189
+ ${rt}
1190
+ ${ia}
1191
+
1192
+ vec4 volPack(float depth) {
1193
+ const vec4 bitShift = vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0);
1194
+ const vec4 bitMask = vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
1195
+
1196
+ vec4 result = fract(depth * bitShift);
1197
+ result -= result.xxyz * bitMask;
1198
+
1199
+ return result;
1200
+ }
1201
+
1202
+ void main(void) {
1203
+ float viewZ = volLinearDepth(volSampleDepth(vUV));
1204
+
1205
+ #ifdef VOL_LINEAR_DEPTH_PACKED
1206
+ gl_FragColor = volPack(clamp(viewZ / volCameraMinMaxZ.y, 0.0, 0.9999999));
1207
+ #else
1208
+ gl_FragColor = vec4(viewZ, 0.0, 0.0, 1.0);
1209
+ #endif
1210
+ }
1211
+ `}a(oa,"buildVolumetricLightingLinearDepthShader");function Vo(t,e){return`
1212
+ float chordLength = t1 - t0;
1213
+
1214
+ // The point of the view ray closest to the light splits the chord in two halves over which both the
1215
+ // attenuation and the phase function are monotonic, which is where stratified samples do best.
1216
+ float closest = clamp(dot(data.xyz, volRayDir), t0, t1);
1217
+ if (closest - t0 < 0.02 * chordLength) {
1218
+ closest = t0;
1219
+ } else if (t1 - closest < 0.02 * chordLength) {
1220
+ closest = t1;
1221
+ }
1222
+
1223
+ int count = volLocalSampleCount(chordLength, falloff.x, tEnd - tStart);
1224
+ int firstCount = closest <= t0 ? 0 : (closest >= t1 ? count : clamp(int(float(count) * (closest - t0) / chordLength + 0.5), 1, count - 1));
1225
+
1226
+ float firstWidth = (closest - t0) / float(max(firstCount, 1));
1227
+ float secondWidth = (t1 - closest) / float(max(count - firstCount, 1));
1228
+ float stratum = volStratumOffset(${t});
1229
+
1230
+ vec3 result = vec3(0.0);
1231
+
1232
+ for (int k = 0; k < VOL_LOCAL_MAX_STEPS; ++k) {
1233
+ if (k >= count) {
1234
+ break;
1235
+ }
1236
+
1237
+ bool inFirstHalf = k < firstCount;
1238
+ float width = inFirstHalf ? firstWidth : secondWidth;
1239
+ float t = inFirstHalf ? t0 + width * (float(k) + stratum) : closest + width * (float(k - firstCount) + stratum);
1240
+
1241
+ vec3 position = volRayDir * t;
1242
+ float sigmaT = volExtinctionAt(volCameraPosition.y + position.y, t);
1243
+
1244
+ float distanceToLight;
1245
+ vec3 contribution = volEvalLocalLight(data, diffuse, direction, falloff, position, distanceToLight);
1246
+
1247
+ if (contribution.r + contribution.g + contribution.b > 0.0) {
1248
+ ${e}
1249
+ result += contribution * (volCombinedTransmittance(t, sigmaT, distanceToLight) * sigmaT * width);
1250
+ }
1251
+ }
1252
+
1253
+ return vec4(result, 1.0);
1254
+ `}a(Vo,"buildLocalLightIntegration");function ra(t){let e=[],i=[],o=[];for(let r=0;r<t;++r)e.push(`
1255
+ #if VOL_SHADOW_SLOT_COUNT > {X}
1256
+ #if VOL_SHADOW_KIND{X} == 2
1257
+ uniform samplerCube volShadowSampler{X};
1258
+ #elif VOL_SHADOW_KIND{X} == 1
1259
+ uniform highp sampler2DShadow volShadowSampler{X};
1260
+ #else
1261
+ uniform sampler2D volShadowSampler{X};
1262
+ #endif
1263
+
1264
+ // Returns the shadowing of a point given its position relative to the camera and, for the 2d shadow maps, its
1265
+ // position in the clip space of the light, which the callers compute the cheapest way they can.
1266
+ float volShadow{X}(vec3 position, vec4 clip) {
1267
+ vec4 info = volShadowInfo[{X}];
1268
+ float edge = volShadowLightFalloff[{X}].z;
1269
+
1270
+ #if VOL_SHADOW_KIND{X} == 2
1271
+ // Cube shadow map of a point light. It stores the radial distance to the light.
1272
+ vec3 toFragment = position - volShadowLightData[{X}].xyz;
1273
+ float depth = clamp((length(toFragment) + info.z) / info.w, 0.0, 1.0);
1274
+
1275
+ toFragment = normalize(toFragment);
1276
+ toFragment.y = -toFragment.y;
1277
+
1278
+ #ifdef VOL_SHADOW_PACKED{X}
1279
+ float shadowMapSample = volUnpack(textureCube(volShadowSampler{X}, toFragment));
1280
+ #else
1281
+ float shadowMapSample = textureCube(volShadowSampler{X}, toFragment).x;
1282
+ #endif
1283
+
1284
+ #if VOL_SHADOW_MODE{X} == 1
1285
+ // Exponential shadow map, same encoding as the 2d case. "info.y" holds the depth scale.
1286
+ return 1.0 - clamp(exp(min(87.0, info.y * depth)) * shadowMapSample, 0.0, 1.0 - info.x);
1287
+ #elif VOL_SHADOW_MODE{X} == 2
1288
+ return clamp(exp(min(87.0, -info.y * (depth - shadowMapSample))), info.x, 1.0);
1289
+ #else
1290
+ return depth > shadowMapSample ? info.x : 1.0;
1291
+ #endif
1292
+ #else
1293
+ vec3 clipSpace = clip.xyz / clip.w;
1294
+
1295
+ // "getTransformMatrix" gives the world to light clip space matrix without the [-1, 1] -> [0, 1] bias.
1296
+ #if VOL_SHADOW_KIND{X} == 1
1297
+ vec3 uvDepth = vec3(0.5 * clipSpace + vec3(0.5));
1298
+ #ifdef VOL_NDC_HALF_Z
1299
+ uvDepth.z = clipSpace.z;
1300
+ #endif
1301
+
1302
+ // Same guard as "computeShadowWithPCF1": past the far plane of the shadow map the hardware
1303
+ // comparison would fail against every texel a caster wrote, reporting the sample as occluded
1304
+ // while the surfaces at the same distance are lit by the material path.
1305
+ float pcfDepthMetric = volDepthMetric(clip, info.zw);
1306
+ if (pcfDepthMetric < 0.0 || pcfDepthMetric > 1.0 || uvDepth.x < 0.0 || uvDepth.x > 1.0 || uvDepth.y < 0.0 || uvDepth.y > 1.0) {
1307
+ return 1.0;
1308
+ }
1309
+
1310
+ // Hardware comparison sampling. "info.y" holds the inverse of the size of the shadow map.
1311
+ #if VOL_PCF_TAPS == 4
1312
+ float shadow = 0.25 * (
1313
+ texture2DLodEXT(volShadowSampler{X}, uvDepth + vec3(-0.5 * info.y, -0.5 * info.y, 0.0), 0.) +
1314
+ texture2DLodEXT(volShadowSampler{X}, uvDepth + vec3( 0.5 * info.y, -0.5 * info.y, 0.0), 0.) +
1315
+ texture2DLodEXT(volShadowSampler{X}, uvDepth + vec3(-0.5 * info.y, 0.5 * info.y, 0.0), 0.) +
1316
+ texture2DLodEXT(volShadowSampler{X}, uvDepth + vec3( 0.5 * info.y, 0.5 * info.y, 0.0), 0.)
1317
+ );
1318
+ #else
1319
+ float shadow = texture2DLodEXT(volShadowSampler{X}, uvDepth, 0.);
1320
+ #endif
1321
+
1322
+ return volFallOff(mix(info.x, 1.0, shadow), clipSpace.xy, edge);
1323
+ #else
1324
+ vec2 uv = 0.5 * clipSpace.xy + vec2(0.5);
1325
+ if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
1326
+ return 1.0;
1327
+ }
1328
+
1329
+ float depthMetric = clamp(volDepthMetric(clip, info.zw), 0.0, 1.0);
1330
+
1331
+ #ifdef VOL_SHADOW_PACKED{X}
1332
+ float shadowMapSample = volUnpack(texture2DLodEXT(volShadowSampler{X}, uv, 0.));
1333
+ #else
1334
+ float shadowMapSample = texture2DLodEXT(volShadowSampler{X}, uv, 0.).x;
1335
+ #endif
1336
+
1337
+ #if VOL_SHADOW_MODE{X} == 1
1338
+ // Exponential shadow map. "info.y" holds the depth scale of the generator.
1339
+ return volFallOff(1.0 - clamp(exp(min(87.0, info.y * depthMetric)) * shadowMapSample, 0.0, 1.0 - info.x), clipSpace.xy, edge);
1340
+ #elif VOL_SHADOW_MODE{X} == 2
1341
+ // Close exponential shadow map.
1342
+ return volFallOff(clamp(exp(min(87.0, -info.y * (depthMetric - shadowMapSample))), info.x, 1.0), clipSpace.xy, edge);
1343
+ #else
1344
+ return depthMetric > shadowMapSample ? volFallOff(info.x, clipSpace.xy, edge) : 1.0;
1345
+ #endif
1346
+ #endif
1347
+ #endif
1348
+ }
1349
+
1350
+ #if VOL_SHADOW_LOCAL{X} == 1
1351
+ // Point or spot light casting volumetric shadows: integrated over its own volume, like the others.
1352
+ vec4 volIntegrateShadowSlot{X}(float tStart, float tEnd) {
1353
+ vec4 data = volShadowLightData[{X}];
1354
+ vec4 direction = volShadowLightDirection[{X}];
1355
+ vec4 falloff = volShadowLightFalloff[{X}];
1356
+
1357
+ vec2 chord = volLightChord(data, direction, falloff.x);
1358
+ float t0 = max(chord.x, tStart);
1359
+ float t1 = min(chord.y, tEnd);
1360
+
1361
+ if (t1 <= t0) {
1362
+ return vec4(0.0);
1363
+ }
1364
+
1365
+ vec4 diffuse = volShadowLightDiffuse[{X}];
1366
+
1367
+ // The light clip space position of the points of the view ray is affine in their distance to the camera,
1368
+ // so each sample only costs a multiply-add instead of a matrix product.
1369
+ vec4 clipOrigin = volShadowMatrix[{X}] * vec4(volCameraPosition, 1.0);
1370
+ vec4 clipDirection = volShadowMatrix[{X}] * vec4(volRayDir, 0.0);
1371
+ ${Vo("float({X}) + 0.5","contribution *= mix(1.0, volShadow{X}(position, clipOrigin + clipDirection * t), falloff.w);")}
1372
+ }
1373
+ #endif
1374
+ #endif
1375
+ `.replace(/\{X\}/g,r.toString())),i.push(`
1376
+ #if VOL_SHADOW_SLOT_COUNT > {X}
1377
+ #if VOL_SHADOW_LOCAL{X} == 0
1378
+ {
1379
+ // The matrix product is recomputed rather than kept affine: the march already holds many values
1380
+ // alive across its steps, and fewer live registers means more pixels processed in parallel.
1381
+ float shadow = volShadow{X}(position, volShadowMatrix[{X}] * vec4(volCameraPosition + position, 1.0));
1382
+ scattering += volEvalDirectionalLight(volShadowLightData[{X}], volShadowLightDiffuse[{X}]) * mix(1.0, shadow, volShadowLightFalloff[{X}].w);
1383
+ stepLights += 1.0;
1384
+ }
1385
+ #endif
1386
+ #endif
1387
+ `.replace(/\{X\}/g,r.toString())),o.push(`
1388
+ #if VOL_SHADOW_SLOT_COUNT > {X}
1389
+ #if VOL_SHADOW_LOCAL{X} == 1
1390
+ lightResult = volIntegrateShadowSlot{X}(tStart, tEnd);
1391
+ accumulated += lightResult.rgb;
1392
+ evaluatedLights += lightResult.a;
1393
+ #endif
1394
+ #endif
1395
+ `.replace(/\{X\}/g,r.toString()));return`precision highp float;
1396
+ precision highp int;
1397
+
1398
+ varying vec2 vUV;
1399
+
1400
+ // Full resolution linear depth of the scene, written by the linear depth pass.
1401
+ uniform highp sampler2D textureSampler;
1402
+
1403
+ // Ratio between the resolution of the linear depth and the resolution of the scattering buffer.
1404
+ uniform vec2 volDepthRatio;
1405
+
1406
+ uniform mat4 volInverseViewProjection;
1407
+ uniform vec3 volCameraPosition;
1408
+ uniform vec3 volCameraForward;
1409
+ uniform vec2 volCameraMinMaxZ;
1410
+ uniform float volFrameIndex;
1411
+
1412
+ uniform vec4 volFogInfos;
1413
+ uniform vec3 volFogColor;
1414
+ uniform float volLinearFogEps;
1415
+ uniform vec4 volMedium;
1416
+
1417
+ #ifdef VOL_SCREEN_SHADOWS
1418
+ uniform mat4 volViewProjection;
1419
+ uniform vec4 volScreenShadowParams;
1420
+ #endif
1421
+ uniform vec3 volAmbient;
1422
+
1423
+ // (maximum distance, dithering strength, light extinction clamp, number of point and spot lights in the arrays)
1424
+ uniform vec4 volParams;
1425
+
1426
+ #if VOL_MAX_ARRAY_LIGHTS > 0
1427
+ uniform vec4 volLightData[VOL_MAX_ARRAY_LIGHTS];
1428
+ uniform vec4 volLightDiffuse[VOL_MAX_ARRAY_LIGHTS];
1429
+ uniform vec4 volLightDirection[VOL_MAX_ARRAY_LIGHTS];
1430
+ uniform vec4 volLightFalloff[VOL_MAX_ARRAY_LIGHTS];
1431
+ #endif
1432
+
1433
+ #if VOL_SHADOW_SLOT_COUNT > 0
1434
+ uniform vec4 volShadowLightData[VOL_SHADOW_SLOT_COUNT];
1435
+ uniform vec4 volShadowLightDiffuse[VOL_SHADOW_SLOT_COUNT];
1436
+ uniform vec4 volShadowLightDirection[VOL_SHADOW_SLOT_COUNT];
1437
+ uniform vec4 volShadowLightFalloff[VOL_SHADOW_SLOT_COUNT];
1438
+ uniform vec4 volShadowInfo[VOL_SHADOW_SLOT_COUNT];
1439
+ uniform mat4 volShadowMatrix[VOL_SHADOW_SLOT_COUNT];
1440
+ #endif
1441
+
1442
+ #ifdef VOL_CSM
1443
+ uniform vec4 volCsmLightData;
1444
+ uniform vec4 volCsmLightDiffuse;
1445
+ uniform vec4 volCsmLightDirection;
1446
+ uniform vec4 volCsmLightFalloff;
1447
+ uniform vec4 volCsmInfo;
1448
+ uniform mat4 volCsmMatrices[VOL_CSM_CASCADES];
1449
+
1450
+ #if VOL_CSM_KIND == 1
1451
+ uniform highp sampler2DArrayShadow volCsmSampler;
1452
+ #else
1453
+ uniform highp sampler2DArray volCsmSampler;
1454
+ #endif
1455
+ #endif
1456
+
1457
+ // Values shared by every function of the pass, computed once per pixel. Every position the raymarching
1458
+ // manipulates is relative to the camera, which keeps the precision of the lights far from the origin.
1459
+ vec3 volRayDir;
1460
+ float volCosForward;
1461
+ float volNoise;
1462
+ float volJitter;
1463
+
1464
+ #ifdef VOL_SCREEN_SHADOWS
1465
+ ivec2 volDepthSize;
1466
+ vec4 volClipOrigin;
1467
+ vec4 volClipDirection;
1468
+ #endif
1469
+
1470
+ ${rt}
1471
+ ${bi}
1472
+
1473
+ float volFallOff(float value, vec2 clipSpaceXY, float frustumEdgeFalloff) {
1474
+ float mask = smoothstep(1.0 - frustumEdgeFalloff, 1.00000012, clamp(dot(clipSpaceXY, clipSpaceXY), 0.0, 1.0));
1475
+ return mix(value, 1.0, mask);
1476
+ }
1477
+
1478
+ // Reproduces the depth metric computed by the "shadowsVertex" include of Babylon.js: the raw clip space
1479
+ // Z is used, without the perspective divide, so the comparison matches what the shadow map stores.
1480
+ float volDepthMetric(vec4 clip, vec2 depthValues) {
1481
+ #ifdef VOL_REVERSE_DEPTH
1482
+ return (-clip.z + depthValues.x) / depthValues.y;
1483
+ #else
1484
+ return (clip.z + depthValues.x) / depthValues.y;
1485
+ #endif
1486
+ }
1487
+
1488
+ // Henyey-Greenstein phase function. "c" is the cosine of the angle between the direction the light
1489
+ // travels and the direction the ray travels, "g" the anisotropy of the medium.
1490
+ //
1491
+ // Normalised to 1 for an isotropic medium rather than to an integral of 1 over the sphere: the lighting of
1492
+ // the surfaces in Babylon.js doesn't divide by PI either, so an intensity of 1 means the same thing for the
1493
+ // light shafts as it does for the surfaces the same light hits.
1494
+ float volPhaseHG(float c, float g) {
1495
+ float g2 = g * g;
1496
+ float d = max(1.0 + g2 - 2.0 * g * c, 1e-4);
1497
+ return (1.0 - g2) / (d * sqrt(d));
1498
+ }
1499
+
1500
+ float volBayer4(vec2 p) {
1501
+ vec2 p1 = mod(floor(p), 2.0);
1502
+ vec2 p2 = mod(floor(p * 0.5), 2.0);
1503
+
1504
+ float b1 = 2.0 * p1.x + 3.0 * p1.y - 4.0 * p1.x * p1.y;
1505
+ float b2 = 2.0 * p2.x + 3.0 * p2.y - 4.0 * p2.x * p2.y;
1506
+
1507
+ return (b1 * 4.0 + b2) / 16.0;
1508
+ }
1509
+
1510
+ float volInterleavedGradientNoise(vec2 p) {
1511
+ return fract(52.9829189 * fract(dot(p, vec2(0.06711056, 0.00583715))));
1512
+ }
1513
+
1514
+ // Returns the offset of the samples of a light inside their strata. Each light gets its own offset, a golden
1515
+ // ratio sequence seeded by the noise of the pixel, so the lights don't all show the same pattern.
1516
+ float volStratumOffset(float seed) {
1517
+ #if VOL_DITHER == 0
1518
+ return 0.5;
1519
+ #else
1520
+ return mix(0.5, fract(volNoise + seed * 0.618034), volParams.y);
1521
+ #endif
1522
+ }
1523
+
1524
+ // Extinction coefficient of the medium, the exact analytic derivative of its optical depth:
1525
+ // sigma(t) = -d/dt ln(T(t)). Keeping the two in sync is what makes the result independent from the number
1526
+ // of samples the medium is integrated with. "volFogInfos" is (mode, start, end, density).
1527
+ float volFogExtinction(float t) {
1528
+ #if VOL_FOG_MODE == 2
1529
+ // T = (end - t) / (end - start) -> sigma = 1 / (end - t), clamped to avoid the pole at t = end.
1530
+ return t < volFogInfos.y ? 0.0 : 1.0 / max(volFogInfos.z - t, volLinearFogEps);
1531
+ #elif VOL_FOG_MODE == 1
1532
+ // T = e^(-(t * density)^2) -> sigma = 2 * density^2 * t.
1533
+ return 2.0 * volFogInfos.w * volFogInfos.w * t;
1534
+ #else
1535
+ // T = e^(-t * density) -> sigma = density (the medium is uniform).
1536
+ return volFogInfos.w;
1537
+ #endif
1538
+ }
1539
+
1540
+ // "height" is the absolute altitude of the sample, "t" its distance to the camera.
1541
+ float volExtinctionAt(float height, float t) {
1542
+ float sigma = volFogExtinction(t);
1543
+
1544
+ #ifdef VOL_HEIGHT_FOG
1545
+ sigma *= exp(-max(0.0, height - volMedium.y) * volMedium.z);
1546
+ #endif
1547
+
1548
+ return sigma;
1549
+ }
1550
+
1551
+ // Transmittance of the medium between the camera and the point of the view ray at the distance "t". The
1552
+ // three models match the ones the fog of Babylon.js uses, but every value comes from the configuration of
1553
+ // this pipeline: the medium the shafts are computed in is independent from the fog applied on the surfaces.
1554
+ #if VOL_TRANSMITTANCE == 1
1555
+ // Length of medium at full density equivalent to the part [s1, s2] of the view ray, which lies entirely on
1556
+ // one side of the base altitude of the height falloff.
1557
+ float volHeightSegment(float s1, float s2) {
1558
+ float y0 = volCameraPosition.y - volMedium.y;
1559
+ float h1 = y0 + s1 * volRayDir.y;
1560
+ float h2 = y0 + s2 * volRayDir.y;
1561
+
1562
+ // Under the base altitude the medium has its full density.
1563
+ if (h1 + h2 <= 0.0) {
1564
+ return s2 - s1;
1565
+ }
1566
+
1567
+ // Over it, the integral of e^(-falloff * height) along the ray, falling back on the midpoint rule
1568
+ // when the altitude barely changes along the segment, where the closed form would cancel out.
1569
+ float e1 = exp(-volMedium.z * max(h1, 0.0));
1570
+ float e2 = exp(-volMedium.z * max(h2, 0.0));
1571
+ float slope = volMedium.z * volRayDir.y;
1572
+
1573
+ return abs(slope * (s2 - s1)) < 1e-4 ? 0.5 * (e1 + e2) * (s2 - s1) : (e1 - e2) / slope;
1574
+ }
1575
+
1576
+ // Exponential medium whose density decreases with the altitude: exact, split where the ray crosses the base altitude.
1577
+ float volOpticalDepth(float t) {
1578
+ float crossing = abs(volRayDir.y) > 1e-6 ? (volMedium.y - volCameraPosition.y) / volRayDir.y : -1.0;
1579
+ float opticalLength = (crossing > 0.0 && crossing < t) ? volHeightSegment(0.0, crossing) + volHeightSegment(crossing, t) : volHeightSegment(0.0, t);
1580
+
1581
+ return volFogInfos.w * opticalLength;
1582
+ }
1583
+
1584
+ float volTransmittance(float t) {
1585
+ return exp(-volOpticalDepth(t));
1586
+ }
1587
+ #elif VOL_TRANSMITTANCE == 2
1588
+ // The other fog modes combined with the height falloff have no closed form: their optical depth is
1589
+ // integrated once per pixel along the view ray, and interpolated from there.
1590
+ float volOpticalDepths[VOL_TRANSMITTANCE_SAMPLES + 1];
1591
+ float volOpticalDepthStart;
1592
+ float volOpticalDepthScale;
1593
+
1594
+ void volBuildOpticalDepths(float tStart, float tEnd) {
1595
+ float stepSize = (tEnd - tStart) / float(VOL_TRANSMITTANCE_SAMPLES);
1596
+
1597
+ volOpticalDepthStart = tStart;
1598
+ volOpticalDepthScale = 1.0 / stepSize;
1599
+
1600
+ // The medium between the camera and the near plane is too thin to be worth integrating.
1601
+ float previous = volExtinctionAt(volCameraPosition.y + volRayDir.y * tStart, tStart);
1602
+ float opticalDepth = previous * tStart;
1603
+
1604
+ volOpticalDepths[0] = opticalDepth;
1605
+
1606
+ for (int i = 1; i <= VOL_TRANSMITTANCE_SAMPLES; ++i) {
1607
+ float t = tStart + stepSize * float(i);
1608
+ float sigma = volExtinctionAt(volCameraPosition.y + volRayDir.y * t, t);
1609
+
1610
+ opticalDepth += 0.5 * (previous + sigma) * stepSize;
1611
+ volOpticalDepths[i] = opticalDepth;
1612
+ previous = sigma;
1613
+ }
1614
+ }
1615
+
1616
+ float volOpticalDepth(float t) {
1617
+ float x = clamp((t - volOpticalDepthStart) * volOpticalDepthScale, 0.0, float(VOL_TRANSMITTANCE_SAMPLES));
1618
+ int i = min(int(x), VOL_TRANSMITTANCE_SAMPLES - 1);
1619
+
1620
+ return mix(volOpticalDepths[i], volOpticalDepths[i + 1], x - float(i));
1621
+ }
1622
+
1623
+ float volTransmittance(float t) {
1624
+ return exp(-volOpticalDepth(t));
1625
+ }
1626
+ #elif VOL_FOG_MODE == 2
1627
+ // The linear mode is the only one whose transmittance, rather than its optical depth, is simple.
1628
+ float volTransmittance(float t) {
1629
+ return clamp((volFogInfos.z - t) / max(volFogInfos.z - volFogInfos.y, volLinearFogEps), 0.0, 1.0);
1630
+ }
1631
+ #else
1632
+ float volOpticalDepth(float t) {
1633
+ #if VOL_FOG_MODE == 1
1634
+ float x = t * volFogInfos.w;
1635
+ return x * x;
1636
+ #else
1637
+ return t * volFogInfos.w;
1638
+ #endif
1639
+ }
1640
+
1641
+ float volTransmittance(float t) {
1642
+ return exp(-volOpticalDepth(t));
1643
+ }
1644
+ #endif
1645
+
1646
+ // Transmittance of the medium between the camera and the point of the view ray at the distance "t", combined
1647
+ // with the attenuation of the light on its way from the light to that point. Both are exponentials of optical
1648
+ // depths whenever the fog mode allows it, which saves one exponential per sample.
1649
+ float volCombinedTransmittance(float t, float sigmaT, float distanceToLight) {
1650
+ #ifdef VOL_LIGHT_EXTINCTION
1651
+ // Exact for an exponential fog, which describes a homogeneous medium, and a faithful approximation for
1652
+ // the other modes.
1653
+ float lightOpticalDepth = sigmaT * min(distanceToLight, volParams.z);
1654
+
1655
+ #ifdef VOL_OPTICAL_DEPTH
1656
+ return exp(-(volOpticalDepth(t) + lightOpticalDepth));
1657
+ #else
1658
+ return volTransmittance(t) * exp(-lightOpticalDepth);
1659
+ #endif
1660
+ #else
1661
+ return volTransmittance(t);
1662
+ #endif
1663
+ }
1664
+
1665
+ #ifdef VOL_SCREEN_SHADOWS
1666
+ // Walks a segment going from a point of the medium towards a light through the depth buffer, and reports the
1667
+ // point as occluded as soon as one of the samples sits behind what the depth buffer holds. This is what stops
1668
+ // the shafts of a light that has no shadow map from showing through the walls between it and the camera.
1669
+ //
1670
+ // The segment is given in clip space: the sample at the fraction "u" of the segment is "clipStart + u * clipDelta".
1671
+ // The clip space position is affine in the world position, and so is the distance along the view axis, so
1672
+ // interpolating both is exact and replaces the matrix product each sample would cost with multiply-adds.
1673
+ // "volScreenShadowParams" is (maximum traced distance, relative depth bias, relative surface thickness, unused).
1674
+ float volScreenShadow(vec4 clipStart, vec4 clipDelta, float depthStart, float depthDelta) {
1675
+ for (int i = 1; i <= VOL_SCREEN_SHADOW_STEPS; ++i) {
1676
+ // The samples are spread strictly between the shaded point and the end of the segment: the point
1677
+ // itself is on the view ray, so it always sits in front of the depth buffer.
1678
+ float u = (float(i) + volJitter) * (1.0 / float(VOL_SCREEN_SHADOW_STEPS + 1));
1679
+
1680
+ vec4 clip = clipStart + clipDelta * u;
1681
+ if (clip.w <= 0.0) {
1682
+ continue;
1683
+ }
1684
+
1685
+ vec2 uv = (clip.xy / clip.w) * 0.5 + 0.5;
1686
+ if (uv.x < 0.0 || uv.x >= 1.0 || uv.y < 0.0 || uv.y >= 1.0) {
1687
+ continue;
1688
+ }
1689
+
1690
+ float sceneDepth = volReadLinearDepth(textureSampler, ivec2(uv * vec2(volDepthSize)));
1691
+
1692
+ // Bounded by the assumed thickness of the surface: a sample much further away than the surface it is
1693
+ // hidden behind has passed it rather than been stopped by it, and counting it as occluded would
1694
+ // stamp the silhouette of everything in the foreground into the shafts behind it.
1695
+ float depthDifference = depthStart + depthDelta * u - sceneDepth;
1696
+ float bias = max(volScreenShadowParams.y * sceneDepth, volCameraMinMaxZ.x);
1697
+
1698
+ if (depthDifference > bias && depthDifference < volScreenShadowParams.z * sceneDepth) {
1699
+ return 0.0;
1700
+ }
1701
+ }
1702
+
1703
+ return 1.0;
1704
+ }
1705
+
1706
+ // Occlusion of a point or a spot light, seen from the point of the view ray at the distance "t". The
1707
+ // search stops at the light, or after the maximum traced distance when the light is further than that.
1708
+ float volScreenShadowToLight(float t, vec4 lightClip, float lightDepth, float distanceToLight) {
1709
+ vec4 clipStart = volClipOrigin + volClipDirection * t;
1710
+ float depthStart = t * volCosForward;
1711
+ float fraction = min(1.0, volScreenShadowParams.x / max(distanceToLight, 1e-4));
1712
+
1713
+ return volScreenShadow(clipStart, (lightClip - clipStart) * fraction, depthStart, (lightDepth - depthStart) * fraction);
1714
+ }
1715
+ #endif
1716
+
1717
+ // Evaluates the in-scattered radiance coming from a directional light, without any shadowing. "data.xyz"
1718
+ // already holds the direction pointing to the light, and the scattering angle is the angle between the
1719
+ // direction the light travels (-data.xyz) and the direction the ray travels (-volRayDir).
1720
+ vec3 volEvalDirectionalLight(vec4 data, vec4 diffuse) {
1721
+ return diffuse.rgb * volPhaseHG(dot(volRayDir, data.xyz), diffuse.a);
1722
+ }
1723
+
1724
+ // Evaluates the in-scattered radiance coming from a point or a spot light at the given position, relative to
1725
+ // the camera, without any shadowing nor extinction.
1726
+ vec3 volEvalLocalLight(vec4 data, vec4 diffuse, vec4 direction, vec4 falloff, vec3 position, out float distanceToLight) {
1727
+ vec3 toLight = data.xyz - position;
1728
+ distanceToLight = max(length(toLight), 1e-4);
1729
+
1730
+ vec3 lightVector = toLight / distanceToLight;
1731
+
1732
+ // Same linear attenuation as "computeLighting" in the "lightsFragmentFunctions" include.
1733
+ float attenuation = max(0.0, 1.0 - distanceToLight / falloff.x);
1734
+
1735
+ if (data.w == 2.0) {
1736
+ float cosAngle = max(0.0, dot(direction.xyz, -lightVector));
1737
+ attenuation *= (cosAngle >= direction.w) ? max(0.0, pow(cosAngle, falloff.y)) : 0.0;
1738
+ }
1739
+
1740
+ if (attenuation <= 0.0) {
1741
+ return vec3(0.0);
1742
+ }
1743
+
1744
+ return diffuse.rgb * (attenuation * volPhaseHG(dot(volRayDir, lightVector), diffuse.a));
1745
+ }
1746
+
1747
+ // Returns the part of the view ray crossing the cone of a spot light, cut by the sphere of its range.
1748
+ // "apex" is relative to the camera and "sphere" is the part of the ray crossing the sphere of the range.
1749
+ vec2 volConeChord(vec3 apex, vec3 axis, float cosAngle, float range, vec2 sphere) {
1750
+ // Only a convex cone can be intersected exactly, anything wider keeps the sphere of the range.
1751
+ if (cosAngle <= 1e-3) {
1752
+ return sphere;
1753
+ }
1754
+
1755
+ // Expressed in units of the range of the light, which keeps the quadratic well conditioned. A point of the
1756
+ // view ray is inside the cone when "dot(p - apex, axis) >= |p - apex| * cos(angle)".
1757
+ vec3 origin = apex * (-1.0 / range);
1758
+ float dv = dot(volRayDir, axis);
1759
+ float ov = dot(origin, axis);
1760
+ float cos2 = cosAngle * cosAngle;
1761
+
1762
+ float a = dv * dv - cos2;
1763
+ float b = dv * ov - cos2 * dot(volRayDir, origin);
1764
+ float c = ov * ov - cos2 * dot(origin, origin);
1765
+
1766
+ // The ray is parallel to the surface of the cone, the sphere is a conservative bound.
1767
+ if (abs(a) < 1e-4) {
1768
+ return sphere;
1769
+ }
1770
+
1771
+ float discriminant = b * b - a * c;
1772
+ vec2 cone;
1773
+
1774
+ if (a < 0.0) {
1775
+ // Less aligned with the axis than the surface of the cone: the ray crosses it along a single segment.
1776
+ if (discriminant <= 0.0) {
1777
+ return vec2(1.0, -1.0);
1778
+ }
1779
+
1780
+ float s = sqrt(discriminant);
1781
+ cone = vec2((-b + s) / a, (-b - s) / a);
1782
+
1783
+ // The segment must belong to the cone of the light, not to its mirror image behind the apex.
1784
+ if (dv * 0.5 * (cone.x + cone.y) + ov < 0.0) {
1785
+ return vec2(1.0, -1.0);
1786
+ }
1787
+ } else {
1788
+ // More aligned with the axis than the surface: the line crosses both the cone and its mirror image, and
1789
+ // only the half line going in the direction of the axis belongs to the cone of the light.
1790
+ float s = sqrt(max(discriminant, 0.0));
1791
+ cone = dv > 0.0 ? vec2((-b + s) / a, 1e30) : vec2(-1e30, (-b - s) / a);
1792
+ }
1793
+
1794
+ // Slightly widened: the samples outside of the cone are rejected by the lighting itself, while an interval
1795
+ // cut too short by the rounding errors would clip the edges of the cone.
1796
+ return vec2(max(sphere.x, (cone.x - 0.005) * range), min(sphere.y, (cone.y + 0.005) * range));
1797
+ }
1798
+
1799
+ // Returns the part of the view ray, as distances to the camera, crossing the volume a point or a spot light
1800
+ // reaches. An empty part is returned as an interval that ends before it starts.
1801
+ vec2 volLightChord(vec4 data, vec4 direction, float range) {
1802
+ // Computed from the point of the ray closest to the light rather than with the textbook discriminant,
1803
+ // which cancels out catastrophically for the small lights far from the camera.
1804
+ float closest = dot(data.xyz, volRayDir);
1805
+ vec3 offset = data.xyz - volRayDir * closest;
1806
+ float halfChord2 = range * range - dot(offset, offset);
1807
+
1808
+ if (halfChord2 <= 0.0) {
1809
+ return vec2(1.0, -1.0);
1810
+ }
1811
+
1812
+ float halfChord = sqrt(halfChord2);
1813
+ vec2 chord = vec2(closest - halfChord, closest + halfChord);
1814
+
1815
+ if (data.w == 2.0) {
1816
+ chord = volConeChord(data.xyz, direction.xyz, direction.w, range, chord);
1817
+ }
1818
+
1819
+ return chord;
1820
+ }
1821
+
1822
+ // Returns the number of samples taken over the given chord of a light: at least "VOL_LIGHT_STEPS" across the
1823
+ // diameter of the light, and at least the density the directional lights are marched with, so a light covering
1824
+ // most of the view ray is never sampled more coarsely than by a march of the whole ray.
1825
+ int volLocalSampleCount(float chordLength, float range, float rayLength) {
1826
+ float count = max(float(VOL_LIGHT_STEPS) * chordLength / (2.0 * range), float(VOL_STEPS) * chordLength / rayLength);
1827
+ return clamp(int(ceil(count)), 2, VOL_LOCAL_MAX_STEPS);
1828
+ }
1829
+
1830
+ ${e.join(`
1831
+ `)}
1832
+
1833
+ #ifdef VOL_CSM
1834
+ // A cascade is an orthographic box in the clip space of the light, where the view ray is a straight line
1835
+ // "origin + t * direction". The parts of the view ray inside each box are computed once per pixel, so finding
1836
+ // the cascade of a sample only costs a few comparisons, and the clip space position of the view ray is only
1837
+ // recomputed when the march enters another cascade, which happens a handful of times per ray.
1838
+ vec4 volCsmEntries;
1839
+ vec4 volCsmExits;
1840
+ int volCsmCurrent;
1841
+ vec4 volCsmClipOrigin;
1842
+ vec4 volCsmClipDirection;
1843
+
1844
+ // Returns the part of the view ray inside the box of a cascade, keeping the same 2% margin on its sides as
1845
+ // the lookup: a point outside every cascade must stay lit, exactly like the material path does past the
1846
+ // last cascade, and falling back on another cascade would sample its clamped border texel.
1847
+ vec2 volCsmBoxInterval(vec4 origin, vec4 direction) {
1848
+ #ifdef VOL_NDC_HALF_Z
1849
+ vec3 boxMin = vec3(-0.96, -0.96, 0.0);
1850
+ #else
1851
+ vec3 boxMin = vec3(-0.96, -0.96, -1.0);
1852
+ #endif
1853
+ vec3 boxMax = vec3(0.96, 0.96, 1.0);
1854
+
1855
+ // A direction parallel to an axis gives huge bounds of the same sign when the ray is outside of the slab,
1856
+ // and huge bounds of opposite signs when it is inside, which is exactly what the slab test expects.
1857
+ vec3 safeDirection = mix(vec3(1e-9), direction.xyz, greaterThan(abs(direction.xyz), vec3(1e-9)));
1858
+ vec3 inverseDirection = 1.0 / safeDirection;
1859
+ vec3 t0 = (boxMin - origin.xyz) * inverseDirection;
1860
+ vec3 t1 = (boxMax - origin.xyz) * inverseDirection;
1861
+ vec3 tMin = min(t0, t1);
1862
+ vec3 tMax = max(t0, t1);
1863
+
1864
+ return vec2(max(max(tMin.x, tMin.y), tMin.z), min(min(tMax.x, tMax.y), tMax.z));
1865
+ }
1866
+
1867
+ void volPrepareCsm() {
1868
+ volCsmEntries = vec4(1e30);
1869
+ volCsmExits = vec4(-1e30);
1870
+
1871
+ for (int cascade = 0; cascade < VOL_CSM_CASCADES; ++cascade) {
1872
+ vec2 interval = volCsmBoxInterval(volCsmMatrices[cascade] * vec4(volCameraPosition, 1.0), volCsmMatrices[cascade] * vec4(volRayDir, 0.0));
1873
+ volCsmEntries[cascade] = interval.x;
1874
+ volCsmExits[cascade] = interval.y;
1875
+ }
1876
+
1877
+ volCsmCurrent = -1;
1878
+ }
1879
+
1880
+ // Returns the shadowing of the point of the view ray at the distance "t" from the camera.
1881
+ float volCsmShadow(float t) {
1882
+ // The first cascade containing the sample is the most detailed one.
1883
+ int cascade = -1;
1884
+ for (int i = VOL_CSM_CASCADES - 1; i >= 0; --i) {
1885
+ if (t >= volCsmEntries[i] && t <= volCsmExits[i]) {
1886
+ cascade = i;
1887
+ }
1888
+ }
1889
+
1890
+ if (cascade < 0) {
1891
+ return 1.0;
1892
+ }
1893
+
1894
+ if (cascade != volCsmCurrent) {
1895
+ volCsmCurrent = cascade;
1896
+ volCsmClipOrigin = volCsmMatrices[cascade] * vec4(volCameraPosition, 1.0);
1897
+ volCsmClipDirection = volCsmMatrices[cascade] * vec4(volRayDir, 0.0);
1898
+ }
1899
+
1900
+ // The projection of a directional light is orthographic, "w" is always 1.
1901
+ vec4 clip = volCsmClipOrigin + volCsmClipDirection * t;
1902
+ vec3 clipSpace = clip.xyz;
1903
+
1904
+ #if VOL_CSM_KIND == 1
1905
+ vec3 uvDepth = vec3(0.5 * clipSpace + vec3(0.5));
1906
+ #ifdef VOL_NDC_HALF_Z
1907
+ uvDepth.z = clipSpace.z;
1908
+ #endif
1909
+
1910
+ float shadow = texture2D(volCsmSampler, vec4(uvDepth.x, uvDepth.y, float(cascade), uvDepth.z));
1911
+ return volFallOff(mix(volCsmInfo.x, 1.0, shadow), clipSpace.xy, volCsmLightFalloff.z);
1912
+ #else
1913
+ vec2 uv = 0.5 * clipSpace.xy + vec2(0.5);
1914
+ float depthMetric = clamp(volDepthMetric(clip, volCsmInfo.zw), 0.0, 1.0);
1915
+
1916
+ #ifdef VOL_CSM_PACKED
1917
+ float shadowMapSample = volUnpack(texture2D(volCsmSampler, vec3(uv, float(cascade))));
1918
+ #else
1919
+ float shadowMapSample = texture2D(volCsmSampler, vec3(uv, float(cascade))).x;
1920
+ #endif
1921
+
1922
+ return depthMetric > shadowMapSample ? volFallOff(volCsmInfo.x, clipSpace.xy, volCsmLightFalloff.z) : 1.0;
1923
+ #endif
1924
+ }
1925
+ #endif
1926
+
1927
+ #if VOL_GLOBAL_LIGHT_COUNT > 0
1928
+ // Marches the whole view ray for the lights that reach all of it: the directional lights. Returns the
1929
+ // in-scattered radiance in "rgb" and the number of lights evaluated in "a".
1930
+ vec4 volMarchGlobalLights(float tStart, float tEnd) {
1931
+ #if VOL_DIRECTIONAL_LIGHT_COUNT > 0
1932
+ #ifdef VOL_SCREEN_SHADOWS
1933
+ // The occlusion search of a directional light always walks the same direction over the same distance,
1934
+ // only its starting point moves along the view ray.
1935
+ vec4 directionClip[VOL_DIRECTIONAL_LIGHT_COUNT];
1936
+ float directionDepth[VOL_DIRECTIONAL_LIGHT_COUNT];
1937
+
1938
+ for (int li = 0; li < VOL_DIRECTIONAL_LIGHT_COUNT; ++li) {
1939
+ vec3 traced = volLightData[li].xyz * volScreenShadowParams.x;
1940
+ directionClip[li] = volViewProjection * vec4(traced, 0.0);
1941
+ directionDepth[li] = dot(traced, volCameraForward);
1942
+ }
1943
+ #endif
1944
+ #endif
1945
+
1946
+ #if VOL_DISTRIBUTION == 1
1947
+ float ratio = pow(tEnd / tStart, 1.0 / float(VOL_STEPS));
1948
+ #else
1949
+ float uniformStep = (tEnd - tStart) / float(VOL_STEPS);
1950
+ #endif
1951
+
1952
+ vec3 result = vec3(0.0);
1953
+ float evaluatedLights = 0.0;
1954
+ float segmentStart = tStart;
1955
+
1956
+ for (int i = 0; i < VOL_STEPS; ++i) {
1957
+ #if VOL_DISTRIBUTION == 1
1958
+ float segmentEnd = segmentStart * ratio;
1959
+ #else
1960
+ float segmentEnd = segmentStart + uniformStep;
1961
+ #endif
1962
+
1963
+ float segmentBegin = segmentStart;
1964
+ float dt = segmentEnd - segmentBegin;
1965
+
1966
+ // The jitter picks the sample inside its own segment, so the marched interval stays exactly
1967
+ // [tStart, tEnd]. Shifting the whole sequence instead would scale the length of the integrated
1968
+ // path by the jitter and turn the dithering into multiplicative noise.
1969
+ float t = segmentBegin + dt * volJitter;
1970
+ segmentStart = segmentEnd;
1971
+
1972
+ vec3 position = volRayDir * t;
1973
+ float sigmaT = volExtinctionAt(volCameraPosition.y + position.y, t);
1974
+
1975
+ if (sigmaT <= 1e-6) {
1976
+ continue;
1977
+ }
1978
+
1979
+ // The transmittance at the START of the segment: the factor below accounts for the extinction
1980
+ // across the segment itself.
1981
+ float viewTransmittance = volTransmittance(segmentBegin);
1982
+ if (viewTransmittance < 0.003) {
1983
+ break;
1984
+ }
1985
+
1986
+ vec3 scattering = vec3(0.0);
1987
+ float stepLights = 0.0;
1988
+
1989
+ ${i.join("")}
1990
+ #ifdef VOL_CSM
1991
+ {
1992
+ scattering += volEvalDirectionalLight(volCsmLightData, volCsmLightDiffuse) * mix(1.0, volCsmShadow(t), volCsmLightFalloff.w);
1993
+ stepLights += 1.0;
1994
+ }
1995
+ #endif
1996
+
1997
+ #if VOL_DIRECTIONAL_LIGHT_COUNT > 0
1998
+ for (int li = 0; li < VOL_DIRECTIONAL_LIGHT_COUNT; ++li) {
1999
+ vec3 contribution = volEvalDirectionalLight(volLightData[li], volLightDiffuse[li]);
2000
+
2001
+ #ifdef VOL_SCREEN_SHADOWS
2002
+ // "volLightFalloff[li].z" carries whether this light asked to be occluded by the geometry.
2003
+ if (volLightFalloff[li].z > 0.5) {
2004
+ contribution *= volScreenShadow(volClipOrigin + volClipDirection * t, directionClip[li], t * volCosForward, directionDepth[li]);
2005
+ }
2006
+ #endif
2007
+
2008
+ scattering += contribution;
2009
+ stepLights += 1.0;
2010
+ }
2011
+ #endif
2012
+
2013
+ evaluatedLights = max(evaluatedLights, stepLights);
2014
+
2015
+ // Analytic integral of the in-scattering over the segment, "sigma" times "(1 - e^(-sigma * dt)) / sigma".
2016
+ // This is what makes the result independent from the number of steps instead of merely converging to it.
2017
+ result += scattering * (viewTransmittance * (1.0 - exp(-sigmaT * dt)));
2018
+ }
2019
+
2020
+ return vec4(result, evaluatedLights);
2021
+ }
2022
+ #endif
2023
+
2024
+ #if VOL_LOCAL_ARRAY_LIGHTS == 1
2025
+ // Integrates a point or a spot light of the arrays over the part of the view ray crossing its volume.
2026
+ // Returns the in-scattered radiance in "rgb" and whether the light was evaluated in "a".
2027
+ vec4 volIntegrateArrayLight(int index, float tStart, float tEnd) {
2028
+ vec4 data = volLightData[index];
2029
+ vec4 direction = volLightDirection[index];
2030
+ vec4 falloff = volLightFalloff[index];
2031
+
2032
+ vec2 chord = volLightChord(data, direction, falloff.x);
2033
+ float t0 = max(chord.x, tStart);
2034
+ float t1 = min(chord.y, tEnd);
2035
+
2036
+ if (t1 <= t0) {
2037
+ return vec4(0.0);
2038
+ }
2039
+
2040
+ vec4 diffuse = volLightDiffuse[index];
2041
+
2042
+ #ifdef VOL_SCREEN_SHADOWS
2043
+ // "falloff.z" carries whether this light asked to be occluded by the geometry.
2044
+ bool occluded = falloff.z > 0.5;
2045
+ vec4 lightClip = volClipOrigin + volViewProjection * vec4(data.xyz, 0.0);
2046
+ float lightDepth = dot(data.xyz, volCameraForward);
2047
+ #endif
2048
+
2049
+ ${Vo("float(index)",`#ifdef VOL_SCREEN_SHADOWS
2050
+ if (occluded) {
2051
+ contribution *= volScreenShadowToLight(t, lightClip, lightDepth, distanceToLight);
2052
+ }
2053
+ #endif`)}
2054
+ }
2055
+ #endif
2056
+
2057
+ void main(void) {
2058
+ // Reconstruct the world space direction of the view ray from the UV of the pixel.
2059
+ vec4 farPoint = volInverseViewProjection * vec4(vUV * 2.0 - 1.0, 1.0, 1.0);
2060
+ volRayDir = normalize(farPoint.xyz / farPoint.w - volCameraPosition);
2061
+
2062
+ // The depth map stores the distance along the view axis, the ray is not aligned with it.
2063
+ volCosForward = max(dot(volRayDir, volCameraForward), 1e-4);
2064
+
2065
+ ivec2 depthSize = textureSize(textureSampler, 0);
2066
+ float viewZ = volReadLinearDepth(textureSampler, volScatterToDepthTexel(ivec2(gl_FragCoord.xy), depthSize));
2067
+
2068
+ float tEnd = min(viewZ / volCosForward, volParams.x);
2069
+ float tStart = max(volCameraMinMaxZ.x / volCosForward, 1e-3);
2070
+
2071
+ if (tEnd <= tStart) {
2072
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
2073
+ return;
2074
+ }
2075
+
2076
+ // Offsets the samples inside their segments to trade the banding produced by a low sample count for noise.
2077
+ volNoise = 0.0;
2078
+ #if VOL_DITHER == 1
2079
+ volNoise = volBayer4(gl_FragCoord.xy);
2080
+ #elif VOL_DITHER == 2
2081
+ vec2 ditherPosition = gl_FragCoord.xy;
2082
+ #ifdef VOL_TEMPORAL_JITTER
2083
+ ditherPosition += volFrameIndex * 5.588238;
2084
+ #endif
2085
+ volNoise = volInterleavedGradientNoise(ditherPosition);
2086
+ #endif
2087
+ volJitter = volNoise * volParams.y;
2088
+
2089
+ #ifdef VOL_SCREEN_SHADOWS
2090
+ volDepthSize = depthSize;
2091
+ volClipOrigin = volViewProjection * vec4(volCameraPosition, 1.0);
2092
+ volClipDirection = volViewProjection * vec4(volRayDir, 0.0);
2093
+ #endif
2094
+
2095
+ #if VOL_TRANSMITTANCE == 2
2096
+ volBuildOpticalDepths(tStart, tEnd);
2097
+ #endif
2098
+
2099
+ #ifdef VOL_CSM
2100
+ volPrepareCsm();
2101
+ #endif
2102
+
2103
+ float evaluatedLights = 0.0;
2104
+
2105
+ // The in-scattering of the constant ambient light has a closed form whatever the medium: the extinction is
2106
+ // the derivative of the optical depth, so the integral of "sigma * T" along the ray is "T(start) - T(end)".
2107
+ vec3 accumulated = volAmbient * (volTransmittance(tStart) - volTransmittance(tEnd));
2108
+ vec4 lightResult = vec4(0.0);
2109
+
2110
+ #if VOL_GLOBAL_LIGHT_COUNT > 0
2111
+ lightResult = volMarchGlobalLights(tStart, tEnd);
2112
+ accumulated += lightResult.rgb;
2113
+ evaluatedLights += lightResult.a;
2114
+ #endif
2115
+
2116
+ ${o.join("")}
2117
+
2118
+ #if VOL_LOCAL_ARRAY_LIGHTS == 1
2119
+ int localEnd = VOL_DIRECTIONAL_LIGHT_COUNT + int(volParams.w + 0.5);
2120
+
2121
+ for (int i = VOL_DIRECTIONAL_LIGHT_COUNT; i < VOL_MAX_ARRAY_LIGHTS; ++i) {
2122
+ if (i >= localEnd) {
2123
+ break;
2124
+ }
2125
+
2126
+ lightResult = volIntegrateArrayLight(i, tStart, tEnd);
2127
+ accumulated += lightResult.rgb;
2128
+ evaluatedLights += lightResult.a;
2129
+ }
2130
+ #endif
2131
+
2132
+ // The scattering coefficient is a fraction of the extinction, which guarantees energy conservation.
2133
+ vec3 result = accumulated * volMedium.x * volFogColor;
2134
+ float finalTransmittance = volTransmittance(tEnd);
2135
+
2136
+ #if VOL_DEBUG == 3
2137
+ // From blue for no light to red for 16 lights or more evaluated by the pixel.
2138
+ float ratioOfBudget = clamp(evaluatedLights / 16.0, 0.0, 1.0);
2139
+ result = vec3(ratioOfBudget, 1.0 - abs(ratioOfBudget * 2.0 - 1.0), 1.0 - ratioOfBudget);
2140
+ #endif
2141
+
2142
+ #ifdef VOL_LDR_ENCODE
2143
+ result = result / (1.0 + result);
2144
+ #endif
2145
+
2146
+ gl_FragColor = vec4(result, finalTransmittance);
2147
+ }
2148
+ `}a(ra,"buildVolumetricLightingScatteringShader");function na(){return`precision highp float;
2149
+ precision highp int;
2150
+
2151
+ varying vec2 vUV;
2152
+
2153
+ uniform sampler2D textureSampler;
2154
+ uniform highp sampler2D volLinearDepthSampler;
2155
+
2156
+ uniform vec2 volCameraMinMaxZ;
2157
+ uniform vec2 volDepthRatio;
2158
+ uniform vec2 volBlurDirection;
2159
+ uniform vec2 volBlurParams;
2160
+
2161
+ ${rt}
2162
+ ${bi}
2163
+
2164
+ void main(void) {
2165
+ // The blur runs at the resolution of the scattering buffer and every tap is an exact texel, compared using
2166
+ // the depth the raymarching used for it: no filtering is needed, no depth has to be unpacked nor linearized.
2167
+ ivec2 size = textureSize(textureSampler, 0);
2168
+ ivec2 depthSize = textureSize(volLinearDepthSampler, 0);
2169
+ ivec2 center = ivec2(gl_FragCoord.xy);
2170
+ ivec2 direction = ivec2(volBlurDirection);
2171
+
2172
+ float centerDepth = volReadLinearDepth(volLinearDepthSampler, volScatterToDepthTexel(center, depthSize));
2173
+ float inverseDepthThreshold = 1.0 / max(volBlurParams.y * max(centerDepth, volCameraMinMaxZ.x), 1e-4);
2174
+ float sigma = max(volBlurParams.x, 1e-4);
2175
+ float inverseTwoSigma2 = 1.0 / (2.0 * sigma * sigma);
2176
+
2177
+ vec4 result = texelFetch(textureSampler, center, 0);
2178
+ float totalWeight = 1.0;
2179
+
2180
+ for (int i = 1; i <= VOL_BLUR_RADIUS; ++i) {
2181
+ float spatialWeight = exp(-float(i * i) * inverseTwoSigma2);
2182
+
2183
+ ivec2 positive = center + direction * i;
2184
+ ivec2 negative = center - direction * i;
2185
+
2186
+ if (positive.x < size.x && positive.y < size.y) {
2187
+ float weight = spatialWeight * exp(-abs(volReadLinearDepth(volLinearDepthSampler, volScatterToDepthTexel(positive, depthSize)) - centerDepth) * inverseDepthThreshold);
2188
+ result += texelFetch(textureSampler, positive, 0) * weight;
2189
+ totalWeight += weight;
2190
+ }
2191
+
2192
+ if (negative.x >= 0 && negative.y >= 0) {
2193
+ float weight = spatialWeight * exp(-abs(volReadLinearDepth(volLinearDepthSampler, volScatterToDepthTexel(negative, depthSize)) - centerDepth) * inverseDepthThreshold);
2194
+ result += texelFetch(textureSampler, negative, 0) * weight;
2195
+ totalWeight += weight;
2196
+ }
2197
+ }
2198
+
2199
+ gl_FragColor = result / totalWeight;
2200
+ }
2201
+ `}a(na,"buildVolumetricLightingBlurShader");function aa(){return`precision highp float;
2202
+ precision highp int;
2203
+
2204
+ varying vec2 vUV;
2205
+
2206
+ uniform sampler2D textureSampler;
2207
+ uniform sampler2D volSceneSampler;
2208
+ uniform highp sampler2D volLinearDepthSampler;
2209
+
2210
+ uniform vec2 volCameraMinMaxZ;
2211
+ uniform vec2 volDepthRatio;
2212
+ uniform vec4 volComposeParams;
2213
+
2214
+ ${rt}
2215
+ ${bi}
2216
+
2217
+ float volBayer8(vec2 p) {
2218
+ vec2 p1 = mod(floor(p), 2.0);
2219
+ vec2 p2 = mod(floor(p * 0.5), 2.0);
2220
+ vec2 p3 = mod(floor(p * 0.25), 2.0);
2221
+
2222
+ float b1 = 2.0 * p1.x + 3.0 * p1.y - 4.0 * p1.x * p1.y;
2223
+ float b2 = 2.0 * p2.x + 3.0 * p2.y - 4.0 * p2.x * p2.y;
2224
+ float b3 = 2.0 * p3.x + 3.0 * p3.y - 4.0 * p3.x * p3.y;
2225
+
2226
+ return (b1 * 16.0 + b2 * 4.0 + b3) / 64.0;
2227
+ }
2228
+
2229
+ // Nearest depth upsampling: the four low resolution taps around the pixel are weighted by both their
2230
+ // bilinear weight and how close the depth the raymarching used for them is to the depth of the pixel.
2231
+ vec4 volUpsample(float centerDepth, ivec2 depthSize) {
2232
+ ivec2 size = textureSize(textureSampler, 0);
2233
+ vec2 texelCoordinate = vUV * vec2(size) - 0.5;
2234
+ vec2 baseCoordinate = floor(texelCoordinate);
2235
+ vec2 fraction = texelCoordinate - baseCoordinate;
2236
+
2237
+ ivec2 base = ivec2(baseCoordinate);
2238
+ ivec2 maximum = size - 1;
2239
+
2240
+ float inverseDepthThreshold = 1.0 / max(volComposeParams.z * max(centerDepth, volCameraMinMaxZ.x), 1e-4);
2241
+
2242
+ vec4 result = vec4(0.0);
2243
+ float totalWeight = 0.0;
2244
+
2245
+ vec4 nearestSample = vec4(0.0);
2246
+ float nearestDistance = 1e20;
2247
+
2248
+ for (int y = 0; y < 2; ++y) {
2249
+ for (int x = 0; x < 2; ++x) {
2250
+ ivec2 coordinates = clamp(base + ivec2(x, y), ivec2(0), maximum);
2251
+
2252
+ float bilinearWeight = (x == 0 ? 1.0 - fraction.x : fraction.x) * (y == 0 ? 1.0 - fraction.y : fraction.y);
2253
+ float depthDistance = abs(volReadLinearDepth(volLinearDepthSampler, volScatterToDepthTexel(coordinates, depthSize)) - centerDepth);
2254
+
2255
+ vec4 tap = texelFetch(textureSampler, coordinates, 0);
2256
+
2257
+ if (depthDistance < nearestDistance) {
2258
+ nearestDistance = depthDistance;
2259
+ nearestSample = tap;
2260
+ }
2261
+
2262
+ float weight = bilinearWeight / (1e-4 + depthDistance * inverseDepthThreshold);
2263
+ result += tap * weight;
2264
+ totalWeight += weight;
2265
+ }
2266
+ }
2267
+
2268
+ // Every tap sits on the other side of a silhouette, fall back to the closest one instead of averaging.
2269
+ return totalWeight > 1e-4 ? result / totalWeight : nearestSample;
2270
+ }
2271
+
2272
+ void main(void) {
2273
+ // The linear depth has the full resolution of the canvas: same texel the depth map would give with a nearest filter.
2274
+ ivec2 depthSize = textureSize(volLinearDepthSampler, 0);
2275
+ float centerDepth = volReadLinearDepth(volLinearDepthSampler, min(ivec2(vUV * vec2(depthSize)), depthSize - 1));
2276
+
2277
+ vec4 volumetric = volUpsample(centerDepth, depthSize);
2278
+
2279
+ #ifdef VOL_LDR_ENCODE
2280
+ volumetric.rgb = volumetric.rgb / max(vec3(1e-4), 1.0 - volumetric.rgb);
2281
+ #endif
2282
+
2283
+ #if VOL_DEBUG == 1 || VOL_DEBUG == 3
2284
+ gl_FragColor = vec4(volumetric.rgb * volComposeParams.x, 1.0);
2285
+ return;
2286
+ #elif VOL_DEBUG == 2
2287
+ gl_FragColor = vec4(vec3(volumetric.a), 1.0);
2288
+ return;
2289
+ #endif
2290
+
2291
+ vec3 sceneColor = texture2D(volSceneSampler, vUV).rgb;
2292
+
2293
+ // The materials of the scene already attenuated their color with the fog, so this is left at 0 by
2294
+ // default and only becomes useful when the medium is driven by the pipeline instead of the scene fog.
2295
+ sceneColor *= mix(1.0, volumetric.a, volComposeParams.y);
2296
+
2297
+ vec3 result = sceneColor + volumetric.rgb * volComposeParams.x;
2298
+
2299
+ // Breaks up the banding an 8 bits output would otherwise show on the smooth gradients of the shafts.
2300
+ result += (volBayer8(gl_FragCoord.xy) - 0.5) * volComposeParams.w;
2301
+
2302
+ gl_FragColor = vec4(result, 1.0);
2303
+ }
2304
+ `}a(aa,"buildVolumetricLightingComposeShader");var Fo={};function Go(t){if(!Fo[t]){if(Fo[t]=!0,t===No.ShaderLanguage.WGSL){let e=Ro();Z.ShaderStore.ShadersStoreWGSL[`${nt}PixelShader`]=e.linearDepth,Z.ShaderStore.ShadersStoreWGSL[`${at}PixelShader`]=e.scattering,Z.ShaderStore.ShadersStoreWGSL[`${st}PixelShader`]=e.blur,Z.ShaderStore.ShadersStoreWGSL[`${lt}PixelShader`]=e.compose;return}Z.ShaderStore.ShadersStore[`${nt}PixelShader`]=oa(),Z.ShaderStore.ShadersStore[`${at}PixelShader`]=ra(E),Z.ShaderStore.ShadersStore[`${st}PixelShader`]=na(),Z.ShaderStore.ShadersStore[`${lt}PixelShader`]=aa()}}a(Go,"registerVolumetricLightingShaders");var Ho=require("babylonjs"),ko=require("babylonjs"),Y=require("babylonjs"),be=require("babylonjs"),Fe=require("babylonjs"),Uo=require("babylonjs"),xi=require("babylonjs"),Ne=require("babylonjs"),Wo=require("babylonjs"),sa=new be.Vector3(0,0,1),la=new be.Vector3(0,0,-1),Bo=["resolutionScale","blurPasses"],ca=32,pa=["volInverseViewProjection","volViewProjection","volCameraPosition","volCameraForward","volCameraMinMaxZ","volDepthRatio","volFrameIndex","volFogInfos","volFogColor","volLinearFogEps","volMedium","volScreenShadowParams","volAmbient","volParams","volLightData","volLightDiffuse","volLightDirection","volLightFalloff","volShadowLightData","volShadowLightDiffuse","volShadowLightDirection","volShadowLightFalloff","volShadowInfo","volShadowMatrix","volCsmLightData","volCsmLightDiffuse","volCsmLightDirection","volCsmLightFalloff","volCsmInfo","volCsmMatrices"],zo=["volCsmSampler"];for(let t=0;t<E;++t)zo.push(`volShadowSampler${t}`);var q=class t extends Wo.PostProcessRenderPipeline{static{a(this,"VolumetricLightingRenderingPipeline")}static SceneColorEffectName="VolumetricLightingSceneColorEffect";static ScatteringEffectName="VolumetricLightingScatteringEffect";static BlurEffectName="VolumetricLightingBlurEffect";static ComposeEffectName="VolumetricLightingComposeEffect";static GetDefaultFogEnd(e,i){return 1/t.GetDefaultFogDensity(e,i)}static GetDefaultFogDensity(e,i){let o=0;if(e.meshes.length){let r=e.getWorldExtends(),n=r.max.subtract(r.min).length();isFinite(n)&&(o=n)}return o<.001&&(o=Math.max(i.globalPosition.length(),i.maxZ*.001,1)),Math.min(1,Math.max(1e-5,1/Math.max(.001,o)))}static IsSupported(e){return e.isWebGPU?!0:(e.webGLVersion??0)>=2}static GetShaderLanguage(e){return e.isWebGPU?xi.ShaderLanguage.WGSL:xi.ShaderLanguage.GLSL}_scene;_camera;_configuration;_configurationProxy;_textureType;_shaderLanguage;_ldrEncode;_linearDepthPacked;_msaaSamples=1;_msaaSamplesAssigned=!1;_depthSource=0;_depthRenderer=null;_ownsDepthRenderer=!1;_depthMode=0;_prePassConfiguration=gi();_linearDepthPostProcess=null;_scatteringPostProcess=null;_blurPostProcesses=[];_composePostProcess=null;_selection=null;_budget;_linearDepthDefines="";_scatteringDefines="";_blurDefines="";_composeDefines="";_frameCount=0;_lightsDirty=!0;_disposed=!1;_beforeCameraRenderObserver=null;_lightAddedObserver=null;_lightRemovedObserver=null;_inverseViewProjection=be.Matrix.Identity();_temporaryVector=new be.Vector3;_temporaryColor=new ko.Color3;_lightData=new Float32Array(K*4);_lightDiffuse=new Float32Array(K*4);_lightDirection=new Float32Array(K*4);_lightFalloff=new Float32Array(K*4);_shadowLightData=new Float32Array(E*4);_shadowLightDiffuse=new Float32Array(E*4);_shadowLightDirection=new Float32Array(E*4);_shadowLightFalloff=new Float32Array(E*4);_shadowInfo=new Float32Array(E*4);_shadowMatrices=new Float32Array(E*16);_csmLightData=new Float32Array(4);_csmLightDiffuse=new Float32Array(4);_csmLightDirection=new Float32Array(4);_csmLightFalloff=new Float32Array(4);_csmMatrices=new Float32Array(64);constructor(e,i,o,r){super(i.getEngine(),e),this._shaderLanguage=t.GetShaderLanguage(i.getEngine()),Go(this._shaderLanguage),this._scene=i,this._camera=o,this._configuration=Se({...Qe(),fogDensity:r?.fogDensity??t.GetDefaultFogDensity(i,o),fogEnd:r?.fogEnd??t.GetDefaultFogEnd(i,o),screenSpaceShadowMaxDistance:r?.screenSpaceShadowMaxDistance??t.GetDefaultFogEnd(i,o),...r}),this._configurationProxy=new Proxy(this._configuration,{set:a((s,c,m)=>{let h=c;return s[h]===m||(s[h]=m,this._onConfigurationChanged(h)),!0},"set")});let n=i.getEngine(),l=n.getCaps(),p=l.textureHalfFloatRender&&l.textureHalfFloatLinearFiltering;this._textureType=p?Y.Constants.TEXTURETYPE_HALF_FLOAT:Y.Constants.TEXTURETYPE_UNSIGNED_BYTE,this._ldrEncode=!p,this._linearDepthPacked=!l.textureFloatRender,this._budget=Me(n,this._configuration),this._depthSource=it(i),this._setupDepthSource(),this._buildRenderEffects(),i.postProcessRenderPipelineManager.addPipeline(this),i.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this.name,o),this._beforeCameraRenderObserver=i.onBeforeCameraRenderObservable.add(s=>{s===this._camera&&(this._updateDepthSource(),this._updateSelection())}),this._lightAddedObserver=i.onNewLightAddedObservable.add(()=>this.markLightsDirty()),this._lightRemovedObserver=i.onLightRemovedObservable.add(()=>this.markLightsDirty())}get isDisposed(){return this._disposed}get scene(){return this._scene}get camera(){return this._camera}get configuration(){return this._configurationProxy}get depthSource(){return this._depthSource}get msaaSamples(){return this._msaaSamples}set msaaSamples(e){this._msaaSamples=e,this._msaaSamplesAssigned=!0,this._applyMsaaSamples()}getStats(){return this._selection?.stats??null}getBudget(){return this._budget}getClassName(){return"VolumetricLightingRenderingPipeline"}markLightsDirty(){this._lightsDirty=!0}applyConfiguration(e){let i=Se({...this._configuration,...e}),o=Bo.some(r=>i[r]!==this._configuration[r]);Object.assign(this._configuration,i),this._budget=Me(this._scene.getEngine(),this._configuration),this._lightsDirty=!0,o&&this._rebuildRenderEffects()}serializeConfiguration(){return{...this._configuration,fogColor:this._configuration.fogColor.slice(),ambientColor:this._configuration.ambientColor.slice()}}dispose(){if(this._disposed)return;this._disposed=!0,this._scene.onBeforeCameraRenderObservable.remove(this._beforeCameraRenderObserver),this._scene.onNewLightAddedObservable.remove(this._lightAddedObserver),this._scene.onLightRemovedObservable.remove(this._lightRemovedObserver),this._beforeCameraRenderObserver=null,this._lightAddedObserver=null,this._lightRemovedObserver=null;let e=this._cameras.slice();this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this.name,e),this._disposePostProcesses(e),this._releaseDepthSource(),this._selection=null,this._scene.postProcessRenderPipelineManager.removePipeline(this.name),super.dispose()}_onConfigurationChanged(e){(e==="maxLights"||e==="maxShadowedLights")&&(this._budget=Me(this._scene.getEngine(),this._configuration)),this._lightsDirty=!0,Bo.includes(e)&&this._rebuildRenderEffects()}_setupDepthSource(){switch(this._depthSource){case 2:this._depthMode=1;break;case 1:this._ensureGeometryBufferDepth(),this._depthMode=1;break;default:this._setupDepthRenderer();break}this._applyPrePassConfiguration(),this._applyMsaaSamples()}_releaseDepthSource(){this._ownsDepthRenderer&&this._scene.disableDepthRenderer(this._camera),this._depthRenderer=null,this._ownsDepthRenderer=!1,this._linearDepthPostProcess&&(this._linearDepthPostProcess._prePassEffectConfiguration=void 0)}_updateDepthSource(){if(this._disposed)return;let e=it(this._scene);if(e===this._depthSource){e===1&&this._ensureGeometryBufferDepth();return}this._releaseDepthSource(),this._depthSource=e,this._setupDepthSource(),ye(this._scene)?.markAsDirty(),this._lightsDirty=!0}_ensureGeometryBufferDepth(){let e=Ve(this._scene);e&&!e.enableDepth&&(e.enableDepth=!0)}_applyPrePassConfiguration(){this._linearDepthPostProcess&&this._depthSource===2&&(this._linearDepthPostProcess._prePassEffectConfiguration=this._prePassConfiguration)}_applyMsaaSamples(){if(this._msaaSamplesAssigned){if(this._depthSource===2){let e=ye(this._scene);if(e){e.samples=this._msaaSamples;return}}!this._enableMSAAOnFirstPostProcess(this._msaaSamples)&&this._msaaSamples>1&&console.warn("Volumetric lighting: MSAA is not supported by the engine, the requested samples are ignored.")}}_setupDepthRenderer(){let e=this._scene._depthRenderer?.[this._camera.uniqueId];this._ownsDepthRenderer=!e,this._depthRenderer=e??this._scene.enableDepthRenderer(this._camera,!1,!1,Y.Constants.TEXTURE_NEAREST_SAMPLINGMODE,!1),this._depthRenderer.isPacked?this._depthMode=2:this._depthRenderer.clearColor.r===0?this._depthMode=1:this._depthMode=0}_bindDepthUniforms(e){let i=this._camera,o=this._scene.getEngine();if(e.setFloat2("volCameraMinMaxZ",i.minZ,i.maxZ),this._depthMode===1){e.setFloat2("volDepthUnpack",1,0);return}let r=i.mode===Ho.Camera.ORTHOGRAPHIC_CAMERA,n=r?!o.useReverseDepthBuffer&&o.isNDCHalfZRange?0:1:o.useReverseDepthBuffer&&o.isNDCHalfZRange?i.minZ:o.isNDCHalfZRange?0:i.minZ,l=r?o.useReverseDepthBuffer&&o.isNDCHalfZRange?0:1:o.useReverseDepthBuffer&&o.isNDCHalfZRange?0:i.maxZ,p=this._scene.getProjectionMatrix().m,s=p[10],c=p[14];if(!s){e.setFloat2("volDepthUnpack",i.maxZ,0);return}let m=o.useReverseDepthBuffer?-1:1;e.setFloat2("volDepthUnpack",m*(n+l)/s,(-m*n-c)/s)}_getEnvironment(){let e=this._configuration,i=0;return e.heightFogEnabled&&(i=e.fogMode===0?1:2),{depthMode:this._depthMode,ldrEncode:this._ldrEncode,reverseDepth:this._scene.getEngine().useReverseDepthBuffer,ndcHalfZ:this._scene.getEngine().isNDCHalfZRange,fogMode:e.fogMode,transmittance:i,linearDepthPacked:this._linearDepthPacked,arrayLightCapacity:this._budget.maxArrayLights,lightSteps:si(e)}}_buildLinearDepthReadDefines(e){return e.linearDepthPacked?`#define VOL_LINEAR_DEPTH_PACKED
2305
+ `:""}_buildLinearDepthDefines(e){let i=this._buildLinearDepthReadDefines(e);return e.depthMode===2?i+=`#define VOL_DEPTH_PACKED
2306
+ `:e.depthMode===1&&(i+=`#define VOL_DEPTH_VIEWZ
2307
+ `),i}_buildScatteringDefines(e,i){let o=this._configuration,r=e?.shadowed??[],n=e?.directionalCount??0,l=e?.csm??null,p=r.filter(c=>!c.shadow.local).length,s=this._buildLinearDepthReadDefines(i);return s+=`#define VOL_STEPS ${o.steps}
2308
+ `,s+=`#define VOL_LIGHT_STEPS ${i.lightSteps}
2309
+ `,s+=`#define VOL_LOCAL_MAX_STEPS ${Math.max(i.lightSteps,o.steps)}
2310
+ `,s+=`#define VOL_DISTRIBUTION ${o.stepDistribution}
2311
+ `,s+=`#define VOL_DITHER ${o.ditherMode}
2312
+ `,s+=`#define VOL_PCF_TAPS ${o.pcfTaps}
2313
+ `,s+=`#define VOL_FOG_MODE ${i.fogMode}
2314
+ `,s+=`#define VOL_TRANSMITTANCE ${i.transmittance}
2315
+ `,(i.transmittance!==0||i.fogMode!==2)&&(s+=`#define VOL_OPTICAL_DEPTH
2316
+ `),s+=`#define VOL_TRANSMITTANCE_SAMPLES ${ca}
2317
+ `,s+=`#define VOL_DEBUG ${o.debugMode}
2318
+ `,s+=`#define VOL_MAX_ARRAY_LIGHTS ${i.arrayLightCapacity}
2319
+ `,s+=`#define VOL_DIRECTIONAL_LIGHT_COUNT ${n}
2320
+ `,s+=`#define VOL_LOCAL_ARRAY_LIGHTS ${i.arrayLightCapacity>n?1:0}
2321
+ `,s+=`#define VOL_SHADOW_SLOT_COUNT ${r.length}
2322
+ `,s+=`#define VOL_GLOBAL_LIGHT_COUNT ${n+p+(l?1:0)}
2323
+ `,o.ditherMode!==0&&o.temporalJitter&&(s+=`#define VOL_TEMPORAL_JITTER
2324
+ `),o.heightFogEnabled&&(s+=`#define VOL_HEIGHT_FOG
2325
+ `),o.lightExtinctionEnabled&&(s+=`#define VOL_LIGHT_EXTINCTION
2326
+ `),o.screenSpaceShadows&&(s+=`#define VOL_SCREEN_SHADOWS
2327
+ `,s+=`#define VOL_SCREEN_SHADOW_STEPS ${o.screenSpaceShadowSteps}
2328
+ `),i.ldrEncode&&(s+=`#define VOL_LDR_ENCODE
2329
+ `),i.reverseDepth&&(s+=`#define VOL_REVERSE_DEPTH
2330
+ `),i.ndcHalfZ&&(s+=`#define VOL_NDC_HALF_Z
2331
+ `),r.forEach((c,m)=>{s+=`#define VOL_SHADOW_KIND${m} ${c.shadow.kind}
2332
+ `,s+=`#define VOL_SHADOW_MODE${m} ${c.shadow.mode}
2333
+ `,s+=`#define VOL_SHADOW_LOCAL${m} ${c.shadow.local?1:0}
2334
+ `,c.shadow.packed&&(s+=`#define VOL_SHADOW_PACKED${m}
2335
+ `)}),l&&(s+=`#define VOL_CSM
2336
+ `,s+=`#define VOL_CSM_CASCADES ${l.cascades}
2337
+ `,s+=`#define VOL_CSM_KIND ${l.kind===1?1:0}
2338
+ `,l.packed&&(s+=`#define VOL_CSM_PACKED
2339
+ `)),s}_buildBlurDefines(e){return`${this._buildLinearDepthReadDefines(e)}#define VOL_BLUR_RADIUS ${this._configuration.blurRadius}
2340
+ `}_buildComposeDefines(e){let i=this._buildLinearDepthReadDefines(e);return i+=`#define VOL_DEBUG ${this._configuration.debugMode}
2341
+ `,e.ldrEncode&&(i+=`#define VOL_LDR_ENCODE
2342
+ `),i}_createPostProcess(e){let i=new Uo.PostProcess(e.name,e.shaderName,e.uniforms,e.samplers,e.ratio,null,e.samplingMode,this._scene.getEngine(),!1,e.defines,e.textureType,void 0,void 0,!1,e.textureFormat,this._shaderLanguage);return i.autoClear=!1,i.alphaMode=Y.Constants.ALPHA_DISABLE,i}_buildRenderEffects(){let e=this._scene.getEngine(),i=this._configuration,o=this._getEnvironment();this._linearDepthDefines=this._buildLinearDepthDefines(o),this._scatteringDefines=this._buildScatteringDefines(this._selection,o),this._blurDefines=this._buildBlurDefines(o),this._composeDefines=this._buildComposeDefines(o),this._linearDepthPostProcess=this._createPostProcess({name:"VolumetricLightingLinearDepth",shaderName:nt,uniforms:["volCameraMinMaxZ","volDepthUnpack"],samplers:["depthSampler"],ratio:1,samplingMode:Fe.Texture.BILINEAR_SAMPLINGMODE,textureType:this._textureType,defines:this._linearDepthDefines}),this._linearDepthPostProcess.onApplyObservable.add(r=>this._bindLinearDepth(r)),this._applyPrePassConfiguration(),this._scatteringPostProcess=this._createPostProcess({name:"VolumetricLightingScattering",shaderName:at,uniforms:pa,samplers:zo,ratio:1,samplingMode:Fe.Texture.NEAREST_SAMPLINGMODE,textureType:this._linearDepthPacked?Y.Constants.TEXTURETYPE_UNSIGNED_BYTE:Y.Constants.TEXTURETYPE_FLOAT,textureFormat:this._linearDepthPacked?Y.Constants.TEXTUREFORMAT_RGBA:Y.Constants.TEXTUREFORMAT_R,defines:this._scatteringDefines}),this._scatteringPostProcess.onApplyObservable.add(r=>this._bindScattering(r)),this._blurPostProcesses=[];for(let r=0;r<i.blurPasses;++r){let n=this._createPostProcess({name:`VolumetricLightingBlur${r}`,shaderName:st,uniforms:["volCameraMinMaxZ","volDepthRatio","volBlurDirection","volBlurParams"],samplers:["volLinearDepthSampler"],ratio:i.resolutionScale,samplingMode:Fe.Texture.BILINEAR_SAMPLINGMODE,textureType:this._textureType,defines:this._blurDefines});n.onApplyObservable.add(l=>this._bindBlur(l,r)),this._blurPostProcesses.push(n)}this._composePostProcess=this._createPostProcess({name:"VolumetricLightingCompose",shaderName:lt,uniforms:["volCameraMinMaxZ","volDepthRatio","volComposeParams"],samplers:["volSceneSampler","volLinearDepthSampler"],ratio:i.resolutionScale,samplingMode:Fe.Texture.BILINEAR_SAMPLINGMODE,textureType:this._textureType,defines:this._composeDefines}),this._composePostProcess.onApplyObservable.add(r=>this._bindCompose(r)),this.addEffect(new Ne.PostProcessRenderEffect(e,t.SceneColorEffectName,()=>this._linearDepthPostProcess,!0)),this.addEffect(new Ne.PostProcessRenderEffect(e,t.ScatteringEffectName,()=>this._scatteringPostProcess,!0)),this._blurPostProcesses.length&&this.addEffect(new Ne.PostProcessRenderEffect(e,t.BlurEffectName,()=>this._blurPostProcesses,!0)),this.addEffect(new Ne.PostProcessRenderEffect(e,t.ComposeEffectName,()=>this._composePostProcess,!0)),this._applyMsaaSamples()}_disposePostProcesses(e){[this._linearDepthPostProcess,this._scatteringPostProcess,...this._blurPostProcesses,this._composePostProcess].forEach(o=>{o&&(e.forEach(r=>o.dispose(r)),o.dispose())}),this._linearDepthPostProcess=null,this._scatteringPostProcess=null,this._blurPostProcesses=[],this._composePostProcess=null}_rebuildRenderEffects(){if(this._disposed)return;let e=this._scene.postProcessRenderPipelineManager,i=this._cameras.slice();try{e.detachCamerasFromRenderPipeline(this.name,i),this._disposePostProcesses(i),Object.keys(this._renderEffects).forEach(o=>{delete this._renderEffects[o]}),this._buildRenderEffects()}catch(o){console.error("Failed to rebuild the volumetric lighting rendering pipeline.",o)}finally{try{e.attachCamerasToRenderPipeline(this.name,i)}catch(o){console.error("Failed to re-attach the cameras to the volumetric lighting rendering pipeline.",o)}}this._lightsDirty=!0}_updateSelection(){if(this._disposed||!this._scatteringPostProcess||(++this._frameCount,!(this._lightsDirty||!this._selection||this._frameCount%this._configuration.selectionRefreshRate===0)))return;this._lightsDirty=!1;let i=this._getEnvironment(),o=di(this._scene,this._camera,this._configuration,this._budget,this._selection);this._selection=o;let r=this._buildScatteringDefines(o,i);r!==this._scatteringDefines&&(this._scatteringDefines=r,this._scatteringPostProcess.updateEffect(r));let n=this._buildLinearDepthDefines(i);n!==this._linearDepthDefines&&(this._linearDepthDefines=n,this._linearDepthPostProcess?.updateEffect(n));let l=this._buildBlurDefines(i);l!==this._blurDefines&&(this._blurDefines=l,this._blurPostProcesses.forEach(s=>s.updateEffect(l)));let p=this._buildComposeDefines(i);p!==this._composeDefines&&(this._composeDefines=p,this._composePostProcess?.updateEffect(p))}_writeLight(e,i,o,r,n,l){let{light:p,config:s}=e,c=i*4;ie(p)?(Re(p,this._temporaryVector),o[c]=-this._temporaryVector.x,o[c+1]=-this._temporaryVector.y,o[c+2]=-this._temporaryVector.z,o[c+3]=1):(et(p,this._temporaryVector).subtractInPlace(this._camera.globalPosition),o[c]=this._temporaryVector.x,o[c+1]=this._temporaryVector.y,o[c+2]=this._temporaryVector.z,o[c+3]=ne(p)?2:0),s.useCustomColor?this._temporaryColor.set(s.color[0],s.color[1],s.color[2]):this._temporaryColor.copyFrom(p.diffuse);let m=p.getScaledIntensity()*s.volumeIntensity*1e-5;r[c]=this._temporaryColor.r*m,r[c+1]=this._temporaryColor.g*m,r[c+2]=this._temporaryColor.b*m,r[c+3]=s.anisotropy,ne(p)?(Re(p,this._temporaryVector),n[c]=this._temporaryVector.x,n[c+1]=this._temporaryVector.y,n[c+2]=this._temporaryVector.z,n[c+3]=Math.cos(p.angle*.5),l[c+1]=p.exponent):(n[c]=0,n[c+1]=0,n[c+2]=1,n[c+3]=-1,l[c+1]=1),l[c]=tt(p,s,this._configuration),l[c+2]=s.castVolumetricShadows?1:0,l[c+3]=s.shadowDarkness}_bindLinearDepth(e){let i=null;switch(this._depthSource){case 2:{let o=ye(this._scene);i=o?vi(o):null;break}case 1:{let o=Ve(this._scene);i=o?Si(o):null;break}default:i=this._depthRenderer?.getDepthMap()??null;break}i&&(e.setTexture("depthSampler",i),this._bindDepthUniforms(e))}_bindScattering(e){let i=this._scene,o=this._camera,r=this._configuration,n=this._selection;if(!n)return;this._inverseViewProjection.copyFrom(i.getTransformMatrix()),this._inverseViewProjection.invert(),e.setMatrix("volInverseViewProjection",this._inverseViewProjection),e.setVector3("volCameraPosition",o.globalPosition),o.getDirectionToRef(i.useRightHandedSystem?la:sa,this._temporaryVector),e.setVector3("volCameraForward",this._temporaryVector.normalize()),e.setFloat2("volCameraMinMaxZ",o.minZ,o.maxZ),e.setFloat("volFrameIndex",i.getRenderId()%64),this._bindDepthRatio(e),e.setFloat4("volFogInfos",r.fogMode,r.fogStart,r.fogEnd,r.fogDensity),this._temporaryColor.set(r.fogColor[0],r.fogColor[1],r.fogColor[2]),e.setColor3("volFogColor",this._temporaryColor),e.setFloat("volLinearFogEps",Math.max((r.fogEnd-r.fogStart)*.02,1e-4)),e.setFloat4("volMedium",r.albedo,r.heightFogBaseHeight,r.heightFogFalloff,0),r.screenSpaceShadows&&(e.setMatrix("volViewProjection",i.getTransformMatrix()),e.setFloat4("volScreenShadowParams",r.screenSpaceShadowMaxDistance,r.screenSpaceShadowBias,r.screenSpaceShadowThickness,0)),this._temporaryColor.set(r.ambientColor[0],r.ambientColor[1],r.ambientColor[2]).scaleInPlace(r.ambientIntensity),e.setColor3("volAmbient",this._temporaryColor);let l=n.unshadowed.length,p=l-n.directionalCount;e.setFloat4("volParams",r.maxDistance,r.ditherStrength,r.lightExtinctionClamp,p);for(let s=0;s<l;++s)this._writeLight(n.unshadowed[s],s,this._lightData,this._lightDiffuse,this._lightDirection,this._lightFalloff);if(l){let s=l*4;e.setFloatArray4("volLightData",this._lightData.subarray(0,s)),e.setFloatArray4("volLightDiffuse",this._lightDiffuse.subarray(0,s)),e.setFloatArray4("volLightDirection",this._lightDirection.subarray(0,s)),e.setFloatArray4("volLightFalloff",this._lightFalloff.subarray(0,s))}if(n.shadowed.forEach((s,c)=>{this._writeLight(s.candidate,c,this._shadowLightData,this._shadowLightDiffuse,this._shadowLightDirection,this._shadowLightFalloff);let{generator:m,kind:h,mode:d,mapSize:f}=s.shadow,S=s.candidate.light,g=c*4;this._shadowLightFalloff[g+2]=m.frustumEdgeFalloff;let b=S.getDepthMinZ?.(i.activeCamera)??0,L=S.getDepthMaxZ?.(i.activeCamera)??1;this._shadowInfo[g]=m.getDarkness(),this._shadowInfo[g+1]=h===1?1/f:d===0?0:m.depthScale,this._shadowInfo[g+2]=b,this._shadowInfo[g+3]=b+L,m.getTransformMatrix().copyToArray(this._shadowMatrices,c*16);let _=m.getShadowMapForRendering();h===1?e.setDepthStencilTexture(`volShadowSampler${c}`,_):e.setTexture(`volShadowSampler${c}`,_)}),n.shadowed.length){let s=n.shadowed.length*4;e.setFloatArray4("volShadowLightData",this._shadowLightData.subarray(0,s)),e.setFloatArray4("volShadowLightDiffuse",this._shadowLightDiffuse.subarray(0,s)),e.setFloatArray4("volShadowLightDirection",this._shadowLightDirection.subarray(0,s)),e.setFloatArray4("volShadowLightFalloff",this._shadowLightFalloff.subarray(0,s)),e.setFloatArray4("volShadowInfo",this._shadowInfo.subarray(0,s)),e.setMatrices("volShadowMatrix",this._shadowMatrices.subarray(0,n.shadowed.length*16))}if(n.csm){let{candidate:s,generator:c,cascades:m,kind:h}=n.csm,d=s.light;this._writeLight(s,0,this._csmLightData,this._csmLightDiffuse,this._csmLightDirection,this._csmLightFalloff),e.setFloat4("volCsmLightData",this._csmLightData[0],this._csmLightData[1],this._csmLightData[2],this._csmLightData[3]),e.setFloat4("volCsmLightDiffuse",this._csmLightDiffuse[0],this._csmLightDiffuse[1],this._csmLightDiffuse[2],this._csmLightDiffuse[3]),e.setFloat4("volCsmLightDirection",this._csmLightDirection[0],this._csmLightDirection[1],this._csmLightDirection[2],this._csmLightDirection[3]),e.setFloat4("volCsmLightFalloff",this._csmLightFalloff[0],this._csmLightFalloff[1],c.frustumEdgeFalloff,s.config.shadowDarkness);let f=d.getDepthMinZ?.(i.activeCamera)??1,S=d.getDepthMaxZ?.(i.activeCamera)??1,g=c.getShadowMap()?.getSize().width??1024;e.setFloat4("volCsmInfo",c.getDarkness(),1/g,f,f+S);for(let L=0;L<m;++L)c.getCascadeTransformMatrix(L)?.copyToArray(this._csmMatrices,L*16);e.setMatrices("volCsmMatrices",this._csmMatrices.subarray(0,m*16));let b=c.getShadowMapForRendering();h===1?e.setDepthStencilTexture("volCsmSampler",b):e.setTexture("volCsmSampler",b)}}_bindDepthRatio(e){let i=this._scatteringPostProcess,o=this._blurPostProcesses[0]??this._composePostProcess,r=i&&i.width>0?i.width:1,n=i&&i.height>0?i.height:1,l=o&&o.width>0?o.width:r,p=o&&o.height>0?o.height:n;e.setFloat2("volDepthRatio",r/l,n/p)}_bindBlur(e,i){this._scatteringPostProcess&&(e.setTextureFromPostProcess("volLinearDepthSampler",this._scatteringPostProcess),e.setFloat2("volCameraMinMaxZ",this._camera.minZ,this._camera.maxZ),this._bindDepthRatio(e),e.setFloat2("volBlurDirection",i%2===0?1:0,i%2===0?0:1),e.setFloat2("volBlurParams",Math.max(this._configuration.blurRadius*.5,.5),this._configuration.blurDepthThreshold))}_bindCompose(e){if(!this._linearDepthPostProcess||!this._scatteringPostProcess)return;let i=this._configuration;e.setTextureFromPostProcess("volSceneSampler",this._linearDepthPostProcess),e.setTextureFromPostProcess("volLinearDepthSampler",this._scatteringPostProcess),e.setFloat2("volCameraMinMaxZ",this._camera.minZ,this._camera.maxZ),this._bindDepthRatio(e);let o=this._ldrEncode?1/255:0;e.setFloat4("volComposeParams",i.intensity,i.extinctionAmount,i.upsampleDepthThreshold,o)}};var M=null,xe=new Map;function ma(){return M?.isDisposed&&(M=null),M}a(ma,"getVolumetricLightingRenderingPipeline");function ha(t){M=t}a(ha,"setVolumetricLightingRenderingPipelineRef");function da(t){let e=t?.getEngine();return e?q.IsSupported(e):!1}a(da,"isVolumetricLightingSupported");function Ci(){M&&(M.dispose(),M=null)}a(Ci,"disposeVolumetricLightingRenderingPipeline");function Xo(t,e,i){return M=new q("VolumetricLightingRenderingPipeline",t,e),M.msaaSamples=i?.msaaSamples??1,M}a(Xo,"createVolumetricLightingRenderingPipeline");function Li(){return M?M.serializeConfiguration():null}a(Li,"serializeVolumetricLightingRenderingPipeline");function Di(t,e,i,o){let r=M??Xo(t,e,o);r.msaaSamples=o?.msaaSamples??1;let n={...i};return n.fogDensity===void 0&&(n.fogDensity=q.GetDefaultFogDensity(r.scene,r.camera)),n.fogEnd===void 0&&(n.fogEnd=q.GetDefaultFogEnd(r.scene,r.camera)),n.screenSpaceShadowMaxDistance===void 0&&(n.screenSpaceShadowMaxDistance=q.GetDefaultFogEnd(r.scene,r.camera)),r.applyConfiguration(Se(n)),r}a(Di,"parseVolumetricLightingRenderingPipeline");function fa(){M?.markLightsDirty()}a(fa,"markVolumetricLightsDirty");var ct=require("babylonjs");function ua(t){ue.set(t,Xt()),he.set(t,Ft()),de.set(t,Bt()),ge.set(t,Zt()),xe.set(t,Li()),ve.set(t,Jt()),fe.set(t,kt())}a(ua,"saveRenderingConfigurationForCamera");function _i(t,e,i){Wt(),Vt(t.getScene()),Gt(),jt(),Ci(),Qt(),Ht();let o=ue.get(t);o&&!i?.ssao2Disabled&&$t(t.getScene(),t,o,i);let r=xe.get(t);r&&!i?.volumetricLightingDisabled&&Di(t.getScene(),t,r,i);let n=he.get(t);n&&!i?.vlsDisabled&&Nt(t.getScene(),n,i);let l=de.get(t);l&&!i?.ssrDisabled&&zt(t.getScene(),t,l,i);let p=ge.get(t);p&&!i?.motionBlurDisabled&&Yt(t.getScene(),t,p,i);let s=ve.get(t);s&&!i?.defaultPipelineDisabled&&ei(t.getScene(),t,s,e,i);let c=fe.get(t);c&&!i?.taaDisabled&&Ut(t.getScene(),t,c,i)}a(_i,"applyRenderingConfigurationForCamera");function ga(t){let e=t.getCaps();return e.textureHalfFloatRender||e.textureFloatRender}a(ga,"canUseHdr");function $(t){let e=t.getCaps();return e.textureHalfFloatRender?ct.Constants.TEXTURETYPE_HALF_FLOAT:e.textureFloatRender?ct.Constants.TEXTURETYPE_FLOAT:ct.Constants.TEXTURETYPE_UNSIGNED_BYTE}a($,"getHdrTextureType");var Ge=require("babylonjs"),$o=require("babylonjs");function Ko(t){let e=t.metadata?.physicsAggregate;if(!e)return;let i;F(t)?i=t:Te(t)&&(i=t.sourceMesh);let o=new $o.PhysicsAggregate(t,e.shape.type,{mesh:i,mass:e.massProperties.mass});o.body.setMassProperties({mass:e.massProperties.mass,inertia:e.massProperties.inertia?Ge.Vector3.FromArray(e.massProperties.inertia):void 0,centerOfMass:e.massProperties.centerOfMass?Ge.Vector3.FromArray(e.massProperties.centerOfMass):void 0,inertiaOrientation:e.massProperties.inertiaOrientation?Ge.Quaternion.FromArray(e.massProperties.inertiaOrientation):void 0}),o.shape.density=e.shape.density,o.body.setMotionType(e.body.motionType),o.shape.material=e.material,t.physicsAggregate=o,t.metadata.physicsAggregate=void 0}a(Ko,"configurePhysicsAggregate");function jo(t,e){(Array.isArray(e)?e:[]).forEach(o=>{let r=t.getCameraById(o.cameraId);r&&(o.ssao2RenderingPipeline&&ue.set(r,o.ssao2RenderingPipeline),o.vlsPostProcess&&he.set(r,o.vlsPostProcess),o.ssrRenderingPipeline&&de.set(r,o.ssrRenderingPipeline),o.motionBlurPostProcess&&ge.set(r,o.motionBlurPostProcess),o.volumetricLightingRenderingPipeline&&xe.set(r,o.volumetricLightingRenderingPipeline),o.defaultRenderingPipeline&&ve.set(r,o.defaultRenderingPipeline),o.taaRenderingPipeline&&fe.set(r,o.taaRenderingPipeline))})}a(jo,"applyRenderingConfigurations");var Zo=require("babylonjs");function Ce(t,e,i){return new Promise((o,r)=>{let n=new Zo.WebRequest;n.open("GET",t),n.responseType=e,n.send(),n.addEventListener("progress",l=>{i?.({total:l.total,loaded:l.loaded})}),n.addEventListener("load",()=>{o(e==="text"?n.responseText:n.response)}),n.addEventListener("error",l=>r(l))})}a(Ce,"loadFile");async function z(t,e){let i=await Ce(t,"text",e);return JSON.parse(i)}a(z,"loadJsonFile");function Pi(t,e){let i=e.getNodeByName(t);if(i)return i;let o=e.lights.filter(r=>pe(r));for(let r of o){let n=r.lights.find(l=>l.name===t);if(n)return n}return null}a(Pi,"getNodeByName");function Le(t,e){let i=e.getNodeById(t);if(i)return i;let o=e.lights.filter(r=>pe(r));for(let r of o){let n=r.lights.find(l=>l.id===t);if(n)return n}return null}a(Le,"getNodeById");var le=require("babylonjs"),Yo=require("babylonjs");function wi(t){let e=Yo.Vector3.FromArray(t);return e.equals(le.Axis.X)?le.Axis.X:e.equals(le.Axis.Y)?le.Axis.Y:e.equals(le.Axis.Z)?le.Axis.Z:e}a(wi,"parseAxis");var qo=require("babylonjs"),Q=require("babylonjs");function Qo(t){return t.runtimeConfiguration.forEach(e=>{e.rotationAxis&&(e.rotationAxis=wi(e.rotationAxis)),e.boneOffsetAxis&&(e.boneOffsetAxis=wi(e.boneOffsetAxis))}),t}a(Qo,"parseRagdollConfiguration");function Oi(t){let e={rootNodeId:t.rootNodeId,skeletonName:t.skeletonName,scalingFactor:t.scalingFactor,runtimeConfiguration:t.runtimeConfiguration.map(i=>({name:i.name,bones:i.bones,width:i.width,depth:i.depth,height:i.height,size:i.size,joint:i.joint,min:i.min,max:i.max,mass:i.mass??1,boxOffset:i.boxOffset,restitution:i.restitution??0,rotationAxis:i.rotationAxis?.slice(),boneOffsetAxis:i.boneOffsetAxis?.slice()}))};return Qo(e)}a(Oi,"copyAndParseRagdollConfiguration");function va(t,e){let i=t.getConstraints(),r=t._skeleton?.getChildren()[0],n=[];if(e.forEach(p=>{(p.bone!==void 0?[p.bone]:p.bones).forEach(c=>{c!==r?.name&&n.push(p)})}),n.length!==i.length)return qo.Logger.Warn("Failed to apply the ragdoll joint limits: the constraints of the ragdoll don't match its configuration."),0;let l=0;return i.forEach((p,s)=>{let c=n[s];if((c.joint??Q.PhysicsConstraintType.HINGE)!==Q.PhysicsConstraintType.HINGE||c.min===void 0||c.max===void 0)return;let h=Math.min(c.min,c.max),d=Math.max(c.min,c.max),f=p._physicsPlugin;f&&(f.setAxisMode(p,Q.PhysicsConstraintAxis.ANGULAR_X,Q.PhysicsConstraintAxisLimitMode.LIMITED),f.setAxisMinLimit(p,Q.PhysicsConstraintAxis.ANGULAR_X,h*Math.PI/180),f.setAxisMaxLimit(p,Q.PhysicsConstraintAxis.ANGULAR_X,d*Math.PI/180),++l)}),l}a(va,"applyRagdollJointLimits");function Sa(t){return new Promise(e=>{setTimeout(()=>e(),t)})}a(Sa,"waitMs");async function Ei(t){for(;!t();)await Sa(150)}a(Ei,"waitUntil");function Ti(t){return t&&JSON.parse(JSON.stringify(t))}a(Ti,"cloneJSObject");var Ii=require("babylonjs"),nr=require("babylonjs"),pt=require("babylonjs"),ar=require("babylonjs"),sr=require("babylonjs"),lr=require("babylonjs"),oe=require("babylonjs"),Jo=!1,er=null,De=[],Ai=new Map;function ya(t,e){let i=(0,oe._GetAudioEngine)(null);return new lr._WebAudioStaticSound(t,i,e)}a(ya,"createSoundInstance");function tr(t){if(er?.remove(),!De.length)return;let e=Ii.Vector3.Zero();er=t.onBeforeRenderObservable.add(()=>{let i=(0,oe._GetAudioEngine)(null).listener.attachedNode;i&&(i.getWorldMatrix().getTranslationToRef(e),De.forEach(o=>{o.isEnabled(!1)&&o.autoUpdateSpatial&&o.sound?._isSpatial&&o.isPlaying()&&t.activeCamera&&Ii.Vector3.Distance(e,o.getAbsolutePosition())<=o.sound.spatial.maxDistance&&o.sound.spatial.update()}))})}a(tr,"registerUpdateSoundsObserver");function ir(t,e){e.onDisposeObservable.addOnce(()=>{let i=De.indexOf(t);i!==-1&&De.splice(i,1)})}a(ir,"registerSoundInstanceCleanup");function or(t){t.sound&&ir(t,t.sound),t.onDisposeObservable.addOnce(()=>{t.sound?.dispose()})}a(or,"registerSoundNodeEvents");function ba(t,e){return new Promise(async(i,o)=>{if(!t.offlineProvider||!nr.Database.IDBStorageEnabled)return(0,oe.CreateSoundBufferAsync)(e).then(r=>i(r)).catch(r=>o(r));t.offlineProvider.loadFile(e,r=>{(0,oe.CreateSoundBufferAsync)(r).then(n=>i(n)).catch(n=>o(n))},void 0,()=>{o(null)},!0)})}a(ba,"loadSoundBuffer");function Mi(t,e){if(!t.soundRelativePath||!t.sound)return;e.onSoundLoadedObservable=new ar.Observable;let i=ya(t.soundRelativePath,{spatialAutoUpdate:!1});i._initAsync(t.sound.buffer,{spatialAutoUpdate:!0}).then(()=>{i.volume=t.volume,i._isSpatial=t.sound._isSpatial,i._isSpatial&&(i.spatial.attach(e),i.spatial.maxDistance=t.sound.spatial.maxDistance,i.spatial.panningModel=t.sound.spatial.panningModel,i.spatial.distanceModel=t.sound.spatial.distanceModel),e.sound=i,e.soundRelativePath=t.soundRelativePath,e.autoUpdateSpatial=t.autoUpdateSpatial,De.push(e),ir(e,i),tr(e.getScene()),e.onSoundLoadedObservable.notifyObservers(e)}),or(e),rr(e,i)}a(Mi,"configureSourceNodeFrom");function rr(t,e){Object.defineProperty(t,"volume",{get:a(()=>e.volume,"get"),set:a(i=>{e.volume=i},"set")}),Object.defineProperty(t,"playbackRate",{get:a(()=>e.playbackRate,"get"),set:a(i=>{e.playbackRate=i},"set")}),t.isPaused=()=>e.state===pt.SoundState.Paused,t.isPlaying=()=>e.state===pt.SoundState.Started,t.isStopped=()=>e.state===pt.SoundState.Stopped,t.pause=()=>e.pause(),t.resume=()=>e.resume(),t.stop=i=>e.stop(i),t.play=i=>e.play(i),t.setVolume=(i,o)=>e.setVolume(i,o),t.getClassName=()=>"SoundNode",t.setSoundSpatial=i=>new Promise(o=>{e._isSpatial=i,setTimeout(()=>{i&&e.spatial.attach(t),o()})}),t.cloneAsync=async(i,o,r)=>new Promise(n=>{let l=t.clone(i,o,r);Mi(t,l),l.onSoundLoadedObservable.addOnce(()=>{setTimeout(()=>n(l))})})}a(rr,"configureSoundNodePrototype");function cr(){Jo||(Jo=!0,(0,sr.AddParser)("SoundNode",(t,e,i,o)=>{t.transformNodes?.forEach(r=>{if(!r.isSoundNode)return;let n=i.transformNodes?.find(l=>l.id===r.id);if(n&&r.soundRelativePath){let l=`${o}${r.soundRelativePath}`;e.addPendingData(l),Ai.has(l)||Ai.set(l,ba(e,l)),Ai.get(l).then(s=>{(0,oe.CreateSoundAsync)(r.soundRelativePath,s,{spatialAutoUpdate:!1}).then(c=>{if(e.removePendingData(l),n.isDisposed())return c.dispose();c.volume=r.volume,c._isSpatial=r.isSpatial,r.isSpatial&&(c.spatial.attach(n),c.spatial.maxDistance=r.maxDistance,c.spatial.panningModel=r.panningModel,c.spatial.distanceModel=r.distanceModel),n.sound=c,n.soundRelativePath=r.soundRelativePath,n.autoUpdateSpatial=r.autoUpdateSpatial,De.push(n),or(n),rr(n,c),tr(e)})})}})}))}a(cr,"registerAudioParser");var pr=require("babylonjs");function _e(t){let e=new Set;[...t.transformNodes,...t.meshes].forEach(o=>{if(o.metadata?.isStaticGroup){let r=o.getDescendants(!1);r.push(o),r.forEach(n=>{if((re(n)||te(n)&&!n.isWorldMatrixFrozen)&&n.billboardMode===pr.AbstractMesh.BILLBOARDMODE_NONE&&n.freezeWorldMatrix(),re(n)){let l=n.material;l&&!l.isFrozen&&!e.has(l)&&(e.add(l),l.onBindObservable.addOnce(()=>{l.freeze()}))}})}})}a(_e,"configureTransformNodes");var Be=class{constructor(e,i){this.entries=e;this.namingId=i}entries;namingId;static{a(this,"AdvancedAssetContainerInstantiatedEntries")}get rootNodes(){return this.entries.rootNodes}get skeletons(){return this.entries.skeletons}get animationGroups(){return this.entries.animationGroups}dispose(){this.entries.dispose()}getRootNodeByName(e){let i=`${e}-${this.namingId}`;return this.entries.rootNodes.find(o=>o.name===i)??null}getNodeByName(e){let i=`${e}-${this.namingId}`;for(let o of this.entries.rootNodes){let r=this._recursivelyGetNodeByName(i,o);if(r)return r}return null}_recursivelyGetNodeByName(e,i){if(i.name===e)return i;for(let o of i.getDescendants(!0)){let r=this._recursivelyGetNodeByName(e,o);if(r)return r}return null}getScriptByClassByObjectName(e,i){let o=this.getNodeByName(e);if(o){let r=Pe(o,i);if(r?.length===1)return r[0]}return null}};var Ri=require("babylonjs"),ze=class{static{a(this,"AdvancedAssetContainer")}container;_rootUrl;_scriptsMap;_originalDescendants=[];_nodesMap=new Map;_animationGroupsMap=new Map;constructor(e,i,o){this.container=e,this._rootUrl=i,this._scriptsMap=o,e.populateRootNodes(),e.rootNodes.forEach(r=>{this._originalDescendants.push(r,...r.getDescendants(!1))}),e.animationGroups.forEach(r=>{this._animationGroupsMap.set(r.name,r)}),this._originalDescendants.forEach(r=>{this._nodesMap.set(r,{node:r,metadata:Ti(r.metadata)})})}removeDefault(){this.container.getNodes().forEach(e=>{H.get(e)?.forEach(o=>{mt(e,o)})}),this.container.removeAllFromScene()}getRootNodeByName(e){return this.container.rootNodes.find(i=>i.name===e)??null}getScriptByClassByObjectName(e,i){let o=this.container.getNodes();for(let r of o)if(r.name===e){let n=Pe(r,i);if(n?.length===1)return n[0]}return null}instantiate(e){let i=Ri.Tools.RandomId(),o=a(s=>s,"nameFunction"),r=this.container.instantiateModelsToScene(o,!1,{...e,predicate:a(s=>(s.name=`${s.name}@editor-tools@${i}_${s.id}`,e?.predicate?.(s)??!0),"predicate")}),n=new Be(r,i);[...this.container.transformNodes,...this.container.meshes,...this.container.lights,...this.container.cameras,...this.container.animationGroups,...this.container.skeletons].forEach(s=>{let c=s.name.split("@editor-tools@");s.name=c[0]}),r.animationGroups.forEach(s=>{let c=s.name.split("@editor-tools@");s.name=`${c[0]}-${i}`});let p=[];return r.rootNodes.forEach(s=>{p.push(s,...s.getDescendants(!1))}),p.forEach(s=>{let c=s.name.split("@editor-tools@"),m=c[1].split("_").pop();s.name=`${c[0]}-${i}`;let h=this._originalDescendants.find(d=>d.id===m);ae(h)&&te(s)&&Mi(h,s),s.id=Ri.Tools.RandomId(),s.metadata=Ti(this._nodesMap.get(h).metadata),s.metadata??={},s.metadata.originalId=m,p.forEach(d=>{d.metadata.scripts?.forEach(f=>{Object.keys(f.values||{}).forEach(g=>{let b=f.values[g];if(b.type==="entity"){b.value===m&&(b.value=s.id),b.value===h.name&&(b.value=s.name);let L=this._animationGroupsMap.get(b.value);L&&(b.value=`${L.name}-${i}`)}})})})}),p.forEach(s=>{B(this.container.scene,s,this._scriptsMap,this._rootUrl)}),_e(this.container.scene),n}};var mr=require("babylonjs"),hr=require("babylonjs");async function dr(t,e,i){let o=i.iblIntensity,r=i.environmentIntensity,l=t.split("/").pop().replace(".scene",".babylon"),p=await(0,hr.LoadAssetContainerAsync)(l,i,{rootUrl:e,pluginExtension:".babylon"});return mr.SceneLoaderFlags.ForceFullSceneLoadingForIncremental&&i.meshes.forEach(s=>F(s)&&s._checkDelayState()),p.addAllToScene(),i.iblIntensity=o,i.environmentIntensity=r,_e(i),p}a(dr,"preloadSceneScriptAsset");async function fr(t,e){return z(`${e}${t}`)}a(fr,"preloadCommonScriptAsset");var I=new Map,He=new Map;function xa(t,e){He.has(t)&&console.warn(`A parser for the extension '${t}' was already registered. It will be overwritten.`),He.set(t,e)}a(xa,"registerScriptAssetParser");async function Vi(t,e,i){[e,...e.transformNodes,...e.meshes,...e.lights,...e.cameras].filter(p=>p.metadata?.scripts?.length).map(p=>p.metadata.scripts).flat().forEach(p=>{if(i[p.key]?.default?._SceneAssets?.forEach(c=>{I.get(c.sceneName)||I.set(c.sceneName,null)}),p.values)for(let c in p.values){if(!p.values.hasOwnProperty(c))continue;let m=p.values[c];m.type==="asset"&&m.value&&!I.get(m.value)&&I.set(m.value,null)}});let n=0;for(let p of I.values())p===null&&++n;if(n===0)return n;let l=[];return I.forEach((p,s)=>{I.get(s)||l.push(new Promise(async c=>{try{let m=s.split(".").pop();switch(m){case"scene":let h=await dr(s,t,e);e.onDisposeObservable.addOnce(()=>{h.dispose(),I.delete(s)}),I.set(s,new ze(h,t,i));break;default:if(He.has(m)){let d=He.get(m);I.set(s,await d({key:s,rootUrl:t,scene:e}));break}else I.set(s,await fr(s,t));break}}catch(m){console.error(m)}c()}))}),await Promise.all(l),n}a(Vi,"_preloadScriptsAssets");var ur=require("babylonjs"),ht=require("babylonjs"),gr=require("babylonjs"),dt=require("babylonjs"),vr=require("babylonjs"),Sr=require("babylonjs-gui");function Fi(t,e,i,o,r){let n=o.constructor;if(!n)return;n._NodesFromScene?.forEach(s=>{o[s.propertyKey.toString()]=Pi(s.nodeName,t)}),n._ComponentsFromScene?.length&&t.getEngine().onBeginFrameObservable.addOnce(()=>{n._ComponentsFromScene?.forEach(s=>{let c=[];if([t,...t.transformNodes,...t.meshes,...t.lights,...t.cameras].forEach(h=>{let d=Ni(h,s.componentConstructor);d&&c.push(d)}),c.length>1)throw new Error(`Multiple components of type ${n._ComponentsFromScene[0].componentConstructor.name} found in scene for property "${n._ComponentsFromScene[0].propertyKey.toString()}".`);o[s.propertyKey.toString()]=c[0]??null})}),n._NodesFromDescendants?.forEach(s=>{let c=e.getDescendants?.(s.directDescendantsOnly,m=>m.name===s.nodeName)[0];o[s.propertyKey.toString()]=c??null}),n._AnimationGroups?.forEach(s=>{o[s.propertyKey.toString()]=t.getAnimationGroupByName(s.animationGroupName)}),n._SoundsFromScene?.forEach(s=>{let c=Pi(s.soundName,t);c&&ae(c)&&(o[s.propertyKey.toString()]=c??null)}),(n._GuiFromAsset??[]).map(async s=>{let c=`${r}assets/${s.pathInAssets}`;try{let m=await z(c),h=Sr.AdvancedDynamicTexture.CreateFullscreenUI(m.name,!0,t);h.parseSerializedObject(m.content,!1),o[s.propertyKey.toString()]=h,s.onGuiCreated?.(o,h)}catch(m){throw console.error(`Failed to load GUI from asset: ${c}`),m}}),n._ParticleSystemsFromScene?.forEach(s=>{let c=t.particleSystems?.find(m=>m.name!==s.particleSystemName?!1:s.directDescendantsOnly?m.emitter===e:m);o[s.propertyKey.toString()]=c}),(n._VisibleInInspector??[]).forEach(s=>{let c=s.propertyKey.toString(),m=i.values;if(!m)throw new Error(`No values found for script with key "${i.key}".`);if(m.hasOwnProperty(c)&&m[c].hasOwnProperty("value")){let h=m[c].value;switch(s.configuration.type){case"number":case"boolean":case"keymap":case"string":o[c]=h;break;case"vector2":o[c]=dt.Vector2.FromArray(h);break;case"vector3":o[c]=dt.Vector3.FromArray(h);break;case"color3":o[c]=ht.Color3.FromArray(h);break;case"color4":o[c]=ht.Color4.FromArray(h);break;case"entity":switch(s.configuration.entityType){case"node":case"sound":o[c]=Le(h,t)??null;break;case"animationGroup":o[c]=t.getAnimationGroupByName(h)??null;break;case"particleSystem":o[c]=t.particleSystems?.find(f=>f.id===h)??null;break}break;case"texture":h&&(o[c]=gr.Texture.Parse(h,t,r));break;case"asset":if(h){let f=s.configuration.assetType,S=I.get(h);switch(f){case"json":case"gui":case"scene":case"navmesh":case"cinematic":o[c]=S;break;case"ragdoll":o[c]=Oi(S);break;case"nodeParticleSystemSet":let g=vr.NodeParticleSystemSet.Parse(S);o[c]=g;break;case"material":o[c]=ur.Material.Parse(S,t,r);break}}}}});let l=null,p=null;if(n._PointerEvents?.length){if(n._PointerEvents.find(m=>m.options.mode==="attachedMeshOnly")&&!re(e))throw new Error('@onPointerEvent with mode "attachedMeshOnly" can only be used on scripts attached to meshes (extends AbstractMesh).');if(n._PointerEvents.find(m=>m.options.mode!=="global")&&!me(e))throw new Error('@onPointerEvent with mode different from "global" can be used only on scripts attached to Node: Mesh, Light, Camera, TransformNode.');l=t.onPointerObservable.add(m=>{let h=null;n._PointerEvents.forEach(d=>{if(!d.eventTypes.includes(m.type))return;let f=d.propertyKey.toString();if(d.options.mode==="global")return o[f]?.(m);h=m.pickInfo,h||(h=t.pick(t.pointerX,t.pointerY,g=>g.isVisible&&g.isPickable&&g.isEnabled(!0)&&!g._masterMesh,!1));let S=h.pickedMesh;if(S&&(d.options.mode==="attachedMeshOnly"&&S===e||d.options.mode==="includeDescendants"&&me(e)&&[e,...e.getDescendants(!1)].find(L=>L===S)))return o[f]?.(m)})})}if(n._KeyboardEvents?.length&&(p=t.onKeyboardObservable.add(s=>{n._KeyboardEvents.forEach(c=>{c.eventTypes.includes(s.type)&&o[c.propertyKey.toString()]?.(s)})})),n._SpritesFromSpriteManager?.length){let s=e;if(!te(s)||!s.isSpriteManager)return console.error("@spriteFromSpriteManager decorator can only be used on SpriteManagerNode.");if(!s.spriteManager)return console.error(`SpriteManagerNode "${s.name}" has no sprite manager assigned.`);n._SpritesFromSpriteManager?.forEach(c=>{let m=s.spriteManager?.sprites.find(h=>h.name===c.spriteName)||null;o[c.propertyKey.toString()]=m})}if(n._AnimationsFromSprite?.length){if(!Ot(e))return console.error("@animationFromSprite decorator can only be used in scripts attached on Sprite.");let s=e.metadata?.spriteAnimations;if(!s?.length)return console.error(`Sprite "${e.name}" has no sprite animations assigned.`);n._AnimationsFromSprite.forEach(c=>{let m=s.find(h=>h.name===c.animationName);m?o[c.propertyKey.toString()]=m??null:console.warn(`Sprite animation named "${c.animationName}" not found on sprite "${e.name}".`)})}return n._SceneAssets?.forEach(s=>{o[s.propertyKey.toString()]=I.get(s.sceneName)}),{observers:{pointerObserver:l,keyboardObserver:p}}}a(Fi,"applyDecorators");function B(t,e,i,o){e.metadata?.scripts&&(e.metadata.scripts?.forEach(r=>{if(!r.enabled)return;let n=i[r.key];if(!n)return;let l=n,p={};if(n.default){l=new n.default(e);let s=Fi(t,e,r,l,o);Object.assign(p,s?.observers??{})}l.onStart&&(p.onStartObserver=t.onBeforeRenderObservable.addOnce(()=>l.onStart(e))),l.onUpdate&&(p.onUpdateObserver=t.onBeforeRenderObservable.add(()=>l.onUpdate(e))),Gi(e,l,r.key,p)}),e.metadata.scripts=void 0)}a(B,"_applyScriptsForObject");function Ca(t,e,i){if(i??=t.getScene?.(),!i)throw new Error("Cannot apply script on object: no scene available.");let o=new e(t),r={};return Fi(i,t,{values:{}},o,""),o.onStart&&(r.onStartObserver=i.onBeforeRenderObservable.addOnce(()=>o.onStart())),o.onUpdate&&i.onBeforeRenderObservable.add(()=>o.onUpdate()),Gi(t,o,"runtime",r),o}a(Ca,"applyScriptOnObject");var H=new Map;function Gi(t,e,i,o){let r={key:i,observers:o,instance:e};H.has(t)?H.get(t).push(r):H.set(t,[r]),(me(t)||wt(t)||_t(t)||ae(t))&&t.onDisposeObservable.addOnce((()=>{H.get(t)?.slice()?.forEach(l=>{mt(t,l)}),H.delete(t)}))}a(Gi,"_registerScriptInstance");function mt(t,e){e.observers.onStartObserver?.remove(),e.observers.onUpdateObserver?.remove(),e.observers.pointerObserver?.remove(),e.observers.keyboardObserver?.remove();try{e.instance.onStop?.(t)}catch(r){console.error(`Failed to call onStop for script ${e.key} on object ${t}`,r)}let i=H.get(t),o=i?.indexOf(e)??-1;o!==-1&&i?.splice(o,1)}a(mt,"_removeRegisteredScriptInstance");function Pe(t,e){return H.get(t)?.filter(r=>r.instance.constructor===e)?.map(r=>r.instance)??null}a(Pe,"getAllScriptsByClassForObject");function Ni(t,e){return Pe(t,e)?.[0]??null}a(Ni,"getScriptByClassForObject");var br=require("babylonjs"),yr=!1;function xr(){yr||(yr=!0,(0,br.AddParser)("MeshEditorPlugin",(t,e,i,o)=>{t.meshes?.forEach(r=>{r.instances?.forEach(n=>{let l=i.meshes?.find(p=>p.id===n.id);l&&n.billboardMode!==void 0&&(l.billboardMode=n.billboardMode)})})}))}a(xr,"registerMeshParser");var Cr=!1;function La(t){Cr=t}a(La,"setUseKtx2CompressedTextures");function ke(){return Cr}a(ke,"isUsingKtx2CompressedTextures");function ft(t){return`${t.substring(0,t.lastIndexOf("."))}.ktx2`}a(ft,"_getKtx2TextureName");function Da(t){t.setCompressedTextureExclusions([".env",".hdr",".dds"]),t.setTextureFormatToUse(["-dxt.ktx","-astc.ktx","-pvrtc.ktx","-etc1.ktx","-etc2.ktx"])}a(Da,"configureEngineToUseCompressedTextures");function ut(t,e){t._excludedCompressedTextures&&!t._excludedCompressedTextures?.includes(e)&&t._excludedCompressedTextures?.push(e)}a(ut,"addExcludedCompressedTexture");function _a(t,e,i){e.loadingTexturesQuality!==t&&(e.loadingTexturesQuality=t,e.textures.forEach(o=>{if(!Ae(o)||!o.url)return;let r=gt(o,e);!r||o.url.includes(r)||o.updateURL(i+r)}))}a(_a,"applyTexturesQuality");function gt(t,e){if(e.loadingTexturesQuality==="high"||!t.metadata?.baseSize)return t.name;let i=t.metadata.baseSize.width,o=t.metadata.baseSize.height,r=i===N(i)||o===N(o),n="";switch(e.loadingTexturesQuality){case"medium":let d=i*.66>>0,f=o*.66>>0;r&&(d=N(d),f=N(f)),n=`_${d}_${f}`;break;case"low":case"very-low":let S=i*.33>>0,g=o*.33>>0;r&&(S=N(S),g=N(g)),n=`_${S}_${g}`;break}let l=t.name;if(!l||!n)return t.name;let p=l.split("/"),s=p.pop();if(!s)return t.name;let c=s.split(".").pop(),h=`${s.replace(`.${c}`,"")}${n}.${c}`;return p.push(h),p.join("/")}a(gt,"getTextureUrl");var Bi=require("babylonjs"),Lr=!1;function Dr(){if(Lr)return;Lr=!0;let t=Bi.SerializationHelper._TextureParser;Bi.SerializationHelper._TextureParser=(e,i,o)=>{ke()&&(e.name&&(e.name=ft(e.name)),e.url&&(e.url=ft(e.url)));let r=gt(e,i);if(!r)return t(e,i,o);let n=e.name;e.name=r;let l=t(e,i,o);return l&&(l.name=n),l}}a(Dr,"registerTextureParser");function zi(t){if(!Array.isArray(t.frames)){let e=[];for(let i of Object.keys(t.frames))e.push({filename:i,...t.frames[i]});t.frames=e}}a(zi,"normalizeAtlasJson");function Pa(t,e,i){let r=(t.metadata?.spriteAnimations??[]).find(n=>n.name===e);if(!r)return console.error(`Animation with name "${e}" not found on sprite.`);t.playAnimation(r.from,r.to,r.loop,r.delay,i)}a(Pa,"playSpriteAnimationFromName");var Pr=require("babylonjs"),wr=require("babylonjs"),Or=require("babylonjs"),Er=require("babylonjs"),Hi=require("babylonjs"),we=require("babylonjs"),Tr=require("babylonjs"),_r=!1;function Ar(){_r||(_r=!0,(0,Tr.AddParser)("SpriteMapNode",(t,e,i,o)=>{t.transformNodes?.forEach(r=>{if(!r.isSpriteMap)return;let n=i.transformNodes?.find(s=>s.id===r.id);if(!n)return;n.isSpriteMap=r.isSpriteMap;let l=`${o}${r.atlasJsonRelativePath}`;e.addPendingData(l);let p=new Or.WebRequest;p.open("GET",l),p.send(),p.addEventListener("load",()=>{e.removePendingData(l);let s=JSON.parse(p.responseText);zi(s);let c=`${Pr.Tools.GetFolderPath(l)}${s.meta.image}`,m=new Hi.Texture(c,e,!1,!1,Hi.Texture.NEAREST_NEAREST,null,null,null,!1,wr.Engine.TEXTUREFORMAT_RGBA),h=new Er.SpriteMap(n.name,s,m,{layerCount:r.options.layerCount,stageSize:we.Vector2.FromArray(r.options.stageSize??[10,1]),outputSize:we.Vector2.FromArray(r.options.outputSize??[100,100]),colorMultiply:we.Vector3.FromArray(r.options.colorMultiply??[1,1,1]),flipU:!0},e);r.getClassName=()=>"SpriteMapNode",r.tiles.forEach(f=>{for(let S=0,g=f.repeatCount.x+1;S<g;++S)for(let b=0,L=f.repeatCount.y+1;b<L;++b){let _=S*(f.repeatOffset.x+1),x=b*(f.repeatOffset.y+1);h.changeTiles(f.layer,new we.Vector2(f.position.x+_,(h.options.stageSize?.y??0)-1-f.position.y-x),f.tile)}});let d=h._output;d.parent=n,n.spriteMap=h})})}))}a(Ar,"registerSpriteMapParser");var Mr=require("babylonjs"),Rr=require("babylonjs"),vt=require("babylonjs"),Vr=require("babylonjs"),Ir=!1;function Fr(){if(Ir)return;Ir=!0,(0,Vr.RegisterShadowGeneratorSceneComponent)(Rr.ShadowGenerator);let t=(0,vt.GetParser)(Mr.SceneComponentConstants.NAME_SHADOWGENERATOR);(0,vt.AddParser)("ShadowGeneratorEditorPlugin",(e,i,o,r)=>{let n=new Map;e.shadowGenerators?.forEach(l=>{if(n.set(l.id,l.mapSize),i.loadingShadowsQuality!=="high"){switch(i.loadingShadowsQuality){case"medium":l.mapSize=l.mapSize*.5;break;case"low":l.mapSize=l.mapSize*.25;break;case"very-low":l.mapSize=l.mapSize*.125;break}l.mapSize=Math.max(128,N(l.mapSize))}}),t?.(e,i,o,r),i.lights.forEach(l=>{let p=l.getShadowGenerator();if(p?.getShadowMap()){let c=p.id,m=n.get(c);m&&(p.originalMapSize=m)}})})}a(Fr,"registerShadowGeneratorParser");var Br=require("babylonjs"),zr=require("babylonjs"),Hr=require("babylonjs"),ki=require("babylonjs"),kr=require("babylonjs");function Nr(t,e){e?.fogEnabled!==void 0&&(t.fogEnabled=e?.fogEnabled),e?.blendMode!==void 0&&(t.blendMode=e?.blendMode),e?.disableDepthWrite!==void 0&&(t.disableDepthWrite=e?.disableDepthWrite),e?.pixelPerfect!==void 0&&(t.pixelPerfect=e?.pixelPerfect),e?.useLogarithmicDepth!==void 0&&(t.useLogarithmicDepth=e?.useLogarithmicDepth),e?.metadata!==void 0&&(t.metadata=e?.metadata);for(let i of e?.sprites??[]){let o=zr.Sprite.Parse(i,t);o.uniqueId=i.uniqueId,o.metadata=i.metadata}}a(Nr,"parseSerializedSpriteManager");var Gr=!1;function Ur(){Gr||(Gr=!0,(0,kr.AddParser)("SpriteManagerNode",(t,e,i,o)=>{t.transformNodes?.forEach(r=>{if(!r.isSpriteManager)return;let n=i.transformNodes?.find(p=>p.id===r.id);if(!n)return;let l=e.getEngine();if(n.isSpriteManager=r.isSpriteManager,r.atlasJsonRelativePath){let p=`${o}${r.atlasJsonRelativePath}`;e.addPendingData(p);let s=new Hr.WebRequest;s.open("GET",p),s.send(),s.addEventListener("load",()=>{e.removePendingData(p);let c=JSON.parse(s.responseText),m=`${Br.Tools.GetFolderPath(p)}${c.meta.image}`;ut(l,m);let h=new ki.SpriteManager(n.name,m,1e3,64,e,void 0,void 0,!0,c);n.spriteManager=h,n.getClassName=()=>"SpriteManagerNode",r.spriteManager&&Nr(h,r.spriteManager)})}else if(r.spriteManager?.textureUrl){ut(l,r.spriteManager.textureUrl);let p=`${o}${r.spriteManager.textureUrl}`,s=new ki.SpriteManager(n.name,p,1e3,{width:r.spriteManager.cellWidth,height:r.spriteManager.cellHeight},e,void 0,void 0,!1);n.spriteManager=s,n.getClassName=()=>"SpriteManagerNode",r.spriteManager&&Nr(s,r.spriteManager)}})}))}a(Ur,"registerSpriteManagerParser");var Xr=require("babylonjs"),$r=require("babylonjs"),Wr=!1;function Kr(){Wr||(Wr=!0,(0,$r.AddParser)("MorphTargetManagerEditorPlugin",(t,e,i,o)=>{t.morphTargetManagers.forEach(r=>{let l=i.meshes.find(c=>c.id===r.meshId)?.morphTargetManager;if(!l||r.targets.find(c=>!c.delayLoadingFile))return;let s=[];r.targets.forEach(c=>{if(!c.delayLoadingFile)return s.push(Promise.resolve(null));let m=`${o}${c.delayLoadingFile}`;e.addPendingData(m);let h=new Xr.WebRequest;h.responseType="arraybuffer",h.open("GET",m),h.send(),s.push(new Promise(d=>{h.addEventListener("load",()=>{e.removePendingData(m),d(h.response)})}))}),Promise.all(s).then(c=>{for(let m=0,h=l.numTargets;m<h;++m){let d=l.getTarget(m),f=r.targets[m],S=c[m];if(f.positionsCount){let g=new Float32Array(S,f.positionsOffset,f.positionsCount);d._positions=g,d.setPositions(g)}if(f.normalsCount){let g=new Float32Array(S,f.normalsOffset,f.normalsCount);d._normals=g,d.setNormals(g)}if(f.tangentsCount){let g=new Float32Array(S,f.tangentsOffset,f.tangentsCount);d._tangents=g,d.setTangents(g)}if(f.uvsCount){let g=new Float32Array(S,f.uvsOffset,f.uvsCount);d._uvs=g,d.setUVs(g)}if(f.uv2sCount){let g=new Float32Array(S,f.uv2sOffset,f.uv2sCount);d._uv2s=g,d.setUV2s(g)}}for(let m=0,h=l.numTargets;m<h;++m)l.getTarget(m)._onDataLayoutChanged.notifyObservers()})})}))}a(Kr,"registerMorphTargetManagerParser");var Zr=require("babylonjs"),Yr=require("babylonjs"),jr=!1;function qr(){jr||(jr=!0,(0,Zr.AddParser)("NodeParticleSystemSetEditorPlugin",(t,e,i,o)=>{t.meshes?.forEach(r=>{if(!r.isNodeParticleSystemMesh)return;let n=i.meshes?.find(l=>l.id===r.id);n&&(r.nodeParticleSystemSet.blocks?.forEach(l=>{l.url&&(l.url=`${o}${l.url}`)}),n.nodeParticleSystemSet=Yr.NodeParticleSystemSet.Parse(r.nodeParticleSystemSet),n.nodeParticleSystemSet.id=r.nodeParticleSystemSet.id,n.nodeParticleSystemSet.uniqueId=r.uniqueId,e.addPendingData(r.id),n.nodeParticleSystemSet.buildAsync(e,!1).then(l=>{e.removePendingData(r.id),n.particleSystemSet=l,l.systems.forEach(p=>{if(Pt(p)){let s=p._sizeCreation.process;s&&(p._sizeCreation.process=(c,m)=>{s(c,m),c.scale.x*=100,c.scale.y*=100})}}),l.emitterNode=n,l.start()}))})}))}a(qr,"registerNodeParticleSystemSetParser");var Qr=require("babylonjs");function Jr(t,e){e??=new Qr.ClusteredLightContainer("Clustered Light Container",[],t);let i=t.metadata?.clusteredLight;return i&&(i.lights.length>0&&(e.horizontalTiles=i.horizontalTiles,e.verticalTiles=i.verticalTiles,e.depthSlices=i.depthSlices,e.maxRange=i.maxRange),i.lights.forEach(o=>{let r=t.getLightById(o);r&&e?.addLight(r)})),e}a(Jr,"configureLights");var tn=require("babylonjs"),Wi=require("babylonjs"),on=require("babylonjs"),rn=require("babylonjs"),Ui=new Map;async function en(t,e){let i=t.getWaitingItemsCount();for(;!t.isDisposed&&(!t.isReady()||t.getWaitingItemsCount()>0);){await new Promise(r=>setTimeout(r,150));let o=i-t.getWaitingItemsCount();o===i&&t.textures.forEach(r=>{r.delayLoadState===Wi.Constants.DELAYLOADSTATE_NONE&&(r.delayLoadState=Wi.Constants.DELAYLOADSTATE_LOADED)}),e(o/i)}}a(en,"waitForWaitingItems");async function wa(t,e,i,o,r){i.loadingQuality=r?.quality??"high",i.loadingTexturesQuality=r?.texturesQuality??i.loadingQuality,i.loadingShadowsQuality=r?.shadowsQuality??i.loadingQuality,i.loadingLodsQuality=r?.lodsQuality??i.loadingQuality,xr(),cr(),Dr(),Fr(),Kr(),Ar(),Ur(),qr();let n=Ui.get(i)??{};if(Ui.set(i,n),i.onDisposeObservable.addOnce(()=>{Ui.delete(i)}),await(0,on.AppendSceneAsync)(`${t}${e}`,i,{pluginExtension:".babylon",onProgress:a(p=>{let s=Math.min(p.loaded/p.total*.5);r?.onProgress?.(s)},"onProgress")}),await en(i,p=>{r?.onProgress?.(.5+p*.25)}),!r?.skipAssetsPreload){let p=0;do p=await Vi(t,i,o);while(p!==0&&!i.isDisposed)}rn.SceneLoaderFlags.ForceFullSceneLoadingForIncremental&&i.meshes.forEach(p=>F(p)&&p._checkDelayState());let l=Jr(i,n.clusteredLightContainer);n.clusteredLightContainer=l,await en(i,p=>{r?.onProgress?.(.75+p*.25)}),r?.onProgress?.(1),At(i),It(i.loadingLodsQuality,i),Mt(i),qe(i),i.metadata?.rendering&&(jo(i,i.metadata.rendering),i.activeCamera&&_i(i.activeCamera,t,r?.postProcessConfiguration)),i.metadata?.physicsGravity&&i.getPhysicsEngine()?.setGravity(tn.Vector3.FromArray(i.metadata?.physicsGravity)),B(i,i,o,t),i.transformNodes.forEach(p=>{B(i,p,o,t)}),i.meshes.forEach(p=>{Ko(p),B(i,p,o,t)}),i.lights.forEach(p=>{B(i,p,o,t)}),l.lights.forEach(p=>{B(i,p,o,t)}),i.cameras.forEach(p=>{B(i,p,o,t)}),i.spriteManagers?.forEach(p=>{p.sprites.forEach(s=>{B(i,s,o,t)})}),_e(i)}a(wa,"loadScene");var nn=require("babylonjs");async function Oa(t,e,i){let o=await z(t+e),n=nn.Tools.Instantiate(o.customType).Parse(o,i,t);return n.id=o.id,n.uniqueId=o.uniqueId,n}a(Oa,"loadMaterialFromFile");function Ea(t){return Promise.all(t.materials.map(async e=>{let i=e.getBindedMeshes();await Promise.all(i.map(async o=>{Te(o)||await e.forceCompilationAsync(o,{clipPlane:!!t.clipPlane,useInstances:o.hasInstances})}))}))}a(Ea,"forceCompileAllSceneMaterials");var J=require("babylonjs");function Ue(t){if(!isNaN(parseFloat(t))&&isFinite(t))return J.Animation.ANIMATIONTYPE_FLOAT;switch(t?.getClassName?.()){case"Vector2":return J.Animation.ANIMATIONTYPE_VECTOR2;case"Vector3":return J.Animation.ANIMATIONTYPE_VECTOR3;case"Quaternion":return J.Animation.ANIMATIONTYPE_QUATERNION;case"Color3":return J.Animation.ANIMATIONTYPE_COLOR3;case"Color4":return J.Animation.ANIMATIONTYPE_COLOR4;case"Size":return J.Animation.ANIMATIONTYPE_SIZE;case"Matrix":return J.Animation.ANIMATIONTYPE_MATRIX}return null}a(Ue,"getAnimationTypeForObject");var an=require("babylonjs");function Ta(t){return function(e,i){let o=e.constructor;o._NodesFromScene??=[],o._NodesFromScene.push({propertyKey:i,nodeName:t})}}a(Ta,"nodeFromScene");function Aa(t){return function(e,i){let o=e.constructor;o._ComponentsFromScene??=[],o._ComponentsFromScene.push({propertyKey:i,componentConstructor:t})}}a(Aa,"componentFromScene");function Ia(t,e=!1){return function(i,o){let r=i.constructor;r._NodesFromDescendants??=[],r._NodesFromDescendants.push({propertyKey:o,nodeName:t,directDescendantsOnly:e})}}a(Ia,"nodeFromDescendants");function Ma(t){return function(e,i){let o=e.constructor;o._AnimationGroups??=[],o._AnimationGroups.push({animationGroupName:t,propertyKey:i})}}a(Ma,"animationGroupFromScene");function Ra(t){return function(e,i){let o=e.constructor;o._SceneAssets??=[],o._SceneAssets.push({sceneName:t,propertyKey:i})}}a(Ra,"sceneAsset");function Va(t,e){return function(i,o){let r=i.constructor;r._GuiFromAsset??=[],r._GuiFromAsset.push({propertyKey:o,pathInAssets:t,onGuiCreated:e})}}a(Va,"guiFromAsset");function Fa(t){return function(e,i){let o=e.constructor;o._SoundsFromScene??=[],o._SoundsFromScene.push({propertyKey:i,soundName:t})}}a(Fa,"soundFromScene");function Na(t,e=!1){return function(i,o){let r=i.constructor;r._ParticleSystemsFromScene??=[],r._ParticleSystemsFromScene.push({propertyKey:o,particleSystemName:t,directDescendantsOnly:e})}}a(Na,"particleSystemFromScene");function Ga(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"boolean"}})}}a(Ga,"visibleAsBoolean");function Ba(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"string"}})}}a(Ba,"visibleAsString");function za(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"number"}})}}a(za,"visibleAsNumber");function Ha(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"vector2"}})}}a(Ha,"visibleAsVector2");function ka(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"vector3"}})}}a(ka,"visibleAsVector3");function Ua(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"color3"}})}}a(Ua,"visibleAsColor3");function Wa(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"color4"}})}}a(Wa,"visibleAsColor4");function Xa(t,e,i){return function(o,r){let n=o.constructor;n._VisibleInInspector??=[],n._VisibleInInspector.push({label:e,propertyKey:r,configuration:{...i,entityType:t,type:"entity"}})}}a(Xa,"visibleAsEntity");function $a(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"texture"}})}}a($a,"visibleAsTexture");function Ka(t,e){return function(i,o){let r=i.constructor;r._VisibleInInspector??=[],r._VisibleInInspector.push({label:t,propertyKey:o,configuration:{...e,type:"keymap"}})}}a(Ka,"visibleAsKeyMap");function ja(t,e,i){return function(o,r){let n=o.constructor;n._VisibleInInspector??=[],n._VisibleInInspector.push({label:e,propertyKey:r,configuration:{...i,assetType:t,type:"asset"}})}}a(ja,"visibleAsAsset");function Za(t,e){return function(i,o){let r=i.constructor;r._PointerEvents??=[],r._PointerEvents.push({propertyKey:o,options:{mode:"global",...e??{}},eventTypes:Array.isArray(t)?t:[t]})}}a(Za,"onPointerEvent");function Ya(t){return function(e,i){let o=e.constructor;o._KeyboardEvents??=[],o._KeyboardEvents.push({propertyKey:i,eventTypes:Array.isArray(t)?t:[t]})}}a(Ya,"onKeyboardEvent");function qa(t){return function(e,i){let o=e.constructor;o._SpritesFromSpriteManager??=[],o._SpritesFromSpriteManager.push({propertyKey:i,spriteName:t})}}a(qa,"spriteFromSpriteManager");function Qa(t){return function(e,i){let o=e.constructor;o._AnimationsFromSprite??=[],o._AnimationsFromSprite.push({propertyKey:i,animationName:t})}}a(Qa,"animationFromSprite");var St=require("babylonjs");function hv(t,e){let i;return t===St.Animation.ANIMATIONTYPE_FLOAT?i=e.value:i=e.value.clone(),{value:i,frame:e.frame,interpolation:e.interpolation,inTangent:t===St.Animation.ANIMATIONTYPE_FLOAT?e.inTangent:e.inTangent?.clone(),outTangent:t===St.Animation.ANIMATIONTYPE_FLOAT?e.outTangent:e.outTangent?.clone()}}a(hv,"cloneKey");function yt(t,e){let i=e.split("."),o=t;for(let r=0;r<i.length;++r)o=o[i[r]];return o}a(yt,"getPropertyValue");function Xi(t,e,i){let o=null;t.onAnimationGroupPlayObservable.add(()=>{o=e.onAfterAnimationsObservable.add(()=>{i()})}),t.onAnimationGroupPauseObservable.add(()=>{o&&(e.onAfterAnimationsObservable.remove(o),o=null)}),t.onAnimationGroupEndObservable.add(()=>{o&&(e.onAfterAnimationsObservable.remove(o),o=null)})}a(Xi,"registerAfterAnimationCallback");var ee=require("babylonjs"),bt=require("babylonjs"),U=require("babylonjs");function Ja(t,e){return{name:t.name,framesPerSecond:t.framesPerSecond,outputFramesPerSecond:t.outputFramesPerSecond,tracks:t.tracks.map(i=>{let o=null,r=null;if(i.node?(o=Le(i.node,e),o||(o=e.particleSystems?.find(l=>l.id===i.node)??null)):i.defaultRenderingPipeline?o=Ie():i.volumetricLightScattering&&(o=Rt()),i.propertyPath){let l=yt(o,i.propertyPath);r=Ue(l)}let n=null;return i.sound&&(n=Le(i.sound,e)),{node:o,sound:n,propertyPath:i.propertyPath,defaultRenderingPipeline:i.defaultRenderingPipeline,volumetricLightScattering:i.volumetricLightScattering,animationGroupWeight:i.animationGroupWeight,animationGroup:i.animationGroup?e.getAnimationGroupByName(i.animationGroup):null,animationGroups:i.animationGroups,sounds:i.sounds,soundVolume:$i(i.soundVolume??[],ee.Animation.ANIMATIONTYPE_FLOAT),keyFrameEvents:i.keyFrameEvents?.map(l=>{let p={...l};switch(l.data?.type){case"set-enabled":p.data={type:"set-enabled",value:l.data.value,node:Le(l.data.node,e)};break;case"apply-impulse":p.data={type:"apply-impulse",radius:l.data.radius,mesh:e.getMeshById(l.data.mesh),force:U.Vector3.FromArray(l.data.force),contactPoint:U.Vector3.FromArray(l.data.contactPoint)};break}return p}),keyFrameAnimations:o&&r!==null&&$i(i.keyFrameAnimations??[],r)}})}}a(Ja,"parseCinematic");function k(t,e){if(t===null)return null;if(t!==void 0)switch(e){case ee.Animation.ANIMATIONTYPE_FLOAT:return t;case ee.Animation.ANIMATIONTYPE_VECTOR2:return U.Vector2.FromArray(t);case ee.Animation.ANIMATIONTYPE_VECTOR3:return U.Vector3.FromArray(t);case ee.Animation.ANIMATIONTYPE_QUATERNION:return U.Quaternion.FromArray(t);case ee.Animation.ANIMATIONTYPE_COLOR3:return bt.Color3.FromArray(t);case ee.Animation.ANIMATIONTYPE_COLOR4:return bt.Color4.FromArray(t);case ee.Animation.ANIMATIONTYPE_MATRIX:return U.Matrix.FromArray(t)}}a(k,"parseCinematicKeyValue");function $i(t,e){return t?.map(i=>{let o=i.type==="key"?i:null;if(o)return{...o,value:k(o.value,e),inTangent:k(o.inTangent,e),outTangent:k(o.outTangent,e)};let r=i.type==="cut"?i:null;if(r)return{...r,key1:{...r.key1,value:k(r.key1.value,e),inTangent:k(r.key1.inTangent,e),outTangent:k(r.key1.outTangent,e)},key2:{...r.key2,value:k(r.key2.value,e),inTangent:k(r.key2.inTangent,e),outTangent:k(r.key2.outTangent,e)}};throw new Error(`Unknown key frame type: ${i.type}`)})}a($i,"parseKeyFrameAnimations");function sn(t,e){t.onEventObservable.notifyObservers(e.eventName)}a(sn,"handleApplyEvent");function ln(t){t.node?.setEnabled(t.value)}a(ln,"handleSetEnabledEvent");var Ki=require("babylonjs"),cn=Ki.Vector3.Zero();function pn(t,e){let i=e.mesh?[e.mesh]:t.meshes.filter(o=>o.physicsAggregate);e.radius&&(i=i.filter(o=>{let r=o.getBoundingInfo().boundingBox.centerWorld;return Ki.Vector3.Distance(r,e.contactPoint)<=e.radius})),i.forEach(o=>{if(o.physicsAggregate?.body){let r=e.contactPoint.subtract(o.getBoundingInfo().boundingBox.centerWorld);r.multiplyInPlace(e.force),o.physicsAggregate.body.setLinearVelocity(cn),o.physicsAggregate.body.setAngularVelocity(cn),o.physicsAggregate.body.applyImpulse(r.negateInPlace(),e.contactPoint)}})}a(pn,"handleApplyImpulseEvent");var mn=require("babylonjs"),hn=require("babylonjs"),We=class extends hn.AnimationGroup{static{a(this,"Cinematic")}onEventObservable=new mn.Observable;onEvent(e,i){this.onEventObservable.add(o=>{e===o&&i()})}};function ji(t){return t.type==="key"}a(ji,"isCinematicKey");function Oe(t){return t.type==="cut"}a(Oe,"isCinematicKeyCut");function es(t){return t.type==="event"}a(es,"isCinematicKeyEvent");function ts(t){return t.type==="group"}a(ts,"isCinematicGroup");function is(t){return t.type==="sound"}a(is,"isCinematicSound");var O=require("babylonjs"),Ee=require("babylonjs");function os(t,e,i){let o=new We(t.name,e);return t.tracks.forEach(r=>{let n=r.animationGroup;if(n&&r.animationGroups?.length){let d=n.clone(`${n.name}-cinematic-temp`),f=e.animationGroups.indexOf(d);f!==-1&&e.animationGroups.splice(f,1),o.onAnimationEndObservable.add(()=>{n.stop(),d.stop()});let S=r.animationGroups.reduce((_,x)=>Math.min(_,x.frame),Number.MAX_VALUE)??0,g=r.animationGroups.reduce((_,x)=>Math.max(_,x.frame+x.endFrame),0)??0,b={frame:S},L=new O.Animation(d.name,"frame",60,O.Animation.ANIMATIONTYPE_FLOAT,O.Animation.ANIMATIONLOOPMODE_CYCLE,!1);if(L.setKeys([{frame:S,value:0},{frame:g,value:g}]),r.animationGroups.forEach(_=>{L.addEvent(new Ee.AnimationEvent(_.frame,()=>{let x=_.repeatCount??0;if(d.to=_.endFrame,d.speedRatio=_.speed,d.stop(),d.play(x>0),d.from!==_.startFrame&&d.goToFrame(_.startFrame),x){let R=0;d.onAnimationGroupLoopObservable.add(()=>{++R,R>x&&d.stop()})}}))}),o.addTargetedAnimation(L,b),(r.animationGroupWeight?.length??0)>=2&&r.animationGroupWeight.find(x=>Oe(x)?x.key1.value!==1||x.key2.value!==1:x.value!==1)){let x={weight:0},R=new O.Animation(`${d.name}-weights`,"weight",60,O.Animation.ANIMATIONTYPE_FLOAT,O.Animation.ANIMATIONLOOPMODE_CYCLE,!1),G=[];r.animationGroupWeight.forEach(v=>{Oe(v)?(G.push(v.key1),G.push(v.key2)):G.push(v)}),R.setKeys(G),o.addTargetedAnimation(R,x),Xi(o,e,()=>{d.weight=x.weight})}}let l=r.sound;if(!i?.ignoreSounds&&l&&l.sound?.buffer&&r.sounds?.length){let d={dummy:0,volume:0},f=new O.Animation(l.name,"dummy",60,O.Animation.ANIMATIONTYPE_FLOAT,O.Animation.ANIMATIONLOOPMODE_CYCLE,!1),S=0;if(r.sounds?.forEach(g=>{let b=g.endFrame-g.startFrame;S=Math.max(S,g.frame+b),f.addEvent(new Ee.AnimationEvent(g.frame,L=>{let x=(L-g.frame+g.startFrame)/t.framesPerSecond;l.play({startOffset:x})},!1)),f.addEvent(new Ee.AnimationEvent(g.frame+b,()=>{l.stop()}))}),f.setKeys([{frame:0,value:0},{frame:S,value:S}]),o.addTargetedAnimation(f,d),(r.soundVolume?.length??0)>=2){let g=new O.Animation(l.name,"volume",60,O.Animation.ANIMATIONTYPE_FLOAT,O.Animation.ANIMATIONLOOPMODE_CYCLE,!1),b=[];r.soundVolume.forEach(L=>{Oe(L)?(b.push(L.key1),b.push(L.key2)):b.push(L)}),g.setKeys(b),o.addTargetedAnimation(g,d),Xi(o,e,()=>{l.volume=d.volume})}}if(r.keyFrameEvents){let d={dummy:0},f=new O.Animation("events","dummy",60,O.Animation.ANIMATIONTYPE_FLOAT,O.Animation.ANIMATIONLOOPMODE_CYCLE,!1),S=0;r.keyFrameEvents?.forEach(g=>{S=Math.max(S,g.frame),f.addEvent(new Ee.AnimationEvent(g.frame,()=>{switch(g.data?.type){case"event":sn(o,g.data);break;case"set-enabled":ln(g.data);break;case"apply-impulse":pn(e,g.data);break}}))}),f.setKeys([{frame:0,value:0},{frame:S+1,value:S+1}]),o.addTargetedAnimation(f,d)}let p=r.defaultRenderingPipeline?Ie():r.node;if(!p||!r.propertyPath||!r.keyFrameAnimations)return;let s=yt(p,r.propertyPath),c=Ue(s);if(c===null)return;let m=new O.Animation(r.propertyPath,r.propertyPath,60,c,O.Animation.ANIMATIONLOOPMODE_CYCLE,!1),h=[];r.keyFrameAnimations?.forEach(d=>{if(ji(d))return h.push(d);Oe(d)&&(h.push(d.key1),h.push(d.key2),Ze(p)&&r.propertyPath==="position"&&m.addEvent(new Ee.AnimationEvent(d.key1.frame,()=>{let f=Kt();if(!f)return;let S=f.motionStrength;f.motionStrength=0,requestAnimationFrame(()=>{f.motionStrength=S})})))}),m.setKeys(h),o.addTargetedAnimation(m,p)}),o.normalize(),o}a(os,"generateCinematicAnimationGroup");async function Zi(t,e){return new Promise((i,o)=>{let r=indexedDB.open(t,1);r.addEventListener("error",()=>o()),r.addEventListener("blocked",()=>o()),r.addEventListener("upgradeneeded",()=>{try{e(r.result)}catch(n){o(n)}}),r.addEventListener("success",()=>{i(r.result)})})}a(Zi,"openIndexDB");function Xe(t,e,i){return new Promise(o=>{let n=t.transaction(e).objectStore(e).get(i);n.addEventListener("error",()=>{o(null)}),n.addEventListener("success",()=>{o(n.result??null)})})}a(Xe,"getFromIndexDB");async function W(t,e,i){let r=t.transaction(e,"readwrite").objectStore(e).put(i);await new Promise((n,l)=>{r.addEventListener("error",()=>l()),r.addEventListener("success",()=>n())})}a(W,"putInIndexDB");var dn=require("babylonjs");function rs(t){dn.AbstractEngine.OfflineProviderFactory=(e,i,o=!1)=>new $e(t,e,i,o)}a(rs,"setupOfflineProvider");async function Yi(t,e){let i=await new Promise(o=>{let r=new $e(t,e,n=>o(n?r:null),!1)});return await i?.open(),i}a(Yi,"createAndOpenDatabase");var $e=class{static{a(this,"Database")}enableSceneOffline=!0;enableTexturesOffline=!0;name;_database=null;_manifestVersion=null;_loadFilePromises=new Map;constructor(e,i,o,r){this.name=e,r?o(!1):this._checkManifest(i,o)}async _checkManifest(e,i){try{let o=await z(`${e}.manifest?${Date.now()}`);this._manifestVersion=o.version,i(!0)}catch{this.enableSceneOffline=!1,this.enableTexturesOffline=!1,i(!1)}}async open(e,i){try{this._database=await Zi(this.name,o=>{o.createObjectStore("files",{keyPath:"url"}),o.createObjectStore("images",{keyPath:"url"}),o.createObjectStore("versions",{keyPath:"url"})}),e?.()}catch{i?.()}}close(){this._database?.close(),this._database=null,this._loadFilePromises.clear()}async loadImage(e,i){if(!this._database){i.src=e;return}let o=null;await Ei(()=>this._manifestVersion!==null);let r=this._loadFilePromises.get(e);if(r)return r.then(l=>{l!==null?i.src=l:i.src=e});let n=new Promise(async l=>{if(await this._getFileVersionForUrl(e)!==this._manifestVersion?(o=await Ce(e,"blob"),await Promise.all([W(this._database,"images",{url:e,data:o}),W(this._database,"versions",{url:e,version:this._manifestVersion})])):o=(await Xe(this._database,"images",e))?.data??null,o!==null){let s=URL.createObjectURL(o);i.src=s}else i.src=e;l(i.src)});this._loadFilePromises.set(e,n)}async saveImage(e){if(!this._database)throw new Error("Database is not available");let i=await Ce(e,"blob");await Promise.all([W(this._database,"images",{url:e,data:i}),W(this._database,"versions",{url:e,version:this._manifestVersion})])}async isFileMatchingVersion(e){return await this._getFileVersionForUrl(e)===this._manifestVersion}async loadFile(e,i,o,r,n){if(!this._database)return r?.();let l=null;await Ei(()=>this._manifestVersion!==null);let p=this._loadFilePromises.get(e);if(p)return p.then(c=>{c!==null?i(c):r?.()});let s=new Promise(async c=>{await this._getFileVersionForUrl(e)!==this._manifestVersion?(l=await Ce(e,n?"arraybuffer":"text",o),await Promise.all([W(this._database,"files",{url:e,data:l}),W(this._database,"versions",{url:e,version:this._manifestVersion})])):l=(await Xe(this._database,"files",e))?.data??null,l!==null?i(l):r?.(),c(l)});this._loadFilePromises.set(e,s)}async saveFile(e,i,o){if(!this._database)throw new Error("Database is not available");let r=await Ce(e,i?"arraybuffer":"text",o);await Promise.all([W(this._database,"files",{url:e,data:r}),W(this._database,"versions",{url:e,version:this._manifestVersion})])}async _getFileVersionForUrl(e){return(await Xe(this._database,"versions",e))?.version??null}};var fn=["mp3","wav"],un=["babylonbinarymeshdata"],ns=["ktx","ktx2","jpg","jpeg","png","bmp","webp"],gn=["babylon","json"],qi=["jpg","jpeg","png","bmp","webp"],vn=["bin","ktx","ktx2",...un,...fn],as=[...gn,...qi,...vn];async function ss(t,e,i){let o=[],r=await z(`${e}scenes-used-files.json`),n=[];if(i?.scenesFilter){n=i.scenesFilter.map(h=>typeof h=="string"?{sceneName:h,disableSounds:!1,disableTextures:!1,disableGeometries:!1}:h);for(let[h,d]of Object.entries(r))n.find(f=>f.sceneName===h)||delete r[h]}let l=0,p=0,s=i?.engine?.textureFormatInUse?i?.engine?.texturesSupported[0]:null,c=Object.values(r).reduce((h,d)=>h+d.length,0);function m(h){++p,i?.onProgress?.(p/c),h?.()}a(m,"notifyProgress");for(let[h,d]of Object.entries(r)){let f=h.replace(".scene",".babylon"),S=await Yi(t,`${e}${f}`);if(!S)continue;let g=n.find(b=>b.sceneName===h);for(let b=0,L=d.length;b<L;++b){let _=d[b],x=_.split(".").pop()?.toLowerCase();if(!x){m();continue}if(un.includes(x)&&g?.disableGeometries){m();continue}if(ns.includes(x)&&g?.disableTextures){m();continue}if(fn.includes(x)&&g?.disableSounds){m();continue}if(qi.includes(x)&&g?.disableTextures){m();continue}if(x==="ktx")if(s){if(!_.endsWith(s)){m();continue}}else{m();continue}if(x==="ktx2"&&!ke()){m();continue}if(o.length>300){try{await Promise.all(o)}catch{}o.splice(0,o.length)}let R=`${e}${_}`;as.includes(x)&&o.push(new Promise(async G=>{if(await S.isFileMatchingVersion(R))return m(G);try{qi.includes(x)?i?.disableImages||(await S.saveImage(R),++l):vn.includes(x)?(await S.saveFile(R,!0),++l):gn.includes(x)&&(await S.saveFile(R,!1),++l)}catch{}m(G)}))}await Promise.all(o),S.close()}return await Promise.all(o),{loadedCount:l,processedFilesCount:p}}a(ss,"preloadAssetsToDatabase");0&&(module.exports={AdvancedAssetContainer,AdvancedAssetContainerInstantiatedEntries,Cinematic,Database,NodeParticleSystemSet,VolumetricDebugMode,VolumetricDepthSource,VolumetricDitherMode,VolumetricFogMode,VolumetricLightingRenderingPipeline,VolumetricShadowKind,VolumetricShadowMode,VolumetricStepDistribution,VolumetricTransmittanceMode,_applyScriptsForObject,_getKtx2TextureName,_preloadScriptsAssets,_registerScriptInstance,_removeRegisteredScriptInstance,addExcludedCompressedTexture,animationFromSprite,animationGroupFromScene,applyMeshesLODQuality,applyRagdollJointLimits,applyRenderingConfigurationForCamera,applyScriptOnObject,applyShadowsQuality,applyTexturesQuality,canUseHdr,componentFromScene,computeVolumetricBudget,computeVolumetricShapeKey,configureEngineToUseCompressedTextures,configureMeshDistanceOrScreenCoverage,configureShadowMapRefreshRate,configureShadowMapRenderListPredicate,copyAndParseRagdollConfiguration,createAndOpenDatabase,createDefaultRenderingPipeline,createMotionBlurPostProcess,createSSAO2RenderingPipeline,createSSRRenderingPipeline,createTAARenderingPipeline,createVLSPostProcess,createVolumetricLightingPrePassConfiguration,createVolumetricLightingRenderingPipeline,defaultPipelineCameraConfigurations,disposeDefaultRenderingPipeline,disposeMotionBlurPostProcess,disposeSSAO2RenderingPipeline,disposeSSRRenderingPipeline,disposeTAARenderingPipeline,disposeVLSPostProcess,disposeVolumetricLightingRenderingPipeline,ensureVolumetricLightConfiguration,forceCompileAllSceneMaterials,generateCinematicAnimationGroup,getAllScriptsByClassForObject,getAllVolumetricCandidateLights,getAnimationTypeForObject,getDefaultRenderingPipeline,getDefaultVolumetricLightConfiguration,getDefaultVolumetricLightingConfiguration,getFromIndexDB,getHdrTextureType,getMotionBlurPostProcess,getPowerOfTwoUntil,getSSAO2RenderingPipeline,getSSRRenderingPipeline,getScriptByClassForObject,getTAARenderingPipeline,getTextureUrl,getVLSPostProcess,getVolumetricGeometryBufferDepthTexture,getVolumetricGeometryBufferRenderer,getVolumetricLightConfiguration,getVolumetricLightRange,getVolumetricLightSteps,getVolumetricLightWorldDirection,getVolumetricLightWorldPosition,getVolumetricLightingRenderingPipeline,getVolumetricPrePassDepthTexture,getVolumetricPrePassRenderer,guiFromAsset,isAbstractMesh,isAnyParticleSystem,isArcRotateCamera,isBone,isCamera,isCascadedShadowGenerator,isCinematicGroup,isCinematicKey,isCinematicKeyCut,isCinematicKeyEvent,isCinematicSound,isClusteredLightContainer,isDecalMesh,isDirectionalLight,isFreeCamera,isGPUParticleSystem,isGaussianSplattingMesh,isGroundMesh,isHemisphericLight,isInstancedMesh,isLight,isMesh,isNode,isNodeFromStaticGroup,isParticleSystem,isPointLight,isScene,isShadowGenerator,isSoundNode,isSpotLight,isSprite,isTexture,isTransformNode,isUsingKtx2CompressedTextures,isVolumetricLightEnabled,isVolumetricLightSupported,isVolumetricLightingSupported,loadMaterialFromFile,loadScene,markVolumetricLightsDirty,maxVolumetricArrayLights,maxVolumetricDirectionalLights,maxVolumetricShadowSlots,motionBlurPostProcessCameraConfigurations,nodeFromDescendants,nodeFromScene,normalizeAtlasJson,normalizeVolumetricLightConfiguration,normalizeVolumetricLightingConfiguration,onKeyboardEvent,onPointerEvent,openIndexDB,parseCinematic,parseCinematicKeyValue,parseDefaultRenderingPipeline,parseKeyFrameAnimations,parseMotionBlurPostProcess,parseRagdollConfiguration,parseSSAO2RenderingPipeline,parseSSRRenderingPipeline,parseTAARenderingPipeline,parseVLSPostProcess,parseVolumetricLightingRenderingPipeline,particleSystemFromScene,playSpriteAnimationFromName,preloadAssetsToDatabase,putInIndexDB,registerScriptAssetParser,resolveVolumetricDepthSource,resolveVolumetricShadowSlot,saveRenderingConfigurationForCamera,sceneAsset,scriptAssetsCache,scriptAssetsParsers,scriptsDictionary,selectVolumetricLights,serializeDefaultRenderingPipeline,serializeMotionBlurPostProcess,serializeSSAO2RenderingPipeline,serializeSSRRenderingPipeline,serializeTAARenderingPipeline,serializeVLSPostProcess,serializeVolumetricLightingRenderingPipeline,setDefaultRenderingPipelineRef,setMotionBlurPostProcessRef,setSSAO2RenderingPipelineRef,setSSRRenderingPipelineRef,setStaticDecalsEnabled,setTAARenderingPipelineRef,setUseKtx2CompressedTextures,setVLSPostProcessRef,setVolumetricLightingRenderingPipelineRef,setupOfflineProvider,soundFromScene,spriteFromSpriteManager,ssaoRenderingPipelineCameraConfigurations,ssrRenderingPipelineCameraConfigurations,supportsVolumetricFloatDepthTexture,taaRenderingPipelineCameraConfigurations,visibleAsAsset,visibleAsBoolean,visibleAsColor3,visibleAsColor4,visibleAsEntity,visibleAsKeyMap,visibleAsNumber,visibleAsString,visibleAsTexture,visibleAsVector2,visibleAsVector3,vlsPostProcessCameraConfigurations,volumetricLightMetadataKey,volumetricLightingPrePassConfigurationName,volumetricLightingRenderingPipelineCameraConfigurations});