@hology/core 0.0.232 → 0.0.234

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md CHANGED
@@ -1,15 +1,15 @@
1
- # Hology Interactive AB Limited License
2
-
3
- This software package, including all associated files and documentation (the "Software"), is licensed to you (the "Licensee") by Hology Interactive AB for use exclusively with the product "Hology Engine."
4
-
5
- By using, copying, modifying, or distributing the Software, Licensee agrees to be bound by the terms of this license.
6
-
7
- 1. License Grant: Hology Interactive AB grants Licensee a limited, non-exclusive, non-transferable license to use the Software solely for the purpose of developing and running software developed with "Hology Engine."
8
-
9
- 2. Restrictions: Licensee may not use, copy, modify, or distribute the Software for any other purpose, including but not limited to the creation of derivative works, standalone applications, or any products not directly associated with "Hology Engine."
10
-
11
- 3. Ownership: Hology Interactive AB retains all intellectual property rights to the Software. This license does not transfer ownership of the Software to Licensee.
12
-
13
- 4. Warranty Disclaimer: THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE CREATOR OF THIS PACKAGE BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE.
14
-
1
+ # Hology Interactive AB Limited License
2
+
3
+ This software package, including all associated files and documentation (the "Software"), is licensed to you (the "Licensee") by Hology Interactive AB for use exclusively with the product "Hology Engine."
4
+
5
+ By using, copying, modifying, or distributing the Software, Licensee agrees to be bound by the terms of this license.
6
+
7
+ 1. License Grant: Hology Interactive AB grants Licensee a limited, non-exclusive, non-transferable license to use the Software solely for the purpose of developing and running software developed with "Hology Engine."
8
+
9
+ 2. Restrictions: Licensee may not use, copy, modify, or distribute the Software for any other purpose, including but not limited to the creation of derivative works, standalone applications, or any products not directly associated with "Hology Engine."
10
+
11
+ 3. Ownership: Hology Interactive AB retains all intellectual property rights to the Software. This license does not transfer ownership of the Software to Licensee.
12
+
13
+ 4. Warranty Disclaimer: THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE CREATOR OF THIS PACKAGE BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE.
14
+
15
15
  6. Contact: For any inquiries regarding this license, please email hello@hology.app
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # Hology Engine Core
2
-
1
+ # Hology Engine Core
2
+
3
3
  For the development with Hology Engine (https://hology.app/)
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as e}from"tslib";import i from"@dimforge/rapier3d-simd-compat";import{takeUntil as o}from"rxjs";import*as s from"three";import{ArrowHelper as n,MathUtils as r,Quaternion as a,Vector3 as h}from"three";import{RootMotionClip as l}from"../../../../animation/root-motion.js";import{inject as c}from"../../../../inject.js";import{ActionInput as u,AxisInput as d,RotationInput as p}from"../../../../input/index.js";import{NetRole as m}from"../../../../net/service/net-actor-role.js";import{RunOnClient as v,RunOnNotOwner as y,RunOnServer as S}from"../../../../net/service/rpc-decorator.js";import{NetService as g}from"../../../../net/service/net-service.js";import{PhysicsSystem as M,RayTestResult as f}from"../../../../services/physics/physics-system.js";import{CapsuleCollisionShape as x}from"../../../../../scene/collision/collision-shape.js";import{Parameter as T}from"../../../../../shader/parameter.js";import{PhysicsBodyType as C}from"../../../../services/physics/physics-system.js";import{ActorComponent as R,Component as w}from"../../../component.js";import{CharacterMovementMode as A}from"./modes.js";import{DEFAULT_MAX_CLIENT_TIME_AHEAD as q,DEFAULT_LARGE_CORRECTION_THRESHOLD as D,DEFAULT_MAX_COMBINED_MOVE_DELTA_TIME as b,DEFAULT_MAX_MOVE_DELTA_TIME as k,DEFAULT_MAX_MOVES_PER_PACKET as I,DEFAULT_MAX_REPLAYED_MOVES as z,DEFAULT_MAX_SERVER_MOVES_PER_TICK as P,DEFAULT_MAX_SAVED_MOVES as O,DEFAULT_MAX_SERVER_MOVE_DELTA_TIME_SCALAR as j,DEFAULT_MAX_SERVER_MOVE_TIME_BUDGET as G,DEFAULT_MAX_SUBSTEP_DELTA_TIME as Y,DEFAULT_MOVE_SEND_INTERVAL as F,DEFAULT_SIMULATED_INTERPOLATION_DELAY as N,DEFAULT_SIMULATED_STATE_INTERVAL as V,DEFAULT_SMALL_CORRECTION_TOLERANCE as U,DEFAULT_TELEPORT_SNAP_THRESHOLD as X,MOVE_FLAG_CROUCH as E,MOVE_FLAG_JUMP as L,MOVE_FLAG_ROOT_MOTION as B,MOVE_FLAG_SLIDE_START as H,MOVE_FLAG_SPRINT as Z,MOVE_FLAG_SPRINT_START as W,SNAPSHOT_FLAG_CROUCH_SUPPRESSED as $,SNAPSHOT_FLAG_CROUCHING as Q,NetCharacterProxySmoother as J,NetCharacterSavedMoveBuffer as K,accrueNetCharacterServerMoveTime as _,createNetCharacterMovementSnapshot as tt,createNetCharacterServerMoveTimingState as et,consumeNetCharacterServerMoveTime as it,decodeNetCharacterMoveBatch as ot,decodeNetCharacterOwnerAck as st,decodeNetCharacterOwnerCorrection as nt,decodeNetCharacterSimulatedState as rt,encodeNetCharacterMoveBatch as at,encodeNetCharacterOwnerAck as ht,encodeNetCharacterOwnerCorrection as lt,encodeNetCharacterSimulatedState as ct,validateNetCharacterMove as ut}from"./net-character-movement-protocol.js";import{NetMode as dt}from"../../../../net/net-session.js";import{setSlideJumpVelocity as pt,shouldContinueSlide as mt,shouldStartSlide as vt,updateSlideVelocity as yt,updateSlideVelocityFromDisplacement as St}from"./character-slide.js";export*from"./net-character-movement-protocol.js";const gt=131070,Mt=new h(0,1,0),ft=new h,xt=new h,Tt=new h,Ct=new h,Rt=new h,wt=new h,At=new h,qt=new h,Dt=new h,bt=new h,kt=new h,It=new h,zt=new h,Pt=new h,Ot=new h(0,1,0),jt=new h(0,-.05,0),Gt=new h,Yt=new a,Ft=new s.Euler,Nt=new h,Vt=new h,Ut=new h,Xt=new h,Et=new i.CharacterCollision;let Lt=class extends R{get autoStepMinWidth(){return this.cc.autostepMinWidth()}set autoStepMinWidth(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),t,this.cc.autostepIncludesDynamicBodies())}get autoStepDynamicObjects(){return this.cc.autostepIncludesDynamicBodies()}set autoStepDynamicObjects(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),this.cc.autostepMinWidth(),t)}get autoStepMaxHeight(){return this.cc.autostepMaxHeight()}set autoStepMaxHeight(t){this.cc.enableAutostep(t,this.cc.autostepMinWidth(),this.cc.autostepIncludesDynamicBodies())}get snapToGround(){return this.cc.snapToGroundDistance()}set snapToGround(t){this.cc.enableSnapToGround(t)}set offset(t){this.cc.setOffset(t)}get offset(){return this.cc.offset()}set normalNudgeFactor(t){this.cc.setNormalNudgeFactor(t)}get normalNudgeFactor(){return this.cc.normalNudgeFactor()}constructor(){super(),this.isDefaultCharacterMovementComponent=!0,this.directionInput=new d,this.jumpInput=new u,this.sprintInput=new u,this.crouchInput=new u,this.rotationInput=new p,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.maxSpeedCrouch=4,this.slideEnabled=!1,this.slideMinStartSpeed=8,this.slideMinExitSpeed=4,this.slideDeceleration=3,this.slideGravityScale=1,this.slideSteeringRate=2,this.sprintStartBoostSpeed=0,this.sprintStartBoostDamping=6,this.jumpVelocity=7,this.fallingMovementControl=.5,this.fallingReorientation=!1,this.groundAccelerationRate=4,this.gravityOverride=null,this.colliderHeight=2,this.colliderRadius=.5,this.crouchColliderHeight=1,this.crouchColliderRadius=null,this.jumpInAir=!1,this.mass=50,this.allowSliding=!0,this.minSlopeSlideAngle=r.degToRad(70),this.maxSlopeClimbAngle=r.degToRad(70),this.applyImpulsesToDynamicBodies=!0,this.normalizedDirection=!0,this.characterCollision=!1,this.allowRootMotionJumpCancel=!1,this.enabled=!0,this.rotateToMovementDirection=!1,this.smoothRotation=!0,this.rotationSpeed=40,this.maxRotationSpeed=100,this.impulseDamping=2,this.moveSendInterval=F,this.simulatedStateInterval=V,this.maxSavedMoves=O,this.maxReplayedMoves=z,this.maxServerMovesPerTick=P,this.maxMovesPerPacket=I,this.maxMoveDeltaTime=k,this.maxCombinedMoveDeltaTime=b,this.maxServerMoveDeltaTimeScalar=j,this.maxClientTimeAhead=q,this.maxServerMoveTimeBudget=G,this.maxSubstepDeltaTime=Y,this.fallGraceTime=.1,this.correctionToleranceSq=U*U,this.largeCorrectionThreshold=D,this.teleportSnapThreshold=X,this.listenServerSmoothing=!0,this.listenServerSmoothLocationTime=.04,this.listenServerMaxSmoothUpdateDistance=1,this.listenServerNoSmoothUpdateDistance=2.5,this.debugCorrections=!0,this.suppressUncrouchLift=!1,this.velocity=new h,this.visualSmoothingOffset=new h,this.slideDirection=new h,this.slideSurfaceNormal=new h(0,1,0),this.mode=A.walking,this.isSprinting=!1,this.isCrouching=!1,this.isSliding=!1,this.pressedJump=!1,this.rayTestResult=new f,this.groundRayTestOptions={debug:!1,excludeTriggers:!0,excludeActor:void 0,resolveActor:!1},this.physicsSystem=c(M),this.netService=c(g),this.state={sequence:0,position:new h,velocity:new h,yaw:0,lookYaw:0,mode:A.walking,grounded:!1,currentSpeed:0,fallGraceTime:0,prevInputDirection:new h,prevRotateToMovementDirection:!1},this.movementModes=new Map,this.savedMoves=new K(O),this.serverMoveTiming=et(),this.serverMoveQueue=[],this.inputMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.authoritativeMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.movementModeContext={component:this,state:this.state,move:this.inputMoveScratch,deltaTime:0,rotatedDirection:xt,platformVelocity:Ct,outVelocity:Tt,rootMotionActive:!1,startedSprinting:!1},this.proxySmoother=new J(N,X),this.proxySample=tt(),this.pendingSnapshot=tt(),this.impulse=new h,this.prevRootMotionPos=new h,this.rootMotionOptions={},this.resetRootMotion=!1,this.nextMoveSequence=0,this.clientMoveTime=0,this.lastSentClientMoveTime=0,this.moveSendAccumulator=0,this.simulatedStateAccumulator=0,this.proxyTime=0,this.lastServerProcessedSequence=0,this.lastServerReceivedSequence=0,this.lastAutonomousMoveFlags=0,this.previousSprintInput=!1,this.previousCrouchInput=!1,this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.initialized=!1,this.cc=this.physicsSystem.getCharacterController(.1),this.cc.enableSnapToGround(.1),this.cc.enableAutostep(0,.1,!1),this.registerMovementMode(Bt),this.registerMovementMode(Ht),this.registerMovementMode({mode:A.sliding,update:t=>this.updateSlidingMode(t)})}onInit(){this.groundRayTestOptions.excludeActor=this.actor,this.configureCharacterController(),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:C.kinematic,continousCollisionDetection:!1,friction:0,restitution:.5,ignoreForNavMesh:!0}),this.rotationInput.rotation.copy(this.actor.rotation),this.initializeStateFromActor(),this.initialized=!0,this.physicsSystem.beforeStep.pipe(o(this.disposed)).subscribe(t=>this.tick(t))}onLateUpdate(t){this.updateVisualSmoothing(t)}registerMovementMode(t){this.movementModes.set(t.mode,t)}applyImpulse(t){this.impulse.add(t)}getEffectiveGravity(){return this.gravityOverride??this.physicsSystem.getGravity().y}get isGrounded(){return this.rayTestResult.hasHit||this.cc.computedGrounded()}setRootMotionAction(t,e={}){const i=t?.getClip();if(i instanceof l){this.rootMotionAction=t,this.rootMotionOptions=e,this.resetRootMotion=!0;const o=[];this.rootMotionInterpolant=i.motionTrack.InterpolantFactoryMethodSmooth(o);const n=s.PropertyBinding.parseTrackName(i.motionTrack.name);this.rootMotionRootBone=this.actor.object.getObjectByName(n.nodeName)}}serverMove(t){const e=ot(t);if(e.ok)for(const t of e.value.moves)ut(t,this.lastServerReceivedSequence,this.maxMoveDeltaTime)&&(this.lastServerReceivedSequence=t.sequence,this.serverMoveQueue.push(t))}clientMoveAck(t){const e=st(t);e.ok&&this.actor.netRole===m.autonomousProxy&&(this.savedMoves.ack(e.value.sequence),this.sprintPolicy?.ack?.(e.value.sequence,!1))}clientMoveCorrection(t){const e=nt(t);e.ok&&this.actor.netRole===m.autonomousProxy&&(this.debugCorrections&&(null==this.correctionDebug&&(this.correctionDebug=new Qt(Kt(this.actor.object))),this.correctionDebug.update(this.state.position,e.value.snapshot)),this.applyCorrection(e.value.snapshot))}simulatedState(t){const e=rt(t);e.ok&&this.actor.netRole===m.simulatedProxy&&this.proxySmoother.push(e.value,this.proxyTime)}tick(t){if(!this.initialized)return;t=Math.min(.1,t);const e=this.actor.netRole,i=this.netService.mode;e!==m.simulatedProxy?this.enabled&&(e!==m.autonomousProxy?this.isRemoteControlledAuthority(i,e)?this.tickRemoteAuthority(t):this.tickAuthority(t,i):this.tickAutonomousProxy(t)):this.tickSimulatedProxy(t)}tickAutonomousProxy(t){const e=this.state.mode,i=this.lastAutonomousMoveFlags,o=this.createMoveFromInput(t,++this.nextMoveSequence,{quantizeClientTime:!0});this.performMove(o,_t),this.resetToggleCrouchAfterSlide(e);const s=this.state.mode!==e||o.flags!==i;this.lastAutonomousMoveFlags=o.flags,this.savedMoves.capacity=this.maxSavedMoves,this.savedMoves.maxCombinedDeltaTime=Math.min(this.maxCombinedMoveDeltaTime,this.maxMoveDeltaTime),this.savedMoves.push(o),this.sendSavedMoves(t,s)}tickAuthority(t,e){const i=this.state.mode,o=this.createMoveFromInput(t,++this.nextMoveSequence);this.performMove(o,_t),this.resetToggleCrouchAfterSlide(i),e!==dt.none&&this.sendSimulatedState(t,!1)}resetToggleCrouchAfterSlide(t){t===A.sliding&&this.state.mode!==A.sliding&&"toggle"===this.crouchInput.mode&&this.crouchInput.activated&&this.crouchInput.setActivated(!1)}tickRemoteAuthority(t){_(this.serverMoveTiming,t,this.maxServerMoveTimeBudget);let e=!1;const i=Number.isFinite(this.maxServerMovesPerTick)?Math.max(1,Math.floor(this.maxServerMovesPerTick)):this.serverMoveQueue.length,o=Math.min(this.serverMoveQueue.length,i),s=Ut.copy(this.actor.position);let n=!1;for(let t=0;t<o;t++){const t=this.serverMoveQueue.shift();if(null==t)break;if(!ut(t,this.lastServerProcessedSequence,this.maxMoveDeltaTime)){console.log("Net: Invalid move",t),this.sendOwnerCorrection(!0),e=!0;continue}const i=it(this.serverMoveTiming,t,{maxMoveDeltaTime:this.maxMoveDeltaTime,maxServerMoveDeltaTimeScalar:this.maxServerMoveDeltaTimeScalar,maxClientTimeAhead:this.maxClientTimeAhead});if(i<0){this.sendOwnerCorrection(!0),e=!0;continue}const o=Wt(t,this.authoritativeMoveScratch);o.dt=i,o.rootMotionX=0,o.rootMotionY=0,o.rootMotionZ=0,o.flags&=~B,this.performMove(o,{immediate:!0,savedRootMotion:!1}),n=!0,this.lastServerProcessedSequence=o.sequence;const s=$t(this.state,t);if(s>this.correctionToleranceSq){console.log(`Net server: Correction error: ${Math.sqrt(s)}`);const o=this.state.position.x-t.clientX,n=this.state.position.y-t.clientY,r=this.state.position.z-t.clientZ;console.log(`diff x: ${o}, y: ${n}, z: ${r}`),console.log({sequence:t.sequence,moveDt:t.dt,serverMoveDeltaTime:i,flags:t.flags,mode:this.state.mode,grounded:this.state.grounded,fallGraceTime:this.state.fallGraceTime}),this.sendOwnerCorrection(s>this.largeCorrectionThreshold*this.largeCorrectionThreshold),e=!0}}0===this.lastServerProcessedSequence||e||(this.sprintPolicy?.ack?.(this.lastServerProcessedSequence,!1),this.clientMoveAck(ht(this.lastServerProcessedSequence))),n&&this.accumulateListenServerVisualSmoothing(s,this.actor.position),this.sendSimulatedState(t,!1)}tickSimulatedProxy(t){this.proxyTime+=t,this.proxySmoother.sample(this.proxyTime,this.proxySample)&&this.applySnapshot(this.proxySample,!0)}accumulateListenServerVisualSmoothing(t,e){if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);Xt.subVectors(t,e);const i=Xt.lengthSq();i>1e-8&&(i>this.listenServerNoSmoothUpdateDistance*this.listenServerNoSmoothUpdateDistance?this.visualSmoothingOffset.set(0,0,0):(i>this.listenServerMaxSmoothUpdateDistance*this.listenServerMaxSmoothUpdateDistance&&Xt.setLength(this.listenServerMaxSmoothUpdateDistance),this.visualSmoothingOffset.add(Xt)))}updateVisualSmoothing(t){if(this.visualSmoothingOffset.lengthSq()<=1e-8)return void this.visualSmoothingOffset.set(0,0,0);if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);const e=Math.max(.001,this.listenServerSmoothLocationTime);t<e?this.visualSmoothingOffset.multiplyScalar(1-t/e):this.visualSmoothingOffset.set(0,0,0),this.visualSmoothingOffset.lengthSq()<=1e-4&&this.visualSmoothingOffset.set(0,0,0)}shouldSmoothListenServerRemoteAuthority(){return this.listenServerSmoothing&&this.actor.netRole===m.authority&&this.netService.isServer&&!this.netService.isDedicatedServer&&this.isRemoteControlledAuthority()}createMoveFromInput(t,e,i={}){const o=r.clamp(t,.001,this.maxMoveDeltaTime);this.clientMoveTime+=o;let s=this.clientMoveTime,n=o;!0===i.quantizeClientTime&&(s=Math.max(this.lastSentClientMoveTime+.001,Math.round(1e3*this.clientMoveTime)/1e3),n=r.clamp(s-this.lastSentClientMoveTime,.001,this.maxMoveDeltaTime),this.lastSentClientMoveTime=s),this.sampleRootMotion(At);const a=this.crouchInput.activated,h=a&&!this.previousCrouchInput;this.previousCrouchInput=a;const l=!a&&this.sprintInput.activated,c=l&&!this.previousSprintInput;this.previousSprintInput=l;const u=(this.jumpInput.activated?L:0)|(l?Z:0)|(a?E:0)|(h&&this.slideEnabled?H:0)|(c?W:0)|(At.lengthSq()>0?B:0),d=function(t,e){e.set(t.x,0,t.y),e.lengthSq()>1&&e.normalize();return e}(this.directionInput.vector,Nt),p=this.inputMoveScratch;return p.sequence=e>>>0,p.clientTime=s,p.dt=n,p.inputX=d.x,p.inputY=d.z,p.yaw=this.rotationInput.rotation.y,p.flags=u,p.clientX=this.state.position.x,p.clientY=this.state.position.y,p.clientZ=this.state.position.z,p.rootMotionX=At.x,p.rootMotionY=At.y,p.rootMotionZ=At.z,p}performMove(t,e){const i=r.clamp(t.dt,.001,this.maxMoveDeltaTime),o=Math.max(1,Math.ceil(i/this.maxSubstepDeltaTime)),s=0!==(t.flags&Z)&&0===(t.flags&E);this.sprintPolicy?.update?.(i,t.sequence,s),It.set(e.savedRootMotion?t.rootMotionX:0,e.savedRootMotion?t.rootMotionY:0,e.savedRootMotion?t.rootMotionZ:0),e.savedRootMotion||this.sampleRootMotion(It);let n=i;const a=i/o;for(let s=0;s<o;s++){const o=i>0?a/i:1;this.performSubstep(t,Math.min(a,n),It,o,e.immediate,0===s),n-=a}t.clientX=this.state.position.x,t.clientY=this.state.position.y,t.clientZ=this.state.position.z,t.flags=It.lengthSq()>0?t.flags|B:t.flags&~B,this.state.sequence=t.sequence,this.syncPublicState()}performSubstep(t,e,i,o,s,n){if(e<.001)return;this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded;const r=null!=this.rootMotionAction&&this.rootMotionAction.enabled,a=i.lengthSq()>0,h=!r&&0!==(t.flags&L),l=r||a;this.updateCrouchState(t,n,l,h),this.pressedJump=h,this.isSprinting=!1,this.updateRotation(t,e,r,a),this.resolvePlatformVelocity(Ct);const c=this.movementModeContext,u=this.movementModes.get(this.state.mode);if(null!=u){c.move=t,c.deltaTime=e,c.rootMotionActive=l,c.startedSprinting=n&&!l&&0===(t.flags&E)&&0!==(t.flags&W);const i=u.update(c);"number"==typeof i&&(this.state.mode=i)}else Tt.set(0,0,0);if(a){qt.copy(i).multiplyScalar(o).applyQuaternion(this.actor.quaternion),Dt.copy(qt).divideScalar(e),this.state.mode===A.walking?(Tt.x=Dt.x+Ct.x,Tt.z=Dt.z+Ct.z):(Tt.x=Dt.x,Tt.z=Dt.z);const t=Math.sqrt(Dt.x*Dt.x+Dt.z*Dt.z);t>.4&&(this.state.currentSpeed=t)}if(this.applyImpulseToVelocity(Tt,e),h&&this.isSprinting){const t=Math.max(0,this.maxSpeedSprint),e=Zt(Tt);if(e>t){const i=t/e;Tt.x*=i,Tt.z*=i,this.state.velocity.x*=i,this.state.velocity.z*=i}}this.state.mode===A.walking&&this.state.velocity.copy(Tt),this.applyMovement(Tt,e,s),this.state.mode===A.sliding&&(St(this.state.velocity,wt,Ct,this.slideSurfaceNormal,e),this.state.currentSpeed=Zt(this.state.velocity)),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.updateModeAfterMove(Tt,e),this.state.mode===A.sliding&&this.state.velocity.length()<Math.max(0,this.slideMinExitSpeed)&&(this.state.mode=A.walking)}updateRotation(t,e,i,o){ft.set(-t.inputX,0,t.inputY),ft.lengthSq()>1&&ft.normalize();const s=this.state.prevRotateToMovementDirection!==this.rotateToMovementDirection;let n=r.euclideanModulo(t.yaw-this.state.lookYaw+Math.PI,2*Math.PI)-Math.PI;if(s&&(this.actor.object.quaternion.setFromEuler(Ft.set(0,t.yaw,0)),this.state.prevRotateToMovementDirection||(n=0,this.state.lookYaw=t.yaw),this.state.prevRotateToMovementDirection=this.rotateToMovementDirection),xt.set(0,0,0),i)this.state.lookYaw=t.yaw;else if(this.rotateToMovementDirection){if(ft.lengthSq()>0&&this.state.mode!==A.falling){const i=Ft.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,o=Math.atan2(ft.x,ft.z),s=.99*t.yaw+o;if(this.smoothRotation){const t=r.euclideanModulo(s-i+Math.PI,2*Math.PI)-Math.PI;let o=r.clamp(t*this.rotationSpeed*e,-this.maxRotationSpeed*e,this.maxRotationSpeed*e);Math.abs(o)>Math.abs(t)&&(o=t),this.actor.object.quaternion.setFromEuler(Ft.set(0,i+o,0))}else this.actor.object.quaternion.setFromEuler(Ft.set(0,s,0));this.state.prevInputDirection.lerp(ft,e*this.rotationSpeed),this.state.lookYaw+=n,xt.copy(this.actor.object.getWorldDirection(Nt).normalize())}}else o||(this.state.lookYaw+=n,this.actor.object.quaternion.multiply(Yt.setFromEuler(Ft.set(0,n,0))),ft.lengthSq()>0&&xt.copy(ft).applyQuaternion(this.actor.object.quaternion).normalize())}applyMovement(t,e,i){if(t.lengthSq()>0||!this.state.grounded){if(Rt.copy(t).multiplyScalar(e),this.state.grounded&&((o=this.state.mode)===A.walking||o===A.sliding)&&(this.state.mode===A.walking&&this.rayTestResult.distance<=this.cc.offset()&&(Rt.y=Math.max(0,Ct.y*e)),this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Rt,this.getCollisionGroup()),this.cc.computedCollision(0,Et),null!=Et.normal1)){const t=Nt.copy(Et.normal1);Math.acos(r.clamp(t.dot(Mt),-1,1))>this.cc.maxSlopeClimbAngle()&&(Rt.y=.016*this.getEffectiveGravity()*.5)}wt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Rt,this.getCollisionGroup()))}else wt.set(0,0,0);var o;this.suppressUncrouchLift&&(this.suppressUncrouchLift=!1,this.state.grounded&&this.state.mode===A.walking&&Rt.y<=1e-6&&wt.y>0&&(wt.y=0)),this.state.position.add(wt),i?(this.actor.position.copy(this.state.position),this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()):this.physicsSystem.setNextKinematicPosition(this.actor,this.state.position)}updateModeAfterMove(t,e){const i=function(t){if(0===t.numComputedCollisions())return!1;const e=t.computedCollision(0);Gt.set(e.normal2.x,e.normal2.y,e.normal2.z);const i=Gt.angleTo(Mt);Gt.set(e.normal1.x,e.normal1.y,e.normal1.z);const o=Gt.angleTo(Mt);if(i<100)return!1;return o>t.minSlopeSlideAngle()}(this.cc);!this.state.grounded||i?this.state.mode!==A.falling&&(this.state.fallGraceTime+=e,this.state.fallGraceTime>this.fallGraceTime+1e-6&&(this.state.mode=A.falling,this.state.velocity.copy(t))):this.state.velocity.y<=0&&(this.state.mode===A.falling&&(this.state.mode=A.walking),this.state.mode!==A.sliding&&(this.state.velocity.y=0),this.state.fallGraceTime=0)}applyImpulseToVelocity(t,e){if(this.impulse.lengthSq()<=.1)return void this.impulse.set(0,0,0);const i=Math.min(1,this.impulse.length()/5);t.x=r.lerp(t.x,this.impulse.x,i),t.z=r.lerp(t.z,this.impulse.z,i),t.y+=this.impulse.y;const o=Math.exp(-this.impulseDamping*e);this.impulse.x*=o,this.impulse.y>0?this.impulse.y+=e*this.getEffectiveGravity():this.impulse.y*=o,this.impulse.z*=o}sendSavedMoves(t,e=!1){if(this.moveSendAccumulator+=t,!e&&this.moveSendAccumulator<this.moveSendInterval)return;this.moveSendAccumulator=0;const i=this.savedMoves.getMovesForSend(this.maxMovesPerPacket);0!==i.length&&this.serverMove(at(i))}sendOwnerCorrection(t){const e=this.toSnapshot(this.pendingSnapshot);t&&(e.horizontalSpeed=this.horizontalSpeed),this.sprintPolicy?.ack?.(e.sequence,!0),this.clientMoveCorrection(lt(e))}sendSimulatedState(t,e){this.simulatedStateAccumulator+=t,!e&&this.simulatedStateAccumulator<this.simulatedStateInterval||(this.simulatedStateAccumulator=0,this.simulatedState(ct(this.toSnapshot(this.pendingSnapshot))))}applyCorrection(t){this.sprintPolicy?.restore?.(t.sequence),this.savedMoves.ack(t.sequence),this.sprintPolicy?.ack?.(t.sequence,!0),this.applySnapshot(t,!0),this.savedMoves.replayAfter(t.sequence,t=>(this.performMove(t,{immediate:!0,savedRootMotion:!0}),null),this.maxReplayedMoves)}applySnapshot(t,e){this.state.sequence=t.sequence,this.state.position.set(t.x,t.y,t.z),this.state.velocity.set(t.velocityX,t.velocityY,t.velocityZ),this.state.yaw=t.yaw,this.state.lookYaw=t.yaw,this.state.mode=t.mode,this.state.currentSpeed=t.horizontalSpeed,this.state.fallGraceTime=0,this.actor.position.copy(this.state.position),this.actor.object.quaternion.setFromEuler(Ft.set(0,t.yaw,0)),this.crouchSuppressedUntilRelease=0!==(t.flags&$),this.setCrouching(0!==(t.flags&Q)||t.mode===A.sliding),e&&(this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.syncPublicState()}toSnapshot(t){return t.sequence=this.state.sequence,t.x=this.state.position.x,t.y=this.state.position.y,t.z=this.state.position.z,t.velocityX=this.state.velocity.x,t.velocityY=this.state.velocity.y,t.velocityZ=this.state.velocity.z,t.yaw=Ft.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,t.mode=this.state.mode,t.flags=(this.isCrouching?Q:0)|(this.crouchSuppressedUntilRelease?$:0),t.horizontalSpeed=this.state.currentSpeed,t}syncPublicState(){this.velocity.copy(this.state.velocity),this.mode=this.state.mode,this.horizontalSpeed=this.state.currentSpeed,this.isSliding=this.state.mode===A.sliding,this.isSliding?(this.resolveGroundNormal(this.slideSurfaceNormal),this.slideDirection.copy(this.state.velocity).projectOnPlane(this.slideSurfaceNormal),this.slideDirection.lengthSq()>1e-8?this.slideDirection.normalize():this.slideDirection.set(0,0,0)):(this.slideDirection.set(0,0,0),this.slideSurfaceNormal.copy(Mt))}sampleRootMotion(t){if(t.set(0,0,0),null==this.rootMotionAction||this.rootMotionAction.isRunning()||this.clearRootMotionAction(this.rootMotionAction),null!=this.rootMotionAction&&this.rootMotionOptions.cancelWithJump&&this.jumpInput.activated&&(this.isGrounded||this.jumpInAir)){const e=this.rootMotionAction,i=this.rootMotionOptions.onJumpCancel;return this.clearRootMotionAction(e),e.stop(),i?.(),t}if(null==this.rootMotionAction)return t;if(!(this.rootMotionAction.getClip()instanceof l))return t;const e=this.rootMotionInterpolant;this.resetRootMotion&&(this.prevRootMotionPos.fromArray(e.evaluate(0)),this.resetRootMotion=!1),kt.fromArray(e.evaluate(this.rootMotionAction.time)),t.subVectors(kt,this.prevRootMotionPos),this.prevRootMotionPos.copy(kt);return(this.rootMotionRootBone??this.rootMotionAction.getRoot()).getWorldScale(bt),t.multiply(bt),t}clearRootMotionAction(t){null!=t&&this.rootMotionAction!==t||(this.rootMotionAction=null,this.rootMotionOptions={},this.resetRootMotion=!1)}isRemoteControlledAuthority(t=this.netService.mode,e=this.actor.netRole){if(t===dt.none||e!==m.authority||t>=dt.client)return!1;return null!=this.netService.resolveActorConnection(this.actor)&&!this.netService.isLocalOwner(this.actor)}configureCharacterController(){const t=this.cc;t.setApplyImpulsesToDynamicBodies(this.applyImpulsesToDynamicBodies),t.setMinSlopeSlideAngle(this.minSlopeSlideAngle),t.setMaxSlopeClimbAngle(this.maxSlopeClimbAngle),t.setCharacterMass(this.mass),t.setSlideEnabled(this.allowSliding)}initializeStateFromActor(){this.state.position.copy(this.actor.position),this.state.velocity.set(0,0,0),this.state.yaw=this.actor.rotation.y,this.state.lookYaw=this.rotationInput.rotation.y,this.state.mode=this.mode,this.state.currentSpeed=this.horizontalSpeed,this.state.prevRotateToMovementDirection=this.rotateToMovementDirection}createCollisionShape(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1),i=new x(t,e);return i.offset.y=this.getCapsuleOffsetY(t,e),i.collisionGroup=gt,i}updateCrouchState(t,e,i,o){if(!(0!==(t.flags&E)))return this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.state.mode===A.sliding&&(this.state.mode=A.walking),void this.tryUncrouch();if(this.state.mode===A.sliding&&(!this.slideEnabled||i))return this.slideOnLandingRequested=!1,this.state.mode=A.walking,void(this.crouchSuppressedUntilRelease||this.setCrouching(!0));if(this.state.mode===A.sliding&&o)return this.crouchSuppressedUntilRelease=!0,this.slideOnLandingRequested=!1,void this.tryUncrouch();if(this.crouchSuppressedUntilRelease)return void(this.slideOnLandingRequested=!1);if(this.setCrouching(!0),!this.slideEnabled||i)return void(this.slideOnLandingRequested=!1);if(this.state.mode===A.falling)return void(this.slideOnLandingRequested=!0);this.resolveGroundNormal(Vt);const s=this.slideOnLandingRequested&&this.state.mode===A.walking&&this.state.grounded,n=e&&0!==(t.flags&H)||s;s&&(this.slideOnLandingRequested=!1);const r=Zt(this.state.velocity);this.state.mode===A.walking&&vt(this.slideEnabled,n,this.state.grounded,this.isWalkableSlideSurface(Vt),i,r,this.slideMinStartSpeed)&&(this.state.mode=A.sliding,this.slideSurfaceNormal.copy(Vt),this.state.velocity.projectOnPlane(this.slideSurfaceNormal),this.state.currentSpeed=Zt(this.state.velocity))}updateSlidingMode(t){const e=t.state,i=t.move;this.resolveGroundNormal(this.slideSurfaceNormal);const o=this.isWalkableSlideSurface(this.slideSurfaceNormal),s=e.velocity.length();if(!e.grounded||!o)return e.mode=A.falling,Ht.update(t),A.falling;if(this.slideEnabled&&0!==(i.flags&E)&&!t.rootMotionActive&&0!==(i.flags&L))return pt(t.outVelocity,e.velocity,this.jumpVelocity),e.velocity.copy(t.outVelocity),e.currentSpeed=Zt(e.velocity),A.falling;if(!mt(this.slideEnabled,0!==(i.flags&E),e.grounded,o,t.rootMotionActive,s,this.slideMinExitSpeed))return e.mode=A.walking,Bt.update(t),A.walking;const n=yt(e.velocity,e.velocity,this.slideSurfaceNormal,t.rotatedDirection,this.getEffectiveGravity(),t.deltaTime,this.slideDeceleration,this.slideGravityScale,this.slideSteeringRate);if(e.currentSpeed=Zt(e.velocity),n<Math.max(0,this.slideMinExitSpeed))return e.mode=A.walking,Bt.update(t),A.walking;t.outVelocity.copy(e.velocity).add(t.platformVelocity)}tryUncrouch(){this.isCrouching&&this.canUncrouch()&&this.setCrouching(!1)&&(this.suppressUncrouchLift=!0,this.state.fallGraceTime=0)}resolveGroundNormal(t){return!this.rayTestResult.hasHit||this.rayTestResult.hitNormal.lengthSq()<=1e-8?t.copy(Mt):(t.copy(this.rayTestResult.hitNormal).normalize(),t.dot(Mt)<0&&t.multiplyScalar(-1),t)}isWalkableSlideSurface(t){return t.dot(Mt)>=Math.cos(this.cc.maxSlopeClimbAngle())}setCrouching(t){return this.isCrouching!==t&&(this.isCrouching=t,this.syncColliderShape(),!0)}canUncrouch(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1);return!this.physicsSystem.hasActorCapsuleIntersection(this.actor,this.state.position,t,e,this.getCapsuleOffsetY(t,e),this.getCollisionGroup())}syncColliderShape(){const t=this.getColliderHeight(this.isCrouching),e=this.getColliderRadius(this.isCrouching);this.physicsSystem.setActorCapsuleCollider(this.actor,t,e,this.getCapsuleOffsetY(t,e))}getColliderHeight(t){const e=Number.isFinite(this.colliderHeight)?Math.max(0,this.colliderHeight):0;if(!t)return e;const i=Number.isFinite(this.crouchColliderHeight)?this.crouchColliderHeight:e;return r.clamp(i,0,e)}getColliderRadius(t){const e=Number.isFinite(this.colliderRadius)?Math.max(.001,this.colliderRadius):.001;if(!t)return e;const i=this.crouchColliderRadius??e,o=Number.isFinite(i)?i:e;return r.clamp(o,.001,e)}getCapsuleOffsetY(t,e){return e+t/2+this.offset}checkGrounded(t){jt.y=-Math.max(.05,this.cc.snapToGroundDistance()),this.physicsSystem.rayTest(zt.addVectors(t,Ot.set(0,this.offset,0)),Pt.addVectors(t,jt),this.rayTestResult,this.groundRayTestOptions)}resolvePlatformVelocity(t){return t.set(0,0,0),this.rayTestResult.hasHit&&null!=this.rayTestResult.actor&&this.physicsSystem.getLinearVelocity(this.rayTestResult.actor,t),t}getCollisionGroup(){return this.characterCollision?null:gt}};t([T(),e("design:type",Object)],Lt.prototype,"colliderHeight",void 0),t([T(),e("design:type",Object)],Lt.prototype,"colliderRadius",void 0),t([T(),e("design:type",Object)],Lt.prototype,"crouchColliderHeight",void 0),t([T(),e("design:type",Number)],Lt.prototype,"crouchColliderRadius",void 0),t([S(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"serverMove",null),t([v(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"clientMoveAck",null),t([v(!0),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"clientMoveCorrection",null),t([y(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"simulatedState",null),Lt=t([w({inEditor:!1}),e("design:paramtypes",[])],Lt);export{Lt as CharacterMovementComponent};const Bt={mode:A.walking,update(t){const e=t.component,i=t.move,o=t.state,s=t.rotatedDirection,n=Math.min(1,Math.sqrt(i.inputX*i.inputX+i.inputY*i.inputY)),r=!e.rotateToMovementDirection&&i.inputY<0,a=e.isCrouching,h=!t.rootMotionActive&&!a&&0===(i.flags&E)&&0!==(i.flags&Z)&&!r&&0!==s.lengthSq()&&(e.sprintPolicy?.canSprint()??!0),l=(a?e.maxSpeedCrouch:r?e.maxSpeedBackwards:h?e.maxSpeedSprint:e.maxSpeed)*(e.normalizedDirection?1:n);if(0!==s.lengthSq()){e.isSprinting=h,h&&e.sprintPolicy?.commitSprint(t.deltaTime,i.sequence);let a=Math.min(l,o.currentSpeed),c=e.groundAccelerationRate;if(h&&t.startedSprinting&&e.sprintStartBoostSpeed>0){const t=e.normalizedDirection?1:n;a=Math.max(a,l+e.sprintStartBoostSpeed*t),c=e.sprintStartBoostDamping}else h&&!r&&e.sprintStartBoostSpeed>0&&o.currentSpeed>l&&(a=o.currentSpeed,c=e.sprintStartBoostDamping);o.currentSpeed=function(t,e,i,o){return e+(t-e)*Math.exp(-i*o)}(a,l,c,t.deltaTime),t.outVelocity.copy(s).multiplyScalar(function(t,e,i,o){const s=i*o;if(s<=1e-6)return t;return e+(t-e)*(1-Math.exp(-s))/s}(a,l,c,t.deltaTime))}else o.currentSpeed=0,t.outVelocity.set(0,0,0);if(0!==(i.flags&L))return o.mode=A.falling,o.velocity.copy(t.outVelocity),o.velocity.y=e.jumpVelocity,A.falling;t.outVelocity.y=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.add(t.platformVelocity)}},Ht={mode:A.falling,update(t){const e=t.component,i=t.state,o=t.move;0!==(o.flags&L)&&e.jumpInAir&&(i.velocity.copy(t.outVelocity),i.velocity.y=e.jumpVelocity),i.velocity.y+=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.copy(i.velocity),t.outVelocity.addScaledVector(t.rotatedDirection,e.fallingMovementControl),e.fallingReorientation&&t.outVelocity.applyAxisAngle(Mt,r.euclideanModulo(o.yaw-i.lookYaw+Math.PI,2*Math.PI)-Math.PI)}};function Zt(t){return Math.sqrt(t.x*t.x+t.z*t.z)}function Wt(t,e){return e.sequence=t.sequence,e.clientTime=t.clientTime,e.dt=t.dt,e.inputX=t.inputX,e.inputY=t.inputY,e.yaw=t.yaw,e.flags=t.flags,e.clientX=t.clientX,e.clientY=t.clientY,e.clientZ=t.clientZ,e.rootMotionX=t.rootMotionX,e.rootMotionY=t.rootMotionY,e.rootMotionZ=t.rootMotionZ,e}function $t(t,e){const i=t.position.x-e.clientX,o=t.position.y-e.clientY,s=t.position.z-e.clientZ;return i*i+o*o+s*s}class Qt{constructor(t){this.scene=t,this.serverPosition=new h,this.direction=new h}update(t,e){const i=this.serverPosition.set(e.x,e.y,e.z),o=i.distanceTo(t);o>.1&&console.log(`Correction applied. Error: ${o.toFixed(3)}. Server position: (${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z.toFixed(2)}), Client position: (${t.x.toFixed(2)}, ${t.y.toFixed(2)}, ${t.z.toFixed(2)})`);const s=this.direction.copy(i).sub(t).normalize();Jt.position.copy(t),Jt.setDirection(s),Jt.setLength(o);const n=Kt(this.scene);n.add(Jt),setTimeout(()=>{n.remove(Jt)},1e3)}}const Jt=new n(new h(0,1,0),new h,1,16711680);function Kt(t){return null==t.parent?t:Kt(t.parent)}const _t={immediate:!1,savedRootMotion:!0};/*
1
+ import{__decorate as t,__metadata as e}from"tslib";import i from"@dimforge/rapier3d-simd-compat";import{takeUntil as o}from"rxjs";import*as s from"three";import{ArrowHelper as n,MathUtils as r,Quaternion as a,Vector3 as h}from"three";import{RootMotionClip as l}from"../../../../animation/root-motion.js";import{inject as c}from"../../../../inject.js";import{ActionInput as u,AxisInput as d,RotationInput as p}from"../../../../input/index.js";import{NetRole as m}from"../../../../net/service/net-actor-role.js";import{RunOnClient as v,RunOnNotOwner as y,RunOnServer as S}from"../../../../net/service/rpc-decorator.js";import{NetService as g}from"../../../../net/service/net-service.js";import{PhysicsSystem as M,RayTestResult as f}from"../../../../services/physics/physics-system.js";import{CapsuleCollisionShape as x}from"../../../../../scene/collision/collision-shape.js";import{Parameter as T}from"../../../../../shader/parameter.js";import{PhysicsBodyType as C}from"../../../../services/physics/physics-system.js";import{ActorComponent as R,Component as w}from"../../../component.js";import{CharacterMovementMode as A}from"./modes.js";import{DEFAULT_MAX_CLIENT_TIME_AHEAD as q,DEFAULT_LARGE_CORRECTION_THRESHOLD as D,DEFAULT_MAX_COMBINED_MOVE_DELTA_TIME as b,DEFAULT_MAX_MOVE_DELTA_TIME as k,DEFAULT_MAX_MOVES_PER_PACKET as I,DEFAULT_MAX_REPLAYED_MOVES as z,DEFAULT_MAX_SERVER_MOVES_PER_TICK as P,DEFAULT_MAX_SAVED_MOVES as O,DEFAULT_MAX_SERVER_MOVE_DELTA_TIME_SCALAR as j,DEFAULT_MAX_SERVER_MOVE_TIME_BUDGET as G,DEFAULT_MAX_SUBSTEP_DELTA_TIME as Y,DEFAULT_MOVE_SEND_INTERVAL as N,DEFAULT_SIMULATED_INTERPOLATION_DELAY as F,DEFAULT_SIMULATED_STATE_INTERVAL as V,DEFAULT_SMALL_CORRECTION_TOLERANCE as U,DEFAULT_TELEPORT_SNAP_THRESHOLD as X,MOVE_FLAG_CROUCH as E,MOVE_FLAG_JUMP as L,MOVE_FLAG_ROOT_MOTION as B,MOVE_FLAG_SLIDE_START as H,MOVE_FLAG_SPRINT as Z,MOVE_FLAG_SPRINT_START as W,SNAPSHOT_FLAG_CROUCH_SUPPRESSED as $,SNAPSHOT_FLAG_CROUCHING as Q,NetCharacterProxySmoother as J,NetCharacterSavedMoveBuffer as K,accrueNetCharacterServerMoveTime as _,createNetCharacterMovementSnapshot as tt,createNetCharacterServerMoveTimingState as et,consumeNetCharacterServerMoveTime as it,decodeNetCharacterMoveBatch as ot,decodeNetCharacterOwnerAck as st,decodeNetCharacterOwnerCorrection as nt,decodeNetCharacterSimulatedState as rt,encodeNetCharacterMoveBatch as at,encodeNetCharacterOwnerAck as ht,encodeNetCharacterOwnerCorrection as lt,encodeNetCharacterSimulatedState as ct,validateNetCharacterMove as ut}from"./net-character-movement-protocol.js";import{NetMode as dt}from"../../../../net/net-session.js";import{setSlideJumpVelocity as pt,shouldContinueSlide as mt,shouldStartSlide as vt,updateSlideVelocity as yt,updateSlideVelocityFromDisplacement as St}from"./character-slide.js";export*from"./net-character-movement-protocol.js";const gt=131070,Mt=new h(0,1,0),ft=new h,xt=new h,Tt=new h,Ct=new h,Rt=new h,wt=new h,At=new h,qt=new h,Dt=new h,bt=new h,kt=new h,It=new h,zt=new h,Pt=new h,Ot=new h(0,1,0),jt=new h(0,-.05,0),Gt=new h,Yt=new a,Nt=new s.Euler,Ft=new h,Vt=new h,Ut=new h,Xt=new h,Et=new i.CharacterCollision;let Lt=class extends R{get autoStepMinWidth(){return this.cc.autostepMinWidth()}set autoStepMinWidth(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),t,this.cc.autostepIncludesDynamicBodies())}get autoStepDynamicObjects(){return this.cc.autostepIncludesDynamicBodies()}set autoStepDynamicObjects(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),this.cc.autostepMinWidth(),t)}get autoStepMaxHeight(){return this.cc.autostepMaxHeight()}set autoStepMaxHeight(t){this.cc.enableAutostep(t,this.cc.autostepMinWidth(),this.cc.autostepIncludesDynamicBodies())}get snapToGround(){return this.cc.snapToGroundDistance()}set snapToGround(t){this.cc.enableSnapToGround(t)}set offset(t){this.cc.setOffset(t)}get offset(){return this.cc.offset()}set normalNudgeFactor(t){this.cc.setNormalNudgeFactor(t)}get normalNudgeFactor(){return this.cc.normalNudgeFactor()}constructor(){super(),this.isDefaultCharacterMovementComponent=!0,this.directionInput=new d,this.jumpInput=new u,this.sprintInput=new u,this.crouchInput=new u,this.rotationInput=new p,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.maxSpeedCrouch=4,this.slideEnabled=!1,this.slideMinStartSpeed=8,this.slideMinExitSpeed=4,this.slideDeceleration=3,this.slideGravityScale=1,this.slideSteeringRate=2,this.sprintStartBoostSpeed=0,this.sprintStartBoostDamping=6,this.jumpVelocity=7,this.fallingMovementControl=.5,this.fallingReorientation=!1,this.groundAccelerationRate=4,this.gravityOverride=null,this.colliderHeight=2,this.colliderRadius=.5,this.crouchColliderHeight=1,this.crouchColliderRadius=null,this.jumpInAir=!1,this.mass=50,this.allowSliding=!0,this.minSlopeSlideAngle=r.degToRad(70),this.maxSlopeClimbAngle=r.degToRad(70),this.applyImpulsesToDynamicBodies=!0,this.normalizedDirection=!0,this.characterCollision=!1,this.allowRootMotionJumpCancel=!1,this.enabled=!0,this.rotateToMovementDirection=!1,this.smoothRotation=!0,this.rotationSpeed=40,this.maxRotationSpeed=100,this.impulseDamping=2,this.moveSendInterval=N,this.simulatedStateInterval=V,this.maxSavedMoves=O,this.maxReplayedMoves=z,this.maxServerMovesPerTick=P,this.maxMovesPerPacket=I,this.maxMoveDeltaTime=k,this.maxCombinedMoveDeltaTime=b,this.maxServerMoveDeltaTimeScalar=j,this.maxClientTimeAhead=q,this.maxServerMoveTimeBudget=G,this.maxSubstepDeltaTime=Y,this.fallGraceTime=.1,this.correctionToleranceSq=U*U,this.largeCorrectionThreshold=D,this.teleportSnapThreshold=X,this.listenServerSmoothing=!0,this.listenServerSmoothLocationTime=.04,this.listenServerMaxSmoothUpdateDistance=1,this.listenServerNoSmoothUpdateDistance=2.5,this.debugCorrections=!0,this.suppressUncrouchLift=!1,this.velocity=new h,this.visualSmoothingOffset=new h,this.slideDirection=new h,this.slideSurfaceNormal=new h(0,1,0),this.mode=A.walking,this.isSprinting=!1,this.isCrouching=!1,this.isSliding=!1,this.pressedJump=!1,this.rayTestResult=new f,this.groundRayTestOptions={debug:!1,excludeTriggers:!0,excludeActor:void 0,resolveActor:!1},this.physicsSystem=c(M),this.netService=c(g),this.state={sequence:0,position:new h,velocity:new h,yaw:0,lookYaw:0,mode:A.walking,grounded:!1,currentSpeed:0,fallGraceTime:0,prevInputDirection:new h,prevRotateToMovementDirection:!1},this.movementModes=new Map,this.savedMoves=new K(O),this.serverMoveTiming=et(),this.serverMoveQueue=[],this.inputMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.authoritativeMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.movementModeContext={component:this,state:this.state,move:this.inputMoveScratch,deltaTime:0,rotatedDirection:xt,platformVelocity:Ct,outVelocity:Tt,rootMotionActive:!1,startedSprinting:!1},this.proxySmoother=new J(F,X),this.proxySample=tt(),this.pendingSnapshot=tt(),this.impulse=new h,this.prevRootMotionPos=new h,this.rootMotionOptions={},this.resetRootMotion=!1,this.nextMoveSequence=0,this.clientMoveTime=0,this.lastSentClientMoveTime=0,this.moveSendAccumulator=0,this.simulatedStateAccumulator=0,this.proxyTime=0,this.lastServerProcessedSequence=0,this.lastServerReceivedSequence=0,this.lastAutonomousMoveFlags=0,this.previousSprintInput=!1,this.previousCrouchInput=!1,this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.initialized=!1,this.cc=this.physicsSystem.getCharacterController(.1),this.cc.enableSnapToGround(.1),this.cc.enableAutostep(0,.1,!1),this.registerMovementMode(Bt),this.registerMovementMode(Ht),this.registerMovementMode({mode:A.sliding,update:t=>this.updateSlidingMode(t)})}onInit(){this.groundRayTestOptions.excludeActor=this.actor,this.configureCharacterController(),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:C.kinematic,continousCollisionDetection:!1,friction:0,restitution:.5,ignoreForNavMesh:!0}),this.rotationInput.rotation.copy(this.actor.rotation),this.initializeStateFromActor(),this.initialized=!0,this.physicsSystem.beforeStep.pipe(o(this.disposed)).subscribe(t=>this.tick(t))}onLateUpdate(t){this.updateVisualSmoothing(t)}registerMovementMode(t){this.movementModes.set(t.mode,t)}applyImpulse(t){this.impulse.add(t)}getEffectiveGravity(){return this.gravityOverride??this.physicsSystem.getGravity().y}get isGrounded(){return this.rayTestResult.hasHit||this.cc.computedGrounded()}setRootMotionAction(t,e={}){const i=t?.getClip();if(i instanceof l){this.rootMotionAction=t,this.rootMotionOptions=e,this.resetRootMotion=!0;const o=[];this.rootMotionInterpolant=i.motionTrack.InterpolantFactoryMethodSmooth(o);const n=s.PropertyBinding.parseTrackName(i.motionTrack.name);this.rootMotionRootBone=this.actor.object.getObjectByName(n.nodeName)}}serverMove(t){const e=ot(t);if(e.ok)for(const t of e.value.moves)ut(t,this.lastServerReceivedSequence,this.maxMoveDeltaTime)&&(this.lastServerReceivedSequence=t.sequence,this.serverMoveQueue.push(t))}clientMoveAck(t){const e=st(t);e.ok&&this.actor.netRole===m.autonomousProxy&&(this.savedMoves.ack(e.value.sequence),this.sprintPolicy?.ack?.(e.value.sequence,!1))}clientMoveCorrection(t){const e=nt(t);e.ok&&this.actor.netRole===m.autonomousProxy&&(this.debugCorrections&&(null==this.correctionDebug&&(this.correctionDebug=new Qt(Kt(this.actor.object))),this.correctionDebug.update(this.state.position,e.value.snapshot)),this.applyCorrection(e.value.snapshot))}simulatedState(t){const e=rt(t);e.ok&&this.actor.netRole===m.simulatedProxy&&this.proxySmoother.push(e.value,this.proxyTime)}tick(t){if(!this.initialized)return;t=Math.min(.1,t);const e=this.actor.netRole,i=this.netService.mode;e!==m.simulatedProxy?this.enabled&&(e!==m.autonomousProxy?this.isRemoteControlledAuthority(i,e)?this.tickRemoteAuthority(t):this.tickAuthority(t,i):this.tickAutonomousProxy(t)):this.tickSimulatedProxy(t)}tickAutonomousProxy(t){const e=this.state.mode,i=this.lastAutonomousMoveFlags,o=this.createMoveFromInput(t,++this.nextMoveSequence,{quantizeClientTime:!0});this.performMove(o,_t),this.resetToggleCrouchAfterSlide(e);const s=this.state.mode!==e||o.flags!==i;this.lastAutonomousMoveFlags=o.flags,this.savedMoves.capacity=this.maxSavedMoves,this.savedMoves.maxCombinedDeltaTime=Math.min(this.maxCombinedMoveDeltaTime,this.maxMoveDeltaTime),this.savedMoves.push(o),this.sendSavedMoves(t,s)}tickAuthority(t,e){const i=this.state.mode,o=this.createMoveFromInput(t,++this.nextMoveSequence);this.performMove(o,_t),this.resetToggleCrouchAfterSlide(i),e!==dt.none&&this.sendSimulatedState(t,!1)}resetToggleCrouchAfterSlide(t){t===A.sliding&&this.state.mode!==A.sliding&&"toggle"===this.crouchInput.mode&&this.crouchInput.activated&&this.crouchInput.setActivated(!1)}tickRemoteAuthority(t){_(this.serverMoveTiming,t,this.maxServerMoveTimeBudget);let e=!1;const i=Number.isFinite(this.maxServerMovesPerTick)?Math.max(1,Math.floor(this.maxServerMovesPerTick)):this.serverMoveQueue.length,o=Math.min(this.serverMoveQueue.length,i),s=Ut.copy(this.actor.position);let n=!1;for(let t=0;t<o;t++){const t=this.serverMoveQueue.shift();if(null==t)break;if(!ut(t,this.lastServerProcessedSequence,this.maxMoveDeltaTime)){console.log("Net: Invalid move",t),this.sendOwnerCorrection(!0),e=!0;continue}const i=it(this.serverMoveTiming,t,{maxMoveDeltaTime:this.maxMoveDeltaTime,maxServerMoveDeltaTimeScalar:this.maxServerMoveDeltaTimeScalar,maxClientTimeAhead:this.maxClientTimeAhead});if(i<0){this.sendOwnerCorrection(!0),e=!0;continue}const o=Wt(t,this.authoritativeMoveScratch);o.dt=i,o.rootMotionX=0,o.rootMotionY=0,o.rootMotionZ=0,o.flags&=~B,this.performMove(o,{immediate:!0,savedRootMotion:!1}),n=!0,this.lastServerProcessedSequence=o.sequence;const s=$t(this.state,t);if(s>this.correctionToleranceSq){console.log(`Net server: Correction error: ${Math.sqrt(s)}`);const o=this.state.position.x-t.clientX,n=this.state.position.y-t.clientY,r=this.state.position.z-t.clientZ;console.log(`diff x: ${o}, y: ${n}, z: ${r}`),console.log({sequence:t.sequence,moveDt:t.dt,serverMoveDeltaTime:i,flags:t.flags,mode:this.state.mode,grounded:this.state.grounded,fallGraceTime:this.state.fallGraceTime}),this.sendOwnerCorrection(s>this.largeCorrectionThreshold*this.largeCorrectionThreshold),e=!0}}0===this.lastServerProcessedSequence||e||(this.sprintPolicy?.ack?.(this.lastServerProcessedSequence,!1),this.clientMoveAck(ht(this.lastServerProcessedSequence))),n&&this.accumulateListenServerVisualSmoothing(s,this.actor.position),this.sendSimulatedState(t,!1)}tickSimulatedProxy(t){this.proxyTime+=t,this.proxySmoother.sample(this.proxyTime,this.proxySample)&&this.applySnapshot(this.proxySample,!0)}accumulateListenServerVisualSmoothing(t,e){if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);Xt.subVectors(t,e);const i=Xt.lengthSq();i>1e-8&&(i>this.listenServerNoSmoothUpdateDistance*this.listenServerNoSmoothUpdateDistance?this.visualSmoothingOffset.set(0,0,0):(i>this.listenServerMaxSmoothUpdateDistance*this.listenServerMaxSmoothUpdateDistance&&Xt.setLength(this.listenServerMaxSmoothUpdateDistance),this.visualSmoothingOffset.add(Xt)))}updateVisualSmoothing(t){if(this.visualSmoothingOffset.lengthSq()<=1e-8)return void this.visualSmoothingOffset.set(0,0,0);if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);const e=Math.max(.001,this.listenServerSmoothLocationTime);t<e?this.visualSmoothingOffset.multiplyScalar(1-t/e):this.visualSmoothingOffset.set(0,0,0),this.visualSmoothingOffset.lengthSq()<=1e-4&&this.visualSmoothingOffset.set(0,0,0)}shouldSmoothListenServerRemoteAuthority(){return this.listenServerSmoothing&&this.actor.netRole===m.authority&&this.netService.isServer&&!this.netService.isDedicatedServer&&this.isRemoteControlledAuthority()}createMoveFromInput(t,e,i={}){const o=r.clamp(t,.001,this.maxMoveDeltaTime);this.clientMoveTime+=o;let s=this.clientMoveTime,n=o;!0===i.quantizeClientTime&&(s=Math.max(this.lastSentClientMoveTime+.001,Math.round(1e3*this.clientMoveTime)/1e3),n=r.clamp(s-this.lastSentClientMoveTime,.001,this.maxMoveDeltaTime),this.lastSentClientMoveTime=s),this.sampleRootMotion(At);const a=this.crouchInput.activated,h=a&&!this.previousCrouchInput;this.previousCrouchInput=a;const l=!a&&this.sprintInput.activated,c=l&&!this.previousSprintInput;this.previousSprintInput=l;const u=(this.jumpInput.activated?L:0)|(l?Z:0)|(a?E:0)|(h&&this.slideEnabled?H:0)|(c?W:0)|(At.lengthSq()>0?B:0),d=function(t,e){e.set(t.x,0,t.y),e.lengthSq()>1&&e.normalize();return e}(this.directionInput.vector,Ft),p=this.inputMoveScratch;return p.sequence=e>>>0,p.clientTime=s,p.dt=n,p.inputX=d.x,p.inputY=d.z,p.yaw=this.rotationInput.rotation.y,p.flags=u,p.clientX=this.state.position.x,p.clientY=this.state.position.y,p.clientZ=this.state.position.z,p.rootMotionX=At.x,p.rootMotionY=At.y,p.rootMotionZ=At.z,p}performMove(t,e){const i=r.clamp(t.dt,.001,this.maxMoveDeltaTime),o=Math.max(1,Math.ceil(i/this.maxSubstepDeltaTime)),s=0!==(t.flags&Z)&&0===(t.flags&E);this.sprintPolicy?.update?.(i,t.sequence,s),It.set(e.savedRootMotion?t.rootMotionX:0,e.savedRootMotion?t.rootMotionY:0,e.savedRootMotion?t.rootMotionZ:0),e.savedRootMotion||this.sampleRootMotion(It);let n=i;const a=i/o;for(let s=0;s<o;s++){const o=i>0?a/i:1;this.performSubstep(t,Math.min(a,n),It,o,e.immediate,0===s),n-=a}t.clientX=this.state.position.x,t.clientY=this.state.position.y,t.clientZ=this.state.position.z,t.flags=It.lengthSq()>0?t.flags|B:t.flags&~B,this.state.sequence=t.sequence,this.syncPublicState()}performSubstep(t,e,i,o,s,n){if(e<.001)return;this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded;const r=null!=this.rootMotionAction&&this.rootMotionAction.enabled,a=i.lengthSq()>0,h=!r&&0!==(t.flags&L),l=r||a;this.updateCrouchState(t,n,l,h),this.pressedJump=h,this.isSprinting=!1,this.updateRotation(t,e,r,a),this.resolvePlatformVelocity(Ct);const c=this.movementModeContext,u=this.movementModes.get(this.state.mode);if(null!=u){c.move=t,c.deltaTime=e,c.rootMotionActive=l,c.startedSprinting=n&&!l&&0===(t.flags&E)&&0!==(t.flags&W);const i=u.update(c);"number"==typeof i&&(this.state.mode=i)}else Tt.set(0,0,0);if(a){qt.copy(i).multiplyScalar(o).applyQuaternion(this.actor.quaternion),Dt.copy(qt).divideScalar(e),this.state.mode===A.walking?(Tt.x=Dt.x+Ct.x,Tt.z=Dt.z+Ct.z):(Tt.x=Dt.x,Tt.z=Dt.z);const t=Math.sqrt(Dt.x*Dt.x+Dt.z*Dt.z);t>.4&&(this.state.currentSpeed=t)}if(this.applyImpulseToVelocity(Tt,e),h&&this.isSprinting){const t=Math.max(0,this.maxSpeedSprint),e=Zt(Tt);if(e>t){const i=t/e;Tt.x*=i,Tt.z*=i,this.state.velocity.x*=i,this.state.velocity.z*=i}}this.state.mode===A.walking&&this.state.velocity.copy(Tt),this.applyMovement(Tt,e,s),this.state.mode===A.sliding&&(St(this.state.velocity,wt,Ct,this.slideSurfaceNormal,e),this.state.currentSpeed=Zt(this.state.velocity)),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.updateModeAfterMove(Tt,e),this.state.mode===A.sliding&&this.state.velocity.length()<Math.max(0,this.slideMinExitSpeed)&&(this.state.mode=A.walking)}updateRotation(t,e,i,o){ft.set(-t.inputX,0,t.inputY),ft.lengthSq()>1&&ft.normalize();const s=this.state.prevRotateToMovementDirection!==this.rotateToMovementDirection;let n=r.euclideanModulo(t.yaw-this.state.lookYaw+Math.PI,2*Math.PI)-Math.PI;if(s&&(this.actor.object.quaternion.setFromEuler(Nt.set(0,t.yaw,0)),this.state.prevRotateToMovementDirection||(n=0,this.state.lookYaw=t.yaw),this.state.prevRotateToMovementDirection=this.rotateToMovementDirection),xt.set(0,0,0),i)this.state.lookYaw=t.yaw;else if(this.rotateToMovementDirection){if(ft.lengthSq()>0&&this.state.mode!==A.falling){const i=Nt.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,o=Math.atan2(ft.x,ft.z),s=.99*t.yaw+o;if(this.smoothRotation){const t=r.euclideanModulo(s-i+Math.PI,2*Math.PI)-Math.PI;let o=r.clamp(t*this.rotationSpeed*e,-this.maxRotationSpeed*e,this.maxRotationSpeed*e);Math.abs(o)>Math.abs(t)&&(o=t),this.actor.object.quaternion.setFromEuler(Nt.set(0,i+o,0))}else this.actor.object.quaternion.setFromEuler(Nt.set(0,s,0));this.state.prevInputDirection.lerp(ft,e*this.rotationSpeed),this.state.lookYaw+=n,xt.copy(this.actor.object.getWorldDirection(Ft).normalize())}}else o||(this.state.lookYaw+=n,this.actor.object.quaternion.multiply(Yt.setFromEuler(Nt.set(0,n,0))),ft.lengthSq()>0&&xt.copy(ft).applyQuaternion(this.actor.object.quaternion).normalize())}applyMovement(t,e,i){if(t.lengthSq()>0||!this.state.grounded){if(Rt.copy(t).multiplyScalar(e),this.state.grounded&&((o=this.state.mode)===A.walking||o===A.sliding)&&(this.state.mode===A.walking&&this.rayTestResult.distance<=this.cc.offset()&&(Rt.y=Math.max(0,Ct.y*e)),this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Rt,this.getCollisionGroup()),this.cc.computedCollision(0,Et),null!=Et.normal1)){const t=Ft.copy(Et.normal1);Math.acos(r.clamp(t.dot(Mt),-1,1))>this.cc.maxSlopeClimbAngle()&&(Rt.y=.016*this.getEffectiveGravity()*.5)}wt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Rt,this.getCollisionGroup()))}else wt.set(0,0,0);var o;this.suppressUncrouchLift&&(this.suppressUncrouchLift=!1,this.state.grounded&&this.state.mode===A.walking&&Rt.y<=1e-6&&wt.y>0&&(wt.y=0)),this.state.position.add(wt),i?(this.actor.position.copy(this.state.position),this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()):this.physicsSystem.setNextKinematicPosition(this.actor,this.state.position)}updateModeAfterMove(t,e){const i=function(t){if(0===t.numComputedCollisions())return!1;const e=t.computedCollision(0);Gt.set(e.normal2.x,e.normal2.y,e.normal2.z);const i=Gt.angleTo(Mt);Gt.set(e.normal1.x,e.normal1.y,e.normal1.z);const o=Gt.angleTo(Mt);if(i<100)return!1;return o>t.minSlopeSlideAngle()}(this.cc);!this.state.grounded||i?this.state.mode!==A.falling&&(this.state.fallGraceTime+=e,this.state.fallGraceTime>this.fallGraceTime+1e-6&&(this.state.mode=A.falling,this.state.velocity.copy(t))):this.state.velocity.y<=0&&(this.state.mode===A.falling&&(this.state.mode=A.walking),this.state.mode!==A.sliding&&(this.state.velocity.y=0),this.state.fallGraceTime=0)}applyImpulseToVelocity(t,e){if(this.impulse.lengthSq()<=.1)return void this.impulse.set(0,0,0);const i=Math.min(1,this.impulse.length()/5);t.x=r.lerp(t.x,this.impulse.x,i),t.z=r.lerp(t.z,this.impulse.z,i),t.y+=this.impulse.y;const o=Math.exp(-this.impulseDamping*e);this.impulse.x*=o,this.impulse.y>0?this.impulse.y+=e*this.getEffectiveGravity():this.impulse.y*=o,this.impulse.z*=o}sendSavedMoves(t,e=!1){if(this.moveSendAccumulator+=t,!e&&this.moveSendAccumulator<this.moveSendInterval)return;this.moveSendAccumulator=0;const i=this.savedMoves.getMovesForSend(this.maxMovesPerPacket);0!==i.length&&this.serverMove(at(i))}sendOwnerCorrection(t){const e=this.toSnapshot(this.pendingSnapshot);t&&(e.horizontalSpeed=this.horizontalSpeed),this.sprintPolicy?.ack?.(e.sequence,!0),this.clientMoveCorrection(lt(e))}sendSimulatedState(t,e){this.simulatedStateAccumulator+=t,!e&&this.simulatedStateAccumulator<this.simulatedStateInterval||(this.simulatedStateAccumulator=0,this.simulatedState(ct(this.toSnapshot(this.pendingSnapshot))))}applyCorrection(t){this.sprintPolicy?.restore?.(t.sequence),this.savedMoves.ack(t.sequence),this.sprintPolicy?.ack?.(t.sequence,!0),this.applySnapshot(t,!0),this.savedMoves.replayAfter(t.sequence,t=>(this.performMove(t,{immediate:!0,savedRootMotion:!0}),null),this.maxReplayedMoves)}applySnapshot(t,e){this.state.sequence=t.sequence,this.state.position.set(t.x,t.y,t.z),this.state.velocity.set(t.velocityX,t.velocityY,t.velocityZ),this.state.yaw=t.yaw,this.state.lookYaw=t.yaw,this.state.mode=t.mode,this.state.currentSpeed=t.horizontalSpeed,this.state.fallGraceTime=0,this.actor.position.copy(this.state.position),this.actor.object.quaternion.setFromEuler(Nt.set(0,t.yaw,0)),this.crouchSuppressedUntilRelease=0!==(t.flags&$),this.setCrouching(0!==(t.flags&Q)||t.mode===A.sliding),e&&(this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.syncPublicState()}toSnapshot(t){return t.sequence=this.state.sequence,t.x=this.state.position.x,t.y=this.state.position.y,t.z=this.state.position.z,t.velocityX=this.state.velocity.x,t.velocityY=this.state.velocity.y,t.velocityZ=this.state.velocity.z,t.yaw=Nt.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,t.mode=this.state.mode,t.flags=(this.isCrouching?Q:0)|(this.crouchSuppressedUntilRelease?$:0),t.horizontalSpeed=this.state.currentSpeed,t}syncPublicState(){this.velocity.copy(this.state.velocity),this.mode=this.state.mode,this.horizontalSpeed=this.state.currentSpeed,this.isSliding=this.state.mode===A.sliding,this.isSliding?(this.resolveGroundNormal(this.slideSurfaceNormal),this.slideDirection.copy(this.state.velocity).projectOnPlane(this.slideSurfaceNormal),this.slideDirection.lengthSq()>1e-8?this.slideDirection.normalize():this.slideDirection.set(0,0,0)):(this.slideDirection.set(0,0,0),this.slideSurfaceNormal.copy(Mt))}sampleRootMotion(t){if(t.set(0,0,0),null==this.rootMotionAction||this.rootMotionAction.isRunning()||this.clearRootMotionAction(this.rootMotionAction),null!=this.rootMotionAction&&this.rootMotionOptions.cancelWithJump&&this.jumpInput.activated&&(this.isGrounded||this.jumpInAir)){const e=this.rootMotionAction,i=this.rootMotionOptions.onJumpCancel;return this.clearRootMotionAction(e),e.stop(),i?.(),t}if(null==this.rootMotionAction)return t;if(!(this.rootMotionAction.getClip()instanceof l))return t;const e=this.rootMotionInterpolant;this.resetRootMotion&&(this.prevRootMotionPos.fromArray(e.evaluate(0)),this.resetRootMotion=!1),kt.fromArray(e.evaluate(this.rootMotionAction.time)),t.subVectors(kt,this.prevRootMotionPos),this.prevRootMotionPos.copy(kt);return(this.rootMotionRootBone??this.rootMotionAction.getRoot()).getWorldScale(bt),t.multiply(bt),t}clearRootMotionAction(t){null!=t&&this.rootMotionAction!==t||(this.rootMotionAction=null,this.rootMotionOptions={},this.resetRootMotion=!1)}isRemoteControlledAuthority(t=this.netService.mode,e=this.actor.netRole){if(t===dt.none||e!==m.authority||t>=dt.client)return!1;return null!=this.netService.resolveActorConnection(this.actor)&&!this.netService.isLocalOwner(this.actor)}configureCharacterController(){const t=this.cc;t.setApplyImpulsesToDynamicBodies(this.applyImpulsesToDynamicBodies),t.setMinSlopeSlideAngle(this.minSlopeSlideAngle),t.setMaxSlopeClimbAngle(this.maxSlopeClimbAngle),t.setCharacterMass(this.mass),t.setSlideEnabled(this.allowSliding)}initializeStateFromActor(){this.state.position.copy(this.actor.position),this.state.velocity.set(0,0,0),this.state.yaw=this.actor.rotation.y,this.state.lookYaw=this.rotationInput.rotation.y,this.state.mode=this.mode,this.state.currentSpeed=this.horizontalSpeed,this.state.prevRotateToMovementDirection=this.rotateToMovementDirection}createCollisionShape(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1),i=new x(t,e);return i.offset.y=this.getCapsuleOffsetY(t,e),i.collisionGroup=gt,i}updateCrouchState(t,e,i,o){if(!(0!==(t.flags&E)))return this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.state.mode===A.sliding&&(this.state.mode=A.walking),void this.tryUncrouch();if(this.state.mode===A.sliding&&(!this.slideEnabled||i))return this.slideOnLandingRequested=!1,this.state.mode=A.walking,void(this.crouchSuppressedUntilRelease||this.setCrouching(!0));if(this.state.mode===A.sliding&&o)return this.crouchSuppressedUntilRelease=!0,this.slideOnLandingRequested=!1,void this.tryUncrouch();if(this.crouchSuppressedUntilRelease)return void(this.slideOnLandingRequested=!1);if(this.setCrouching(!0),!this.slideEnabled||i)return void(this.slideOnLandingRequested=!1);if(this.state.mode===A.falling)return void(this.slideOnLandingRequested=!0);this.resolveGroundNormal(Vt);const s=this.slideOnLandingRequested&&this.state.mode===A.walking&&this.state.grounded,n=e&&0!==(t.flags&H)||s;s&&(this.slideOnLandingRequested=!1);const r=Zt(this.state.velocity);this.state.mode===A.walking&&vt(this.slideEnabled,n,this.state.grounded,this.isWalkableSlideSurface(Vt),i,r,this.slideMinStartSpeed)&&(this.state.mode=A.sliding,this.slideSurfaceNormal.copy(Vt),this.state.velocity.projectOnPlane(this.slideSurfaceNormal),this.state.currentSpeed=Zt(this.state.velocity))}updateSlidingMode(t){const e=t.state,i=t.move;this.resolveGroundNormal(this.slideSurfaceNormal);const o=this.isWalkableSlideSurface(this.slideSurfaceNormal),s=e.velocity.length();if(!e.grounded||!o)return e.mode=A.falling,Ht.update(t),A.falling;if(this.slideEnabled&&0!==(i.flags&E)&&!t.rootMotionActive&&0!==(i.flags&L))return pt(t.outVelocity,e.velocity,this.jumpVelocity),e.velocity.copy(t.outVelocity),e.currentSpeed=Zt(e.velocity),A.falling;if(!mt(this.slideEnabled,0!==(i.flags&E),e.grounded,o,t.rootMotionActive,s,this.slideMinExitSpeed))return e.mode=A.walking,Bt.update(t),A.walking;const n=yt(e.velocity,e.velocity,this.slideSurfaceNormal,t.rotatedDirection,this.getEffectiveGravity(),t.deltaTime,this.slideDeceleration,this.slideGravityScale,this.slideSteeringRate);if(e.currentSpeed=Zt(e.velocity),n<Math.max(0,this.slideMinExitSpeed))return e.mode=A.walking,Bt.update(t),A.walking;t.outVelocity.copy(e.velocity).add(t.platformVelocity)}tryUncrouch(){this.isCrouching&&this.canUncrouch()&&this.setCrouching(!1)&&(this.suppressUncrouchLift=!0,this.state.fallGraceTime=0)}resolveGroundNormal(t){return!this.rayTestResult.hasHit||this.rayTestResult.hitNormal.lengthSq()<=1e-8?t.copy(Mt):(t.copy(this.rayTestResult.hitNormal).normalize(),t.dot(Mt)<0&&t.multiplyScalar(-1),t)}isWalkableSlideSurface(t){return t.dot(Mt)>=Math.cos(this.cc.maxSlopeClimbAngle())}setCrouching(t){return this.isCrouching!==t&&(this.isCrouching=t,this.syncColliderShape(),!0)}canUncrouch(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1);return!this.physicsSystem.hasActorCapsuleIntersection(this.actor,this.state.position,t,e,this.getCapsuleOffsetY(t,e),this.getCollisionGroup())}syncColliderShape(){const t=this.getColliderHeight(this.isCrouching),e=this.getColliderRadius(this.isCrouching);this.physicsSystem.setActorCapsuleCollider(this.actor,t,e,this.getCapsuleOffsetY(t,e))}getColliderHeight(t){const e=Number.isFinite(this.colliderHeight)?Math.max(0,this.colliderHeight):0;if(!t)return e;const i=Number.isFinite(this.crouchColliderHeight)?this.crouchColliderHeight:e;return r.clamp(i,0,e)}getColliderRadius(t){const e=Number.isFinite(this.colliderRadius)?Math.max(.001,this.colliderRadius):.001;if(!t)return e;const i=this.crouchColliderRadius??e,o=Number.isFinite(i)?i:e;return r.clamp(o,.001,e)}getCapsuleOffsetY(t,e){return e+t/2+this.offset}checkGrounded(t){jt.y=-Math.max(.05,this.cc.snapToGroundDistance()),this.physicsSystem.rayTest(zt.addVectors(t,Ot.set(0,this.offset,0)),Pt.addVectors(t,jt),this.rayTestResult,this.groundRayTestOptions)}resolvePlatformVelocity(t){return t.set(0,0,0),this.rayTestResult.hasHit&&null!=this.rayTestResult.actor&&this.physicsSystem.getLinearVelocity(this.rayTestResult.actor,t),t}getCollisionGroup(){return this.characterCollision?null:gt}};t([T(),e("design:type",Number)],Lt.prototype,"colliderHeight",void 0),t([T(),e("design:type",Number)],Lt.prototype,"colliderRadius",void 0),t([T(),e("design:type",Number)],Lt.prototype,"crouchColliderHeight",void 0),t([T({optional:!0}),e("design:type",Number)],Lt.prototype,"crouchColliderRadius",void 0),t([S(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"serverMove",null),t([v(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"clientMoveAck",null),t([v(!0),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"clientMoveCorrection",null),t([y(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"simulatedState",null),Lt=t([w({inEditor:!1}),e("design:paramtypes",[])],Lt);export{Lt as CharacterMovementComponent};const Bt={mode:A.walking,update(t){const e=t.component,i=t.move,o=t.state,s=t.rotatedDirection,n=Math.min(1,Math.sqrt(i.inputX*i.inputX+i.inputY*i.inputY)),r=!e.rotateToMovementDirection&&i.inputY<0,a=e.isCrouching,h=!t.rootMotionActive&&!a&&0===(i.flags&E)&&0!==(i.flags&Z)&&!r&&0!==s.lengthSq()&&(e.sprintPolicy?.canSprint()??!0),l=(a?e.maxSpeedCrouch:r?e.maxSpeedBackwards:h?e.maxSpeedSprint:e.maxSpeed)*(e.normalizedDirection?1:n);if(0!==s.lengthSq()){e.isSprinting=h,h&&e.sprintPolicy?.commitSprint(t.deltaTime,i.sequence);let a=Math.min(l,o.currentSpeed),c=e.groundAccelerationRate;if(h&&t.startedSprinting&&e.sprintStartBoostSpeed>0){const t=e.normalizedDirection?1:n;a=Math.max(a,l+e.sprintStartBoostSpeed*t),c=e.sprintStartBoostDamping}else h&&!r&&e.sprintStartBoostSpeed>0&&o.currentSpeed>l&&(a=o.currentSpeed,c=e.sprintStartBoostDamping);o.currentSpeed=function(t,e,i,o){return e+(t-e)*Math.exp(-i*o)}(a,l,c,t.deltaTime),t.outVelocity.copy(s).multiplyScalar(function(t,e,i,o){const s=i*o;if(s<=1e-6)return t;return e+(t-e)*(1-Math.exp(-s))/s}(a,l,c,t.deltaTime))}else o.currentSpeed=0,t.outVelocity.set(0,0,0);if(0!==(i.flags&L))return o.mode=A.falling,o.velocity.copy(t.outVelocity),o.velocity.y=e.jumpVelocity,A.falling;t.outVelocity.y=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.add(t.platformVelocity)}},Ht={mode:A.falling,update(t){const e=t.component,i=t.state,o=t.move;0!==(o.flags&L)&&e.jumpInAir&&(i.velocity.copy(t.outVelocity),i.velocity.y=e.jumpVelocity),i.velocity.y+=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.copy(i.velocity),t.outVelocity.addScaledVector(t.rotatedDirection,e.fallingMovementControl),e.fallingReorientation&&t.outVelocity.applyAxisAngle(Mt,r.euclideanModulo(o.yaw-i.lookYaw+Math.PI,2*Math.PI)-Math.PI)}};function Zt(t){return Math.sqrt(t.x*t.x+t.z*t.z)}function Wt(t,e){return e.sequence=t.sequence,e.clientTime=t.clientTime,e.dt=t.dt,e.inputX=t.inputX,e.inputY=t.inputY,e.yaw=t.yaw,e.flags=t.flags,e.clientX=t.clientX,e.clientY=t.clientY,e.clientZ=t.clientZ,e.rootMotionX=t.rootMotionX,e.rootMotionY=t.rootMotionY,e.rootMotionZ=t.rootMotionZ,e}function $t(t,e){const i=t.position.x-e.clientX,o=t.position.y-e.clientY,s=t.position.z-e.clientZ;return i*i+o*o+s*s}class Qt{constructor(t){this.scene=t,this.serverPosition=new h,this.direction=new h}update(t,e){const i=this.serverPosition.set(e.x,e.y,e.z),o=i.distanceTo(t);o>.1&&console.log(`Correction applied. Error: ${o.toFixed(3)}. Server position: (${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z.toFixed(2)}), Client position: (${t.x.toFixed(2)}, ${t.y.toFixed(2)}, ${t.z.toFixed(2)})`);const s=this.direction.copy(i).sub(t).normalize();Jt.position.copy(t),Jt.setDirection(s),Jt.setLength(o);const n=Kt(this.scene);n.add(Jt),setTimeout(()=>{n.remove(Jt)},1e3)}}const Jt=new n(new h(0,1,0),new h,1,16711680);function Kt(t){return null==t.parent?t:Kt(t.parent)}const _t={immediate:!1,savedRootMotion:!0};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -0,0 +1,7 @@
1
+ import { NodeShaderMaterial, Vec4Node } from 'three-shader-graph';
2
+ /**
3
+ * Creates the renderer-owned third MRT output without coupling the generic
4
+ * node-material compiler to Hology's G-buffer layout.
5
+ */
6
+ export declare function createMotionVectorOutput(material: NodeShaderMaterial): Vec4Node;
7
+ //# sourceMappingURL=motion-vector-node.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{isWgslCompiler as e,isWgslFragmentCompiler as n,vec4 as i,Vec4Node as t}from"three-shader-graph";export function createMotionVectorOutput(e){const n=e,t=e.nodeMaterialDefinition.position;if(null!=t&&null==n.outputPreviousPosition)return i(0,0,1,1);const r=t??new o("current",n.outputPreviousTransform??null),u=null==t?new o("previous",n.outputPreviousTransform??null):n.outputPreviousPosition;return new s(r,u)}class o extends t{constructor(e,n){super(),this.frame=e,this.previousTransform=n}compile(i){if(!e(i)||n(i))throw new Error("Renderer motion clip positions require a WGSL vertex graph.");const t=`rendererMotionClip${i.variable()}`,o=i.getRendererVertexPosition();if("current"===this.frame)return{chunk:`\n#ifdef RENDERER_MOTION_VECTORS\n#ifdef USE_SKINNING\n let ${t} = rendererMotionCurrentClip(\n rendererSkinPosition(input.position, input.skinIndex, input.skinWeight),\n input.instanceIndex\n );\n#else\n let ${t} = rendererMotionCurrentClip(${o}, input.instanceIndex);\n#endif\n#else\n let ${t} = vec4<f32>(0.0);\n#endif`,out:t};return{chunk:`\n#ifdef RENDERER_MOTION_VECTORS\n#ifdef USE_SKINNING\n let ${t} = rendererMotionPreviousClip(\n rendererSkinPosition(input.position, input.skinIndex, input.skinWeight),\n rendererPreviousSkinPosition(input.position, input.skinIndex, input.skinWeight),\n input.instanceIndex\n );\n#else\n let ${t} = rendererMotionPreviousClip(\n ${o},\n ${null==this.previousTransform?o:`((${i.get(this.previousTransform)}) * vec4<f32>(input.position, 1.0)).xyz`},\n input.instanceIndex\n );\n#endif\n#else\n let ${t} = vec4<f32>(0.0);\n#endif`,out:t}}}class r extends t{compile(i){if(!e(i)||n(i))throw new Error("Renderer motion parameters require a WGSL vertex graph.");const t=`rendererMotionParams${i.variable()}`;return{chunk:`\n#ifdef RENDERER_MOTION_VECTORS\n let ${t} = rendererMotionBlurParams(input.instanceIndex);\n#else\n let ${t} = vec4<f32>(0.0);\n#endif`,out:t}}}class s extends t{constructor(e,n){super(),this.currentClip=e,this.previousClip=n,this.motionParams=new r}compile(e){if(!n(e))throw new Error("Motion-vector output requires the WGSL fragment compiler.");const i=e.defineVarying("vec4",this.currentClip).out,t=e.defineVarying("vec4",this.previousClip).out,o=e.defineVarying("vec4",this.motionParams).out,r=e.variable(),s=`motionVector${r}`;return{chunk:`\n let motionSafeCurrentW${r} = select(${i}.w, 1.0, abs(${i}.w) < 1e-6);\n let motionSafePreviousW${r} = select(${t}.w, 1.0, abs(${t}.w) < 1e-6);\n let motionCurrentNdc${r} = ${i}.xy / motionSafeCurrentW${r};\n let motionPreviousNdc${r} = ${t}.xy / motionSafePreviousW${r};\n // Previous -> current velocity in UV units. WebGPU NDC is Y-up while\n // render-target UV is Y-down, hence the negative Y scale.\n var motionVelocityUv${r} =\n (motionCurrentNdc${r} - motionPreviousNdc${r}) * vec2<f32>(0.5, -0.5);\n let motionFinite${r} =\n all(motionVelocityUv${r} == motionVelocityUv${r}) &&\n all(abs(motionVelocityUv${r}) < vec2<f32>(65504.0));\n motionVelocityUv${r} =\n select(vec2<f32>(0.0), motionVelocityUv${r}, motionFinite${r});\n let motionMode${r} = clamp(${o}.x, 0.0, 3.0);\n let motionScale${r} = clamp(${o}.y, 0.0, 8.0);\n let ${s} = vec4<f32>(\n motionVelocityUv${r},\n motionMode${r},\n motionScale${r}\n );`,out:s}}}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{compileNodeWebGpuFullscreen as a,compileNodeShaderMaterialForWebGpu as t,NodeShaderMaterial as n,webGpuRendererBindings as i,textureSampler2d as s}from"three-shader-graph";import{StandardShader as o}from"../shader/builtin/standard-shader.js";import{LambertShader as r}from"../shader/builtin/lambert-shader.js";import{ToonShader as l}from"../shader/builtin/toon-shader.js";import{UnlitShader as u}from"../shader/builtin/unlit-shader.js";import{SpriteShader as p}from"../shader/sprite-shader.js";import{elapsedTimeUniformName as m}from"../shader-nodes/time.js";import{depthUniformName as c,farUniformName as h,nearUniformName as d,resolutionUniformName as f,sceneNormalUniformName as M}from"../shader-nodes/depth.js";import{sceneMapUniformName as v}from"../shader-nodes/scene-sample.js";const y={...i,uniformExpressions:{...i.uniformExpressions,[m]:{type:"float",expression:"rendererElapsedTime()"},[d]:{type:"float",expression:"rendererCameraNear()"},[h]:{type:"float",expression:"rendererCameraFar()"},[f]:{type:"vec2",expression:"rendererCamera.viewportAndTime.xy"}},sceneTextures:{[v]:{semantic:"sceneColor",sampleType:"float"},[c]:{semantic:"sceneDepth",sampleType:"depth"}},attributes:{material:{shaderLocation:6,format:"float32x4",defaultValue:[0,0,0,0]},material2:{shaderLocation:7,format:"float32x4",defaultValue:[0,0,0,0]},hole:{shaderLocation:8,format:"float32",defaultValue:[0]},offset:{shaderLocation:9,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},velocity:{shaderLocation:10,format:"float32x4",stepMode:"instance",defaultValue:[0,0,0,0]},size:{shaderLocation:11,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},rotation:{shaderLocation:12,format:"float32",stepMode:"instance",defaultValue:[0]},particleData:{shaderLocation:13,format:"float32x3",stepMode:"instance",defaultValue:[1,1,0]},particleColor:{shaderLocation:14,format:"float32x4",stepMode:"instance",defaultValue:[1,1,1,1]}}};export function setMaterialUniformValuesAutoUpdate(e,a){e.uniformValuesAutoUpdate=a}export function markMaterialUniformValuesNeedUpdate(e){const a=e;"uniformValuesNeedsUpdate"in a?a.uniformValuesNeedsUpdate=!0:a.uniformValuesAutoVersion=(a.uniformValuesAutoVersion??0)+1}function g(e){return!1!==e.uniformValuesAutoUpdate}function V(e){return e.uniformValuesAutoVersion??0}export function withThreeDefaultVertexAttributeValues(e){return e.map(e=>"uv1"===e.name&&null==e.defaultValue?{...e,defaultValue:[0,0]}:e)}const w=new WeakMap,I=new WeakMap;export function createNodeMaterialSignature(e){const a=I.get(e);if(null!=a)return a;const t=JSON.stringify({version:e.version,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,alphaTest:e.alphaTest,alphaToCoverage:e.alphaToCoverage,blending:e.blending,colorWrite:e.colorWrite,depthFunc:e.depthFunc,depthTest:e.depthTest,depthWrite:e.depthWrite,polygonOffset:e.polygonOffset,polygonOffsetFactor:e.polygonOffsetFactor,polygonOffsetUnits:e.polygonOffsetUnits,premultipliedAlpha:e.premultipliedAlpha,side:e.side,stencilWrite:e.stencilWrite,transparent:e.transparent,wireframe:e.wireframe});return I.set(e,t),t}export class NodeMaterialWebGpuResolver{constructor(e,a){this.webGpu=e,this.mrtResolver=a,this.cache=new WeakMap,this.failedSignatures=new WeakMap,this.mappedMaterialsCache=new WeakMap,this.mappedMaterialsSignatures=new WeakMap,this.observedNodeMaterials=new Map,this.worldEnvironmentMaterials=new WeakSet,this.worldEnvironment=null,this.worldEnvironmentTexture=null,this.worldEnvironmentIntensity=0,this.worldEnvironmentRevision=0,this.cacheValues=new Set}setWorldEnvironment(e){const a=e?.texture??null,t=e?.intensity??0;if(this.worldEnvironmentTexture!==a||this.worldEnvironmentIntensity!==t){if(this.worldEnvironmentTexture!==a)this.worldEnvironmentRevision++;else if(null!=e)for(const e of this.cacheValues)e.inheritsWorldEnvironment&&null!=e.material.uniforms.envMapIntensity&&(e.material.uniforms.envMapIntensity.value=t,e.material.uniformValuesNeedsUpdate=!0);this.worldEnvironment=e,this.worldEnvironmentTexture=a,this.worldEnvironmentIntensity=t}}resolve(e,a=void 0){let i,s=!1;if(e instanceof n)i=e,this.observeNodeMaterial(i);else{const a=this.getOrCreateMappedNodeMaterial(e);if(null==a)return;i=a,s=!0}i.visible=e.visible;const o=a??"default",r=this.cache.get(i),l=r?.get(o);if(s&&null!=l&&l.sourceVersion===e.version&&l.worldEnvironmentRevision===this.worldEnvironmentRevision){const a=g(e),t=V(e);return l.material.uniformValuesAutoUpdate=a,this.syncInheritedWorldEnvironmentSource(i,l),a||l.sourceUniformValuesAutoVersion!==t?(W(e,i),l.compiled.syncLiveUniforms(l.material.uniforms),x(i,l.material.uniforms),T(i,l.material),l.sourceUniformValuesAutoVersion=t,a||(l.material.uniformValuesNeedsUpdate=!0),l.material):l.material}if(!s&&null!=l&&l.sourceVersion===e.version&&l.worldEnvironmentRevision===this.worldEnvironmentRevision&&E(i,l.compiled))return this.syncInheritedWorldEnvironmentSource(i,l),S(i,l),l.material;s&&W(e,i);const u=this.prepareWorldEnvironment(i),p=this.getNodeMaterialSignature(i,u);if(l?.signature===p&&E(i,l.compiled))return s?(l.material.uniformValuesAutoUpdate=g(e),l.compiled.syncLiveUniforms(l.material.uniforms),x(i,l.material.uniforms),T(i,l.material),l.sourceUniformValuesAutoVersion=V(e),l.material.uniformValuesAutoUpdate||(l.material.uniformValuesNeedsUpdate=!0)):S(i,l,!0),l.sourceVersion=e.version,l.worldEnvironmentRevision=this.worldEnvironmentRevision,l.material;try{const n=this.mrtResolver?.(i,a),m=t(i,y,n),c=new this.webGpu.WGSLShaderMaterial({vertexShader:m.vertexShader,fragmentShader:m.fragmentShader,depthVertexShader:m.depthVertexShader,depthFragmentShader:m.depthFragmentShader,pointShadowVertexShader:m.pointShadowVertexShader,pointShadowFragmentShader:m.pointShadowFragmentShader,uniforms:m.uniforms,textures:m.textures,sceneTextures:m.sceneTextures,graphTextures:m.graphTextures,vertexAttributes:withThreeDefaultVertexAttributeValues(m.vertexAttributes),uniformValuesAutoUpdate:s?g(e):i.uniformValuesAutoUpdate,transparent:m.renderState?.transparent,alphaTest:m.renderState?.alphaTest,depthTest:m.renderState?.depthTest,depthWrite:m.renderState?.depthWrite,side:m.renderState?.side,wireframe:i.wireframe});c.uniformValuesAutoUpdate=s?g(e):i.uniformValuesAutoUpdate,function(e,a){if(null==e)return;Object.assign(a,e)}(m.renderState,c),null!=l&&(l.material.dispose(),this.cacheValues.delete(l));const h={signature:p,compiled:m,material:c,inheritsWorldEnvironment:u,sourceVersion:e.version,sourceUniformValuesAutoVersion:s?V(e):i.uniformValuesAutoVersion,worldEnvironmentRevision:this.worldEnvironmentRevision},d=r??new Map;return d.set(o,h),this.cache.set(i,d),this.cacheValues.add(h),x(i,c.uniforms),T(i,c),c}catch(e){let a=this.failedSignatures.get(i);if(null==a&&(a=new Map,this.failedSignatures.set(i,a)),a.get(o)!==p){a.set(o,p);const t=e instanceof Error?e.message:String(e),n=i.name||i.uuid;console.warn(`[Hology WebGPU experiment] Falling back for NodeShaderMaterial "${n}": ${t}`,{material:i,error:e})}return}}compileFullscreen(e){const t=a({color:e.outputColor,wgslBindings:{...y,uniformExpressions:{},graphTextures:{...y.graphTextures,[M]:{resource:"hologyNormalRoughness",dimension:"2d",sampleType:"float",sampler:"filtering"}}}}),n=t.syncLiveUniforms;return{...t,syncLiveUniforms(a){n(a),x(e,a)}}}getOrCreateMappedNodeMaterial(a){const t=function(a){const t=[a.vertexColors,a.transparent,a.alphaTest,a.side,a.depthTest,a.depthWrite,a.wireframe??!1];a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.roughnessMap?a.roughnessMap.uuid:null,a.metalnessMap?a.metalnessMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshLambertMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshToonMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.gradientMap?a.gradientMap.uuid:null):a instanceof e.MeshBasicMaterial?t.push(a.map?a.map.uuid:null,a.aoMap?a.aoMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshPhongMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.SpriteMaterial&&t.push(a.map?a.map.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.sizeAttenuation);return t.join(",")}(a),n=this.mappedMaterialsCache.get(a),i=this.mappedMaterialsSignatures.get(a);if(null!=n&&i===t)return n;if(null!=n){n.dispose();const e=this.cache.get(n);if(null!=e){for(const a of e.values())a.material.dispose(),this.cacheValues.delete(a);this.cache.delete(n)}}const m=function(a){if(a instanceof e.SpriteMaterial){const e=new p;e.color=a.color,e.opacity=a.opacity,e.rotation=a.rotation,e.screenSpaceSize=a.sizeAttenuation?0:1,e.alphaTest=a.alphaTest,a.map&&(e.map=a.map),a.alphaMap&&(e.alphaMap=a.alphaMap);const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t}if(a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial){const e=new o;e.color=a.color,e.opacity=a.opacity,e.roughness=a.roughness,e.metalness=a.metalness,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.roughnessMap&&(e.roughnessMap=s(a.roughnessMap)),a.metalnessMap&&(e.metalnessMap=s(a.metalnessMap)),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.envMapIntensity=a.envMapIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshLambertMaterial){const e=new r;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshToonMaterial){const e=new l;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial){const t=new u;t.color=a.color,t.opacity=a.opacity,t.vertexColor=a.vertexColors,a instanceof e.MeshBasicMaterial&&(a.map&&(t.map=s(a.map)),a.aoMap&&(t.aoMap=s(a.aoMap),t.aoMapIntensity=a.aoMapIntensity),a.lightMap&&(t.lightMap=s(a.lightMap),t.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(t.alphaMap=s(a.alphaMap)),t.envMap=a.envMap),t.alphaTest=a.alphaTest;const n=t.build();return n.transparent=a.transparent,n.side=a.side,n.depthTest=a.depthTest,n.depthWrite=a.depthWrite,n.wireframe=a instanceof e.MeshBasicMaterial&&a.wireframe,n}if(a instanceof e.MeshPhongMaterial){const e=new o;e.color=a.color,e.opacity=a.opacity,e.roughness=Math.max(0,1-a.shininess/100),e.metalness=0,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}return null}(a);return null==m?null:(m.wireframe=a.wireframe??!1,this.mappedMaterialsCache.set(a,m),this.mappedMaterialsSignatures.set(a,t),a.addEventListener("dispose",()=>{const e=this.mappedMaterialsCache.get(a);if(null!=e){e.dispose(),this.mappedMaterialsCache.delete(a),this.mappedMaterialsSignatures.delete(a);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}}}),m)}canResolve(e){return null!=this.resolve(e)}dispose(){for(const[e,a]of this.observedNodeMaterials)e.removeEventListener("dispose",a);this.observedNodeMaterials.clear();for(const e of this.cacheValues)e.material.dispose();this.cacheValues.clear()}syncInheritedWorldEnvironmentSource(e,a){a.inheritsWorldEnvironment&&null!=this.worldEnvironment&&(e.uniforms.envMap.value=this.worldEnvironment.texture,e.uniforms.envMapIntensity.value=this.worldEnvironment.intensity)}getNodeMaterialSignature(e,a){const t=createNodeMaterialSignature(e);return a?`${t}|worldEnvironment:${this.worldEnvironmentRevision}`:t}prepareWorldEnvironment(a){var t,n,i;return null!=a.envMap?(this.worldEnvironmentMaterials.has(a)&&(a.uniforms.envMap={value:a.envMap},a.uniforms.envMapIntensity={value:1},a.uniforms.envMapRotation={value:new e.Matrix3},this.worldEnvironmentMaterials.delete(a)),!1):null==this.worldEnvironment?(this.worldEnvironmentMaterials.has(a)&&(delete a.uniforms.envMap,delete a.uniforms.envMapIntensity,delete a.uniforms.envMapRotation,this.worldEnvironmentMaterials.delete(a)),!1):((t=a.uniforms).envMap??(t.envMap={value:this.worldEnvironment.texture}),a.uniforms.envMap.value=this.worldEnvironment.texture,(n=a.uniforms).envMapIntensity??(n.envMapIntensity={value:this.worldEnvironment.intensity}),a.uniforms.envMapIntensity.value=this.worldEnvironment.intensity,(i=a.uniforms).envMapRotation??(i.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.add(a),!0)}observeNodeMaterial(e){if(this.observedNodeMaterials.has(e))return;const a=()=>{e.removeEventListener("dispose",a),this.observedNodeMaterials.delete(e);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}this.failedSignatures.delete(e),I.delete(e)};this.observedNodeMaterials.set(e,a),e.addEventListener("dispose",a)}}function S(e,a,t=!1){const n=a.material;n.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,(t||e.uniformValuesAutoUpdate||a.sourceUniformValuesAutoVersion!==e.uniformValuesAutoVersion)&&(a.compiled.syncLiveUniforms(n.uniforms),x(e,n.uniforms),T(e,n),a.sourceUniformValuesAutoVersion=e.uniformValuesAutoVersion,n.uniformValuesAutoUpdate||(n.uniformValuesNeedsUpdate=!0))}function x(e,a){let t=w.get(a);if(null==t){t=[];for(const e in a){const n=a[e],i=n.value,s=!0===i?.isVector2?2:!0===i?.isVector3?3:!0===i?.isVector4?4:!0===i?.isColor?5:0;t.push({name:e,target:n,copyKind:s})}w.set(a,t)}const n=e.uniforms;for(let e=0;e<t.length;e++){const a=t[e],i=n[a.name];if(null==i)continue;const s=i.value,o=a.target.value;if(s!==o){if(0!==a.copyKind){const e=s,t=o;if((2===a.copyKind?!0===e?.isVector2:3===a.copyKind?!0===e?.isVector3:4===a.copyKind?!0===e?.isVector4:!0===e?.isColor)&&"function"==typeof t?.copy){t.copy(s);continue}}a.target.value=s}}}function T(a,t){const n=a.uniforms.envMapIntensity,i=t.uniforms.envMapIntensity;null!=n&&null!=i&&(i.value=n.value);const s=a.uniforms.envMapRotation?.value,o=t.uniforms.envMapRotation?.value;s instanceof e.Matrix3&&o instanceof e.Matrix3&&o.copy(s)}function E(e,a){for(const t in a.textures){const n=a.textures[t],i=e.uniforms[t]?.value;if(C(i)&&i!==n)return!1}return!0}function C(e){return!0===e?.isTexture}function W(a,t){if(a instanceof e.SpriteMaterial){const n=t;t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),n.rotation=a.rotation,n.screenSpaceSize=a.sizeAttenuation?0:1}else a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=a.roughness),t.uniforms.metalness&&(t.uniforms.metalness.value=a.metalness),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity),t.uniforms.envMapIntensity&&(t.uniforms.envMapIntensity.value=a.envMapIntensity)):a instanceof e.MeshLambertMaterial||a instanceof e.MeshToonMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity)):a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),a instanceof e.MeshBasicMaterial&&(t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))):a instanceof e.MeshPhongMaterial&&(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=Math.max(0,1-a.shininess/100)),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))}/*
1
+ import*as e from"three";import{compileNodeWebGpuFullscreen as a,compileNodeShaderMaterialForWebGpu as t,NodeShaderMaterial as n,webGpuRendererBindings as i,textureSampler2d as s}from"three-shader-graph";import{StandardShader as o}from"../shader/builtin/standard-shader.js";import{LambertShader as r}from"../shader/builtin/lambert-shader.js";import{ToonShader as l}from"../shader/builtin/toon-shader.js";import{UnlitShader as u}from"../shader/builtin/unlit-shader.js";import{SpriteShader as p}from"../shader/sprite-shader.js";import{elapsedTimeUniformName as m}from"../shader-nodes/time.js";import{depthUniformName as c,farUniformName as h,nearUniformName as d,resolutionUniformName as f,sceneNormalUniformName as M}from"../shader-nodes/depth.js";import{sceneMapUniformName as v}from"../shader-nodes/scene-sample.js";const y={...i,uniformExpressions:{...i.uniformExpressions,[m]:{type:"float",expression:"rendererElapsedTime()"},[d]:{type:"float",expression:"rendererCameraNear()"},[h]:{type:"float",expression:"rendererCameraFar()"},[f]:{type:"vec2",expression:"rendererCamera.viewportAndTime.xy"}},sceneTextures:{[v]:{semantic:"sceneColor",sampleType:"float"},[c]:{semantic:"sceneDepth",sampleType:"depth"}},attributes:{material:{shaderLocation:6,format:"float32x4",defaultValue:[0,0,0,0]},material2:{shaderLocation:7,format:"float32x4",defaultValue:[0,0,0,0]},hole:{shaderLocation:8,format:"float32",defaultValue:[0]},offset:{shaderLocation:9,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},velocity:{shaderLocation:10,format:"float32x4",stepMode:"instance",defaultValue:[0,0,0,0]},size:{shaderLocation:11,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},rotation:{shaderLocation:12,format:"float32",stepMode:"instance",defaultValue:[0]},particleData:{shaderLocation:13,format:"float32x3",stepMode:"instance",defaultValue:[1,1,0]},particleColor:{shaderLocation:14,format:"float32x4",stepMode:"instance",defaultValue:[1,1,1,1]}}};export function setMaterialUniformValuesAutoUpdate(e,a){e.uniformValuesAutoUpdate=a}export function markMaterialUniformValuesNeedUpdate(e){const a=e;"uniformValuesNeedsUpdate"in a?a.uniformValuesNeedsUpdate=!0:a.uniformValuesAutoVersion=(a.uniformValuesAutoVersion??0)+1}function g(e){return!1!==e.uniformValuesAutoUpdate}function V(e){return e.uniformValuesAutoVersion??0}export function withThreeDefaultVertexAttributeValues(e){return e.map(e=>"uv1"===e.name&&null==e.defaultValue?{...e,defaultValue:[0,0]}:e)}const w=new WeakMap,I=new WeakMap;export function createNodeMaterialSignature(e){const a=I.get(e);if(null!=a)return a;const t=JSON.stringify({version:e.version,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,alphaTest:e.alphaTest,alphaToCoverage:e.alphaToCoverage,blending:e.blending,colorWrite:e.colorWrite,depthFunc:e.depthFunc,depthTest:e.depthTest,depthWrite:e.depthWrite,polygonOffset:e.polygonOffset,polygonOffsetFactor:e.polygonOffsetFactor,polygonOffsetUnits:e.polygonOffsetUnits,premultipliedAlpha:e.premultipliedAlpha,side:e.side,stencilWrite:e.stencilWrite,transparent:e.transparent,wireframe:e.wireframe});return I.set(e,t),t}export class NodeMaterialWebGpuResolver{constructor(e,a){this.webGpu=e,this.mrtResolver=a,this.cache=new WeakMap,this.failedSignatures=new WeakMap,this.mappedMaterialsCache=new WeakMap,this.mappedMaterialsSignatures=new WeakMap,this.observedNodeMaterials=new Map,this.worldEnvironmentMaterials=new WeakSet,this.worldEnvironment=null,this.worldEnvironmentTexture=null,this.worldEnvironmentIntensity=0,this.worldEnvironmentRevision=0,this.cacheValues=new Set}setWorldEnvironment(e){const a=e?.texture??null,t=e?.intensity??0;if(this.worldEnvironmentTexture!==a||this.worldEnvironmentIntensity!==t){if(this.worldEnvironmentTexture!==a)this.worldEnvironmentRevision++;else if(null!=e)for(const e of this.cacheValues)e.inheritsWorldEnvironment&&null!=e.material.uniforms.envMapIntensity&&(e.material.uniforms.envMapIntensity.value=t,e.material.uniformValuesNeedsUpdate=!0);this.worldEnvironment=e,this.worldEnvironmentTexture=a,this.worldEnvironmentIntensity=t}}resolve(e,a=void 0){let i,s=!1;if(e instanceof n)i=e,this.observeNodeMaterial(i);else{const a=this.getOrCreateMappedNodeMaterial(e);if(null==a)return;i=a,s=!0}i.visible=e.visible,s&&(i.userData.receiveDecals=e.userData.receiveDecals);const o=a??"default",r=this.cache.get(i),l=r?.get(o);if(s&&null!=l&&l.sourceVersion===e.version&&l.worldEnvironmentRevision===this.worldEnvironmentRevision){const a=g(e),t=V(e);return l.material.uniformValuesAutoUpdate=a,this.syncInheritedWorldEnvironmentSource(i,l),a||l.sourceUniformValuesAutoVersion!==t?(W(e,i),l.compiled.syncLiveUniforms(l.material.uniforms),x(i,l.material.uniforms),T(i,l.material),l.sourceUniformValuesAutoVersion=t,a||(l.material.uniformValuesNeedsUpdate=!0),l.material):l.material}if(!s&&null!=l&&l.sourceVersion===e.version&&l.worldEnvironmentRevision===this.worldEnvironmentRevision&&E(i,l.compiled))return this.syncInheritedWorldEnvironmentSource(i,l),S(i,l),l.material;s&&W(e,i);const u=this.prepareWorldEnvironment(i),p=this.getNodeMaterialSignature(i,u);if(l?.signature===p&&E(i,l.compiled))return s?(l.material.uniformValuesAutoUpdate=g(e),l.compiled.syncLiveUniforms(l.material.uniforms),x(i,l.material.uniforms),T(i,l.material),l.sourceUniformValuesAutoVersion=V(e),l.material.uniformValuesAutoUpdate||(l.material.uniformValuesNeedsUpdate=!0)):S(i,l,!0),l.sourceVersion=e.version,l.worldEnvironmentRevision=this.worldEnvironmentRevision,l.material;try{const n=this.mrtResolver?.(i,a),m=t(i,y,n),c=new this.webGpu.WGSLShaderMaterial({vertexShader:m.vertexShader,fragmentShader:m.fragmentShader,depthVertexShader:m.depthVertexShader,depthFragmentShader:m.depthFragmentShader,pointShadowVertexShader:m.pointShadowVertexShader,pointShadowFragmentShader:m.pointShadowFragmentShader,uniforms:m.uniforms,textures:m.textures,sceneTextures:m.sceneTextures,graphTextures:m.graphTextures,vertexAttributes:withThreeDefaultVertexAttributeValues(m.vertexAttributes),uniformValuesAutoUpdate:s?g(e):i.uniformValuesAutoUpdate,transparent:m.renderState?.transparent,alphaTest:m.renderState?.alphaTest,depthTest:m.renderState?.depthTest,depthWrite:m.renderState?.depthWrite,side:m.renderState?.side,wireframe:i.wireframe});c.uniformValuesAutoUpdate=s?g(e):i.uniformValuesAutoUpdate,function(e,a){if(null==e)return;Object.assign(a,e)}(m.renderState,c),null!=l&&(l.material.dispose(),this.cacheValues.delete(l));const h={signature:p,compiled:m,material:c,inheritsWorldEnvironment:u,sourceVersion:e.version,sourceUniformValuesAutoVersion:s?V(e):i.uniformValuesAutoVersion,worldEnvironmentRevision:this.worldEnvironmentRevision},d=r??new Map;return d.set(o,h),this.cache.set(i,d),this.cacheValues.add(h),x(i,c.uniforms),T(i,c),c}catch(e){let a=this.failedSignatures.get(i);if(null==a&&(a=new Map,this.failedSignatures.set(i,a)),a.get(o)!==p){a.set(o,p);const t=e instanceof Error?e.message:String(e),n=i.name||i.uuid;console.warn(`[Hology WebGPU experiment] Falling back for NodeShaderMaterial "${n}": ${t}`,{material:i,error:e})}return}}compileFullscreen(e){const t=a({color:e.outputColor,wgslBindings:{...y,uniformExpressions:{},graphTextures:{...y.graphTextures,[M]:{resource:"hologyNormalRoughness",dimension:"2d",sampleType:"float",sampler:"filtering"}}}}),n=t.syncLiveUniforms;return{...t,syncLiveUniforms(a){n(a),x(e,a)}}}getOrCreateMappedNodeMaterial(a){const t=function(a){const t=[a.vertexColors,a.transparent,a.alphaTest,a.side,a.depthTest,a.depthWrite,a.wireframe??!1];a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.roughnessMap?a.roughnessMap.uuid:null,a.metalnessMap?a.metalnessMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshLambertMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshToonMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.gradientMap?a.gradientMap.uuid:null):a instanceof e.MeshBasicMaterial?t.push(a.map?a.map.uuid:null,a.aoMap?a.aoMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshPhongMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.SpriteMaterial&&t.push(a.map?a.map.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.sizeAttenuation);return t.join(",")}(a),n=this.mappedMaterialsCache.get(a),i=this.mappedMaterialsSignatures.get(a);if(null!=n&&i===t)return n;if(null!=n){n.dispose();const e=this.cache.get(n);if(null!=e){for(const a of e.values())a.material.dispose(),this.cacheValues.delete(a);this.cache.delete(n)}}const m=function(a){if(a instanceof e.SpriteMaterial){const e=new p;e.color=a.color,e.opacity=a.opacity,e.rotation=a.rotation,e.screenSpaceSize=a.sizeAttenuation?0:1,e.alphaTest=a.alphaTest,a.map&&(e.map=a.map),a.alphaMap&&(e.alphaMap=a.alphaMap);const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t}if(a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial){const e=new o;e.color=a.color,e.opacity=a.opacity,e.roughness=a.roughness,e.metalness=a.metalness,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.roughnessMap&&(e.roughnessMap=s(a.roughnessMap)),a.metalnessMap&&(e.metalnessMap=s(a.metalnessMap)),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.envMapIntensity=a.envMapIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshLambertMaterial){const e=new r;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshToonMaterial){const e=new l;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial){const t=new u;t.color=a.color,t.opacity=a.opacity,t.vertexColor=a.vertexColors,a instanceof e.MeshBasicMaterial&&(a.map&&(t.map=s(a.map)),a.aoMap&&(t.aoMap=s(a.aoMap),t.aoMapIntensity=a.aoMapIntensity),a.lightMap&&(t.lightMap=s(a.lightMap),t.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(t.alphaMap=s(a.alphaMap)),t.envMap=a.envMap),t.alphaTest=a.alphaTest;const n=t.build();return n.transparent=a.transparent,n.side=a.side,n.depthTest=a.depthTest,n.depthWrite=a.depthWrite,n.wireframe=a instanceof e.MeshBasicMaterial&&a.wireframe,n}if(a instanceof e.MeshPhongMaterial){const e=new o;e.color=a.color,e.opacity=a.opacity,e.roughness=Math.max(0,1-a.shininess/100),e.metalness=0,e.vertexColor=a.vertexColors,a.map&&(e.map=s(a.map)),a.normalMap&&(e.normalMap=s(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=s(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=s(a.emissiveMap)),a.lightMap&&(e.lightMap=s(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=s(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}return null}(a);return null==m?null:(m.wireframe=a.wireframe??!1,this.mappedMaterialsCache.set(a,m),this.mappedMaterialsSignatures.set(a,t),a.addEventListener("dispose",()=>{const e=this.mappedMaterialsCache.get(a);if(null!=e){e.dispose(),this.mappedMaterialsCache.delete(a),this.mappedMaterialsSignatures.delete(a);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}}}),m)}canResolve(e){return null!=this.resolve(e)}dispose(){for(const[e,a]of this.observedNodeMaterials)e.removeEventListener("dispose",a);this.observedNodeMaterials.clear();for(const e of this.cacheValues)e.material.dispose();this.cacheValues.clear()}syncInheritedWorldEnvironmentSource(e,a){a.inheritsWorldEnvironment&&null!=this.worldEnvironment&&(e.uniforms.envMap.value=this.worldEnvironment.texture,e.uniforms.envMapIntensity.value=this.worldEnvironment.intensity)}getNodeMaterialSignature(e,a){const t=`${createNodeMaterialSignature(e)}|receiveDecals:${!1!==e.userData.receiveDecals}`;return a?`${t}|worldEnvironment:${this.worldEnvironmentRevision}`:t}prepareWorldEnvironment(a){var t,n,i;return null!=a.envMap?(this.worldEnvironmentMaterials.has(a)&&(a.uniforms.envMap={value:a.envMap},a.uniforms.envMapIntensity={value:1},a.uniforms.envMapRotation={value:new e.Matrix3},this.worldEnvironmentMaterials.delete(a)),!1):null==this.worldEnvironment?(this.worldEnvironmentMaterials.has(a)&&(delete a.uniforms.envMap,delete a.uniforms.envMapIntensity,delete a.uniforms.envMapRotation,this.worldEnvironmentMaterials.delete(a)),!1):((t=a.uniforms).envMap??(t.envMap={value:this.worldEnvironment.texture}),a.uniforms.envMap.value=this.worldEnvironment.texture,(n=a.uniforms).envMapIntensity??(n.envMapIntensity={value:this.worldEnvironment.intensity}),a.uniforms.envMapIntensity.value=this.worldEnvironment.intensity,(i=a.uniforms).envMapRotation??(i.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.add(a),!0)}observeNodeMaterial(e){if(this.observedNodeMaterials.has(e))return;const a=()=>{e.removeEventListener("dispose",a),this.observedNodeMaterials.delete(e);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}this.failedSignatures.delete(e),I.delete(e)};this.observedNodeMaterials.set(e,a),e.addEventListener("dispose",a)}}function S(e,a,t=!1){const n=a.material;n.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,(t||e.uniformValuesAutoUpdate||a.sourceUniformValuesAutoVersion!==e.uniformValuesAutoVersion)&&(a.compiled.syncLiveUniforms(n.uniforms),x(e,n.uniforms),T(e,n),a.sourceUniformValuesAutoVersion=e.uniformValuesAutoVersion,n.uniformValuesAutoUpdate||(n.uniformValuesNeedsUpdate=!0))}function x(e,a){let t=w.get(a);if(null==t){t=[];for(const e in a){const n=a[e],i=n.value,s=!0===i?.isVector2?2:!0===i?.isVector3?3:!0===i?.isVector4?4:!0===i?.isColor?5:0;t.push({name:e,target:n,copyKind:s})}w.set(a,t)}const n=e.uniforms;for(let e=0;e<t.length;e++){const a=t[e],i=n[a.name];if(null==i)continue;const s=i.value,o=a.target.value;if(s!==o){if(0!==a.copyKind){const e=s,t=o;if((2===a.copyKind?!0===e?.isVector2:3===a.copyKind?!0===e?.isVector3:4===a.copyKind?!0===e?.isVector4:!0===e?.isColor)&&"function"==typeof t?.copy){t.copy(s);continue}}a.target.value=s}}}function T(a,t){const n=a.uniforms.envMapIntensity,i=t.uniforms.envMapIntensity;null!=n&&null!=i&&(i.value=n.value);const s=a.uniforms.envMapRotation?.value,o=t.uniforms.envMapRotation?.value;s instanceof e.Matrix3&&o instanceof e.Matrix3&&o.copy(s)}function E(e,a){for(const t in a.textures){const n=a.textures[t],i=e.uniforms[t]?.value;if(C(i)&&i!==n)return!1}return!0}function C(e){return!0===e?.isTexture}function W(a,t){if(a instanceof e.SpriteMaterial){const n=t;t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),n.rotation=a.rotation,n.screenSpaceSize=a.sizeAttenuation?0:1}else a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=a.roughness),t.uniforms.metalness&&(t.uniforms.metalness.value=a.metalness),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity),t.uniforms.envMapIntensity&&(t.uniforms.envMapIntensity.value=a.envMapIntensity)):a instanceof e.MeshLambertMaterial||a instanceof e.MeshToonMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity)):a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),a instanceof e.MeshBasicMaterial&&(t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))):a instanceof e.MeshPhongMaterial&&(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=Math.max(0,1-a.shininess/100)),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -2,11 +2,18 @@ import * as THREE from 'three';
2
2
  import { NodeMaterialWebGpuResolver } from './node-material-webgpu-resolver.js';
3
3
  import type { WorldEnvironmentState } from './environment.js';
4
4
  import type { PostProcessEffectStage } from './post-process-effect.js';
5
- import type { BloomOptions, ColorGradingOptions, DepthOfFieldOptions, FXAAOptions, GTAOOptions, OutlineOptions, OutlineInstanceSelection, SSROptions, RendererFrameProfile, SMAAOptions, TemporalAAOptions, VolumetricFogOptions } from '@hology/webgpu-renderer';
6
- export type { RendererFrameProfile } from '@hology/webgpu-renderer';
5
+ import type { BloomOptions, ColorGradingOptions, DepthOfFieldOptions, FXAAOptions, GTAOOptions, GTAOQuality, OutlineOptions, OutlineInstanceSelection, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, SSROptions, RendererFrameProfile, SMAAOptions, TemporalAAOptions, VolumetricFogOptions, VolumetricFogQuality } from '@hology/webgpu-renderer';
6
+ export type { RendererFrameProfile, GTAOOptions, GTAOQuality, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, VolumetricFogOptions, VolumetricFogQuality } from '@hology/webgpu-renderer';
7
7
  type SupportedCamera = THREE.PerspectiveCamera | THREE.OrthographicCamera;
8
+ export type AntiAliasingMode = 'off' | 'fxaa' | 'smaa' | 'taa';
8
9
  export interface ExperimentalWebGpuPostProcessingOptions {
9
10
  readonly bloom?: false | BloomOptions;
11
+ /**
12
+ * Selects one mutually exclusive antialiasing method. When present, all
13
+ * variants are kept available for inexpensive runtime switching.
14
+ * Defaults to the legacy behavior (TAA unless explicitly disabled/replaced).
15
+ */
16
+ readonly antiAliasing?: AntiAliasingMode;
10
17
  /** Optional low-cost, stateless antialiasing pass. Enable with `fxaa: {}`. */
11
18
  readonly fxaa?: false | FXAAOptions;
12
19
  /**
@@ -18,6 +25,8 @@ export interface ExperimentalWebGpuPostProcessingOptions {
18
25
  /** Screen-space reflections using the opaque color, depth, normal and roughness buffers. */
19
26
  readonly ssr?: false | SSROptions;
20
27
  readonly taa?: false | TemporalAAOptions;
28
+ /** HDR motion blur using opaque MRT velocity. Disabled by default. */
29
+ readonly motionBlur?: false | MotionBlurOptions;
21
30
  /** Compute-driven froxel fog. Existing FogVolume actors are discovered automatically. */
22
31
  readonly volumetricFog?: false | VolumetricFogOptions;
23
32
  /** Final HDR color grading and tone mapping. PostProcessVolumes update it at runtime. */
@@ -70,12 +79,15 @@ export declare class ExperimentalWebGpuBackend {
70
79
  private readonly gtao;
71
80
  private readonly ssr;
72
81
  private readonly taa;
82
+ private readonly motionBlur;
73
83
  private readonly volumetricFog;
74
84
  private readonly colorGrading;
75
85
  private readonly depthOfField;
76
86
  private readonly outline;
77
87
  private readonly postProcessEffects;
88
+ private readonly antiAliasingState;
78
89
  readonly canvas: HTMLCanvasElement;
90
+ private renderScale;
79
91
  private pmremGenerator;
80
92
  private readonly pmremResults;
81
93
  private readonly ownedPmremResults;
@@ -83,7 +95,7 @@ export declare class ExperimentalWebGpuBackend {
83
95
  private constructor();
84
96
  static create(postProcessing?: ExperimentalWebGpuPostProcessingOptions): Promise<ExperimentalWebGpuBackend>;
85
97
  static supportsCamera(camera: THREE.Camera): camera is SupportedCamera;
86
- setSize(width: number, height: number, pixelRatio: number): void;
98
+ setSize(width: number, height: number, presentationPixelRatio: number, renderScale?: number): void;
87
99
  initTexture(texture: THREE.Texture): void;
88
100
  setPostProcessEffects(effects: readonly ExperimentalWebGpuPostProcessEffect[]): void;
89
101
  setEnableOutlines(enabled: boolean): void;
@@ -103,6 +115,14 @@ export declare class ExperimentalWebGpuBackend {
103
115
  compile(scene: THREE.Scene, camera: SupportedCamera): Promise<void>;
104
116
  createStaticDrawSet(root: THREE.Object3D, label: string): ExperimentalWebGpuStaticDrawSet | null;
105
117
  render(scene: THREE.Scene, camera: SupportedCamera, timeSeconds: number): void;
118
+ setMotionBlurOptions(options: MotionBlurOptions): void;
119
+ setGTAOOptions(options: GTAOOptions): void;
120
+ setAntiAliasingMode(mode: AntiAliasingMode): void;
121
+ setGTAOQuality(quality: GTAOQuality): void;
122
+ setVolumetricFogOptions(options: VolumetricFogOptions): void;
123
+ setVolumetricFogQuality(quality: VolumetricFogQuality): void;
124
+ pushMotionBlurOverride(override: MotionBlurOverride): MotionBlurOverrideHandle | null;
125
+ invalidateObjectMotion(object: THREE.Object3D): void;
106
126
  getLastFrameProfile(): RendererFrameProfile | null;
107
127
  setPostProcessState(state: ExperimentalWebGpuPostProcessState | null): void;
108
128
  setProfilingEnabled(enabled: boolean): void;
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{NodeMaterialWebGpuResolver as t}from"./node-material-webgpu-resolver.js";import{float as n,varyingTransformed as i,vec4 as r}from"three-shader-graph";import{NodeShaderMaterial as o}from"../shader-nodes/index.js";import{sceneMapUniformName as s}from"../shader-nodes/scene-sample.js";export class ExperimentalWebGpuBackend{constructor(e,t,n,i,r,o,s,a,l,d,c,u,h,p,m,g){this.renderer=e,this.fallbackMaterial=t,this.nodeMaterialResolver=n,this.gBufferFallbackSource=i,this.bloom=r,this.fxaa=o,this.smaa=s,this.gtao=a,this.ssr=l,this.taa=d,this.volumetricFog=c,this.colorGrading=u,this.depthOfField=h,this.outline=p,this.postProcessEffects=m,this.pmremGenerator=null,this.pmremResults=new WeakMap,this.ownedPmremResults=new Set,this.warnedUnsupportedPostProcessStages=new Set,this.canvas=g}static async create(d={}){const c=await import("@hology/webgpu-renderer"),u=document.createElement("canvas");u.dataset.hologyRenderer="webgpu-experimental";const h=new c.WGSLShaderMaterial({vertexShader:a,fragmentShader:l});h.side=c.DoubleSide;const p=new t(c,(e,t)=>"opaque"===t?[e.outputColor.xyz.rgba(e.alphaTest),r((e.outputNormal??i.normal).multiplyScalar(.5).addScalar(.5),e.outputRoughness??n(1))]:void 0),m=new e.MeshStandardMaterial({color:8688803,roughness:1});if(null==p.resolve(m,"opaque"))throw h.dispose(),m.dispose(),new Error("Failed to compile the WebGPU G-buffer fallback material.");const g=!1===d.gtao?null:new c.GTAOEffect({normalSpace:"view",resolutionScale:.5,...d.gtao??{}}),f=!1===d.ssr||null==d.ssr?null:new c.SSREffect({normalSpace:"view",resolutionScale:.5,...d.ssr??{}}),P=!1===d.bloom?null:new c.BloomEffect({threshold:1,strength:.9,radius:.2,...d.bloom??{}}),S=!1===d.fxaa||null==d.fxaa?null:new c.FXAAEffect(d.fxaa),x=!1===d.smaa||null==d.smaa?null:new c.SMAAEffect(d.smaa),w=!1===d.taa||null!=d.smaa&&!1!==d.smaa&&null==d.taa?null:new c.TemporalAAEffect({renderScale:.9,...d.taa??{}}),b=d.volumetricFog||void 0,v=!1===d.volumetricFog?null:new c.VolumetricFogEffect(void 0,{froxelPixelSize:8,maxDistance:64,depthSlices:64,integrationSubsteps:2,temporalJitter:!0,spatialJitter:!0,scatteringIntensity:Math.PI,...b,blur:!1!==b?.blur&&{depthAwareUpsample:!0,...b?.blur}}),C=!1===d.colorGrading?null:new c.ColorGradingEffect({enabled:!1,...d.colorGrading??{}}),L=!1===d.depthOfField?null:new c.DepthOfFieldEffect({enabled:!1,...d.depthOfField??{}}),y=!1===d.outline?null:new c.OutlineEffect({enabled:!1,...d.outline??{}}),F=[],M=new WeakMap,G=new Set,O=(e,t,n)=>{let i=n;const r=F.filter(e=>e.enabled&&e.stage===t).sort((e,t)=>e.priority-t.priority||e.id-t.id);for(const t of r){if(!(t.material instanceof o)){const e=`${t.id}:material`;G.has(e)||(G.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: only NodeShaderMaterial effects are supported.`));continue}try{let n=M.get(t.material);null!=n&&n.version===t.material.version||(n={version:t.material.version,shader:p.compileFullscreen(t.material)},M.set(t.material,n));const r=e.createColorTarget(`hologyCustomPostProcess${t.id}`);e.addNodeFullscreenPass({name:`HologyCustomPostProcess${t.id}`,shader:n.shader,inputOverrides:{[s]:i},outputs:r}),i=r}catch(e){const n=`${t.id}:compile:${t.material.version}`;G.has(n)||(G.add(n),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: ${e instanceof Error?e.message:String(e)}`,e))}}return i},R=new c.WebGpuRenderer({canvas:u,fallbackMaterial:h,materialResolver:(e,t)=>p.resolve(e,t),invokeObjectRenderCallbacks:!1,hiZOcclusionCulling:!0,renderGraphProfiling:!1,sampleCount:1,multiDrawIndirect:!1});R.setRenderScale(w?.renderScale??1),R.setRenderGraphBuilder((e,t)=>{const n=new c.FrameGraphBuilder(t),i=n.createColorTarget("hologyNormalRoughness",{format:"rgba16float"});n.addDirectionalShadowPass(),n.addPointShadowPass(),n.addSpotShadowPass(),n.addDepthPrepass(),n.addHiZPasses(),n.addVisibilityPass(),n.addMaterialPass({name:"OpaqueGBufferPass",outputs:[n.sceneColor,i],drawStage:"opaque",loadDepth:!0}),n.addHiZHistoryPass("OpaqueGBufferPass");let r=n.sceneColor;if(null!=g){const e=g.addPasses(n,{depth:n.mainDepth,normal:i});r=g.addCompositePass(n,r,e)}null!=f&&(r=f.addPasses(n,{sceneColor:r,depth:n.mainDepth,normalRoughness:i})),n.addSceneTextureCopyPass(r),n.addLatePass(r),r=O(n,"beforeFog",r),null!=v&&(r=v.addPasses(n,{sceneColor:r,depth:n.mainDepth,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=P&&(r=P.addPass(n,r)),r=O(n,"beforeOutline",r),null!=y&&(r=y.addPass(n,r)),r=O(n,"beforeDepthOfField",r),null!=L&&(r=L.addPass(n,r,n.mainDepth)),r=O(n,"beforeColorAdjustment",r),null!=C&&(r=C.addPass(n,r)),r=O(n,"beforeAntiAliasing",r);let o=w?.addPass(n,r,n.mainDepth)??r;null!=x?o=x.addPass(n,o):null!=S&&(o=S.addPass(n,o)),o=O(n,"beforeOutput",o),n.present(o)});try{return await R.initialize(),new ExperimentalWebGpuBackend(R,h,p,m,P,S,x,g,f,w,v,C,L,y,F,u)}catch(e){throw R.destroy(),h.dispose(),p.dispose(),m.dispose(),g?.dispose(),x?.dispose(),v?.dispose(),y?.dispose(),e}}static supportsCamera(t){return t instanceof e.PerspectiveCamera||t instanceof e.OrthographicCamera}setSize(e,t,n){this.renderer.setSize(e,t,n)}initTexture(e){this.renderer.initTexture(e)}setPostProcessEffects(e){this.postProcessEffects.splice(0,this.postProcessEffects.length,...e);for(const t of e){if("beforeLut"!==t.stage)continue;const e=`${t.id}:${t.stage}`;this.warnedUnsupportedPostProcessStages.has(e)||(this.warnedUnsupportedPostProcessStages.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: stage "${t.stage}" has no native WebGPU anchor.`))}}setEnableOutlines(e){null!=this.outline&&(this.outline.enabled=e)}setDynamicBatchingEnabled(e){this.renderer.setDynamicBatchingEnabled(e)}setSelectedObjects(e){this.outline?.setSelectedObjects(e)}setSelectedObjectInstances(e){this.outline?.setSelectedInstances(e)}setCascadedShadowRanges(e,t=[]){this.renderer.setCascadedShadowRanges(e,t),this.volumetricFog?.setCascadedDirectionalLights(t)}setWorldEnvironment(t){if(null==t)return void this.nodeMaterialResolver.setWorldEnvironment(null);let n=t.source;if(n.mapping!==e.CubeUVReflectionMapping){let e=this.pmremResults.get(n);null==e&&(this.pmremGenerator??(this.pmremGenerator=this.renderer.createPMREMGenerator()),e=this.pmremGenerator.fromEquirectangular(n),this.pmremResults.set(n,e),this.ownedPmremResults.add(e)),n=e.texture}this.nodeMaterialResolver.setWorldEnvironment({texture:n,intensity:t.intensity})}resetViewHistory(){this.renderer.resetViewHistory(),this.taa?.reset()}async compile(e,t){await this.renderer.compileAsync(e,t)}createStaticDrawSet(e,t){this.renderer.setHiZOcclusionCullingEnabled(!0);const n=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:"skip"});return 0===n.drawCount?(n.dispose(),null):n}render(e,t,n){this.volumetricFog?.setScene(e),this.taa?.prepareCamera(t,this.canvas.width,this.canvas.height);try{this.renderer.render(e,t,n)}finally{this.taa?.finishCamera(t)}}getLastFrameProfile(){return this.renderer.getLastFrameProfile()}setPostProcessState(e){null!=this.colorGrading&&(Object.assign(this.colorGrading.options,e??{enabled:!1}),this.colorGrading.options.enabled=!0===e?.enabled),null!=this.depthOfField&&(this.depthOfField.options.enabled=null!=e?.depthFocus||null!=e?.depthAperture||null!=e?.depthMaxBlur,this.depthOfField.options.focus=e?.depthFocus,this.depthOfField.options.aperture=e?.depthAperture,this.depthOfField.options.maxBlur=e?.depthMaxBlur)}setProfilingEnabled(e){this.renderer.setRenderGraphProfilingEnabled(e)}resetTemporalHistory(){this.taa?.reset()}inspect(e,t){return inspectWebGpuScene(e,t,this.nodeMaterialResolver)}destroy(){this.nodeMaterialResolver.dispose(),this.gBufferFallbackSource.dispose(),this.gtao?.dispose(),this.smaa?.dispose(),this.volumetricFog?.dispose();for(const e of this.ownedPmremResults)e.dispose();this.ownedPmremResults.clear(),this.renderer.destroy(),this.fallbackMaterial.dispose()}}export function inspectWebGpuScene(e,t,n){const i={meshes:0,skinnedMeshes:0,instancedMeshes:0,batchedMeshes:0,sprites:0,points:0,lines:0,missingPositionGeometry:0,transparentMaterials:0,shaderMaterialsReplaced:0,materialsReplaced:0,unsupportedCamera:ExperimentalWebGpuBackend.supportsCamera(t)?0:1};return e.traverse(e=>{if(e.isSprite)return void i.sprites++;if(e.isPoints)return void i.points++;if(e.isLine)return void i.lines++;if(!e.isMesh)return;const t=e;t.isBatchedMesh?i.batchedMeshes++:t.isInstancedMesh?i.instancedMeshes++:t.isSkinnedMesh?i.skinnedMeshes++:i.meshes++,null==t.geometry?.getAttribute("position")&&i.missingPositionGeometry++;const r=Array.isArray(t.material)?t.material:[t.material];for(const e of r){if(null==e)continue;e.transparent&&i.transparentMaterials++;const t=!0===e.isWGSLShaderMaterial||!0===e.isLineMaterial,r=!t&&!0===n?.canResolve(e);t||r||(i.materialsReplaced++,e.isShaderMaterial&&i.shaderMaterialsReplaced++)}}),i}export function formatWebGpuSceneCapabilitySummary(e){return`[Hology WebGPU experiment] ${JSON.stringify(e)}`}const a="\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) color: vec4<f32>,\n#ifdef USE_SKINNING\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n#endif\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n#ifdef USE_SKINNING\n let localPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let localNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let localPosition = input.position;\n let localNormal = input.normal;\n#endif\n let world = rendererWorldPosition(localPosition, input.instanceIndex);\n output.position = rendererClipPosition(localPosition, input.instanceIndex);\n output.worldPosition = world.xyz;\n output.worldNormal = rendererWorldNormal(localNormal, input.instanceIndex);\n output.color = input.color * rendererObjectColor(input.instanceIndex);\n return output;\n}\n",l="\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\nfn distanceAttenuation(distanceToLight: f32, range: f32) -> f32 {\n let linear = max(0.0, 1.0 - distanceToLight / max(range, 0.001));\n return linear * linear;\n}\n\n@fragment\nfn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n let normal = normalize(input.worldNormal);\n let normalTint = normal * 0.5 + vec3<f32>(0.5);\n let base = mix(vec3<f32>(0.52, 0.58, 0.64), normalTint, 0.22) * input.color.rgb;\n var lighting = rendererIndirectDiffuse(normal) + vec3<f32>(0.08);\n var directionalLighting = vec3<f32>(0.0);\n let directionalCount = rendererDirectionalLightCount();\n\n for (var index: u32 = 0u; index < directionalCount; index = index + 1u) {\n let lightDirection = rendererDirectionalLightDirectionForLight(index);\n let shadow = rendererSampleDirectionalShadowForLightWithNormal(index, input.worldPosition, normal);\n directionalLighting += rendererDirectionalLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * shadow;\n }\n if (directionalCount > 0u) {\n lighting += directionalLighting / f32(directionalCount);\n }\n\n for (var index: u32 = 0u; index < rendererPointLightCount(); index = index + 1u) {\n let lightVector = rendererPointLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let shadow = rendererSamplePointShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererPointLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * distanceAttenuation(distanceToLight, rendererPointLightRangeForLight(index)) * shadow;\n }\n\n for (var index: u32 = 0u; index < rendererSpotLightCount(); index = index + 1u) {\n let lightVector = rendererSpotLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let angleCos = dot(-lightDirection, rendererSpotLightDirectionForLight(index));\n let cone = smoothstep(rendererSpotLightConeCosForLight(index), rendererSpotLightPenumbraCosForLight(index), angleCos);\n let shadow = rendererSampleSpotShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererSpotLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * cone * distanceAttenuation(distanceToLight, rendererSpotLightRangeForLight(index)) * shadow;\n }\n\n return vec4<f32>(base * max(lighting, vec3<f32>(0.08)), input.color.a);\n}\n";/*
1
+ import*as e from"three";import{NodeMaterialWebGpuResolver as t}from"./node-material-webgpu-resolver.js";import{float as i,varyingTransformed as n,vec4 as r}from"three-shader-graph";import{NodeShaderMaterial as o}from"../shader-nodes/index.js";import{sceneMapUniformName as s}from"../shader-nodes/scene-sample.js";import{MATERIAL_FLAG_ALPHA_TEST as a,MATERIAL_FLAG_RECEIVE_DECALS as l}from"../shader-nodes/material-flags.js";import{createMotionVectorOutput as d}from"./motion-vector-node.js";export class ExperimentalWebGpuBackend{constructor(e,t,i,n,r,o,s,a,l,d,c,h,u,p,m,g,f,v){this.renderer=e,this.fallbackMaterial=t,this.nodeMaterialResolver=i,this.gBufferFallbackSource=n,this.bloom=r,this.fxaa=o,this.smaa=s,this.gtao=a,this.ssr=l,this.taa=d,this.motionBlur=c,this.volumetricFog=h,this.colorGrading=u,this.depthOfField=p,this.outline=m,this.postProcessEffects=g,this.antiAliasingState=f,this.renderScale=1,this.pmremGenerator=null,this.pmremResults=new WeakMap,this.ownedPmremResults=new Set,this.warnedUnsupportedPostProcessStages=new Set,this.canvas=v}static async create(u={}){const p=await import("@hology/webgpu-renderer"),m=document.createElement("canvas");m.dataset.hologyRenderer="webgpu-experimental";const g=new p.WGSLShaderMaterial({vertexShader:c,fragmentShader:h});g.side=p.DoubleSide;const f=p,v=null!=u.motionBlur&&!1!==u.motionBlur,S=!1!==u.gtao&&(null==u.gtao||!1!==u.gtao.temporal),P=!1!==u.volumetricFog&&(null==u.volumetricFog||!1!==u.volumetricFog.temporal),w=null!=(x=u).antiAliasing?x.antiAliasing:null!=x.taa&&!1!==x.taa?"taa":null!=x.smaa&&!1!==x.smaa?"smaa":null!=x.fxaa&&!1!==x.fxaa?"fxaa":!1===x.taa?"off":"taa";var x;const b=null!=u.antiAliasing,y=v||S||P||(b||"taa"===w),F=new t(f,(e,t)=>"opaque"===t?[e.outputColor.xyz.rgba(i(e.alphaTest>0?a:0).add(!1===e.userData.receiveDecals?0:l)),r((e.outputNormal??n.normal).multiplyScalar(.5).addScalar(.5),e.outputRoughness??i(1)),...y?[d(e)]:[]]:void 0),M=new e.MeshStandardMaterial({color:8688803,roughness:1});if(null==F.resolve(M,"opaque"))throw g.dispose(),M.dispose(),new Error("Failed to compile the WebGPU G-buffer fallback material.");const O=!1===u.gtao?null:new p.GTAOEffect({normalSpace:"view",...p.GTAO_PRESETS.high,...u.gtao??{}}),C=!1===u.ssr||null==u.ssr?null:new p.SSREffect({normalSpace:"view",resolutionScale:.5,...u.ssr??{}}),L=!1===u.bloom?null:new p.BloomEffect({threshold:1,strength:.9,radius:.2,...u.bloom??{}}),E=b||!1!==u.fxaa&&"fxaa"===w?new p.FXAAEffect(!1===u.fxaa?{}:u.fxaa):null,G=b||!1!==u.smaa&&"smaa"===w?new p.SMAAEffect(!1===u.smaa?{}:u.smaa):null,R=b||!1!==u.taa&&"taa"===w?new p.TemporalAAEffect({renderScale:1,...!1===u.taa?{}:u.taa}):null,B={mode:w},D=!1===u.motionBlur||null==u.motionBlur?null:new p.MotionBlurEffect(u.motionBlur),A=u.volumetricFog||void 0,T=!1===u.volumetricFog?null:new p.VolumetricFogEffect(void 0,{...p.VOLUMETRIC_FOG_PRESETS.high,maxDistance:64,spatialJitter:!0,scatteringIntensity:Math.PI,...A,temporal:!1!==A?.temporal&&{...p.VOLUMETRIC_FOG_PRESETS.high.temporal,...A?.temporal},blur:!1!==A?.blur&&{...!1===p.VOLUMETRIC_FOG_PRESETS.high.blur?{}:p.VOLUMETRIC_FOG_PRESETS.high.blur,depthAwareUpsample:!0,...A?.blur}}),V=!1===u.colorGrading?null:new p.ColorGradingEffect({enabled:!1,...u.colorGrading??{}}),W=!1===u.depthOfField?null:new p.DepthOfFieldEffect({enabled:!1,...u.depthOfField??{}}),k=!1===u.outline?null:new p.OutlineEffect({enabled:!1,...u.outline??{}}),I=[],N=new WeakMap,U=new Set,j=(e,t,i)=>{let n=i;const r=I.filter(e=>e.enabled&&e.stage===t).sort((e,t)=>e.priority-t.priority||e.id-t.id);for(const t of r){if(!(t.material instanceof o)){const e=`${t.id}:material`;U.has(e)||(U.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: only NodeShaderMaterial effects are supported.`));continue}try{let i=N.get(t.material);null!=i&&i.version===t.material.version||(i={version:t.material.version,shader:F.compileFullscreen(t.material)},N.set(t.material,i));const r=e.createColorTarget(`hologyCustomPostProcess${t.id}`);e.addNodeFullscreenPass({name:`HologyCustomPostProcess${t.id}`,shader:i.shader,inputOverrides:{[s]:n},outputs:r}),n=r}catch(e){const i=`${t.id}:compile:${t.material.version}`;U.has(i)||(U.add(i),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: ${e instanceof Error?e.message:String(e)}`,e))}}return n},H=new p.WebGpuRenderer({canvas:m,fallbackMaterial:g,materialResolver:(e,t)=>F.resolve(e,t),invokeObjectRenderCallbacks:!1,hiZOcclusionCulling:!0,renderGraphProfiling:!1,sampleCount:1,multiDrawIndirect:!1});H.setRenderScale("taa"===w?R?.renderScale??1:1),H.setRenderGraphBuilder((e,t)=>{const i=new p.FrameGraphBuilder(t),n=i.createColorTarget("hologyNormalRoughness",{format:"rgba16float"}),r=y?i.createColorTarget("hologyMotionVectors",{format:"rgba16float"}):null;i.addDirectionalShadowPass(),i.addPointShadowPass(),i.addSpotShadowPass(),i.addDepthPrepass(),i.addHiZPasses(),i.addVisibilityPass(),i.addMaterialPass({name:"OpaqueGBufferPass",outputs:null==r?[i.sceneColor,n]:[i.sceneColor,n,r],drawStage:"opaque",loadDepth:!0}),i.addHiZHistoryPass("OpaqueGBufferPass");let o=i.sceneColor;if(O?.enabled){const e=O.addPasses(i,{depth:i.mainDepth,normal:n,velocity:r??void 0});o=O.addCompositePass(i,o,e)}null!=C&&(o=C.addPasses(i,{sceneColor:o,depth:i.mainDepth,normalRoughness:n})),i.addSceneTextureCopyPass(o),i.addLatePass(o),o=j(i,"beforeFog",o),null!=T&&(o=T.addPasses(i,{sceneColor:o,depth:i.mainDepth,velocity:r??void 0,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=D&&null!=r&&(o=D.addPass(i,o,r,i.mainDepth)),null!=L&&(o=L.addPass(i,o)),o=j(i,"beforeOutline",o),null!=k&&(o=k.addPass(i,o)),o=j(i,"beforeDepthOfField",o),null!=W&&(o=W.addPass(i,o,i.mainDepth)),o=j(i,"beforeColorAdjustment",o),null!=V&&(o=V.addPass(i,o)),o=j(i,"beforeAntiAliasing",o);let s="taa"===B.mode&&null!=R?R.addPass(i,o,i.mainDepth,r??void 0):o;"smaa"===B.mode&&null!=G?s=G.addPass(i,s):"fxaa"===B.mode&&null!=E&&(s=E.addPass(i,s)),s=j(i,"beforeOutput",s),i.present(s)});try{return await H.initialize(),new ExperimentalWebGpuBackend(H,g,F,M,L,E,G,O,C,R,D,T,V,W,k,I,B,m)}catch(e){throw H.destroy(),g.dispose(),F.dispose(),M.dispose(),O?.dispose(),G?.dispose(),D?.dispose(),T?.dispose(),k?.dispose(),e}}static supportsCamera(t){return t instanceof e.PerspectiveCamera||t instanceof e.OrthographicCamera}setSize(e,t,i,n=1){const r=this.canvas.width,o=this.canvas.height,s=Math.min(1,Math.max(.25,n)),a=s!==this.renderScale;this.renderScale=s,this.renderer.setRenderScale(s),this.taa?.setRenderScale(s),this.renderer.setSize(e,t,i),(a||this.canvas.width!==r||this.canvas.height!==o)&&this.resetViewHistory()}initTexture(e){this.renderer.initTexture(e)}setPostProcessEffects(e){this.postProcessEffects.splice(0,this.postProcessEffects.length,...e);for(const t of e){if("beforeLut"!==t.stage)continue;const e=`${t.id}:${t.stage}`;this.warnedUnsupportedPostProcessStages.has(e)||(this.warnedUnsupportedPostProcessStages.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: stage "${t.stage}" has no native WebGPU anchor.`))}}setEnableOutlines(e){null!=this.outline&&(this.outline.enabled=e)}setDynamicBatchingEnabled(e){this.renderer.setDynamicBatchingEnabled(e)}setSelectedObjects(e){this.outline?.setSelectedObjects(e)}setSelectedObjectInstances(e){this.outline?.setSelectedInstances(e)}setCascadedShadowRanges(e,t=[]){this.renderer.setCascadedShadowRanges(e,t),this.volumetricFog?.setCascadedDirectionalLights(t)}setWorldEnvironment(t){if(null==t)return void this.nodeMaterialResolver.setWorldEnvironment(null);let i=t.source;if(i.mapping!==e.CubeUVReflectionMapping){let e=this.pmremResults.get(i);null==e&&(this.pmremGenerator??(this.pmremGenerator=this.renderer.createPMREMGenerator()),e=this.pmremGenerator.fromEquirectangular(i),this.pmremResults.set(i,e),this.ownedPmremResults.add(e)),i=e.texture}this.nodeMaterialResolver.setWorldEnvironment({texture:i,intensity:t.intensity})}resetViewHistory(){this.renderer.resetViewHistory(),this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset()}async compile(e,t){await this.renderer.compileAsync(e,t)}createStaticDrawSet(e,t){this.renderer.setHiZOcclusionCullingEnabled(!0);const i=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:"skip"});return 0===i.drawCount?(i.dispose(),null):i}render(e,t,i){const n="taa"===this.antiAliasingState.mode?this.taa:null;this.volumetricFog?.setScene(e),this.renderer.setMotionVectorProjection(t.projectionMatrix),this.motionBlur?.prepareCamera(t,this.canvas.width,this.canvas.height,i),this.motionBlur?.requiresRendererHistoryReset()&&(this.renderer.resetViewHistory(),this.gtao?.reset(),this.volumetricFog?.reset()),n?.prepareCamera(t,this.canvas.width,this.canvas.height),this.motionBlur?.setJitterUv(n?.currentJitterUv.x??0,n?.currentJitterUv.y??0);let r=!1;try{this.renderer.render(e,t,i),r=!0}finally{n?.finishCamera(t),r&&this.motionBlur?.commitCamera()}}setMotionBlurOptions(e){null!=this.motionBlur&&Object.assign(this.motionBlur.options,e)}setGTAOOptions(e){this.gtao?.setOptions(e)}setAntiAliasingMode(e){e!==this.antiAliasingState.mode&&("taa"===e&&null==this.taa||"smaa"===e&&null==this.smaa||"fxaa"===e&&null==this.fxaa?console.warn(`[Hology WebGPU experiment] Anti-aliasing mode "${e}" was not initialized. Set webgpuPostProcessing.antiAliasing in the initial rendering configuration to enable runtime switching.`):(this.antiAliasingState.mode=e,this.resetTemporalHistory()))}setGTAOQuality(e){this.gtao?.applyPreset(e)}setVolumetricFogOptions(e){this.volumetricFog?.setOptions(e)}setVolumetricFogQuality(e){this.volumetricFog?.applyPreset(e)}pushMotionBlurOverride(e){return this.motionBlur?.pushOverride(e)??null}invalidateObjectMotion(e){this.renderer.invalidateObjectMotion(e)}getLastFrameProfile(){return this.renderer.getLastFrameProfile()}setPostProcessState(e){null!=this.colorGrading&&(Object.assign(this.colorGrading.options,e??{enabled:!1}),this.colorGrading.options.enabled=!0===e?.enabled),null!=this.depthOfField&&(this.depthOfField.options.enabled=null!=e?.depthFocus||null!=e?.depthAperture||null!=e?.depthMaxBlur,this.depthOfField.options.focus=e?.depthFocus,this.depthOfField.options.aperture=e?.depthAperture,this.depthOfField.options.maxBlur=e?.depthMaxBlur)}setProfilingEnabled(e){this.renderer.setRenderGraphProfilingEnabled(e)}resetTemporalHistory(){this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.renderer.resetViewHistory()}inspect(e,t){return inspectWebGpuScene(e,t,this.nodeMaterialResolver)}destroy(){this.nodeMaterialResolver.dispose(),this.gBufferFallbackSource.dispose(),this.gtao?.dispose(),this.smaa?.dispose(),this.motionBlur?.dispose(),this.volumetricFog?.dispose();for(const e of this.ownedPmremResults)e.dispose();this.ownedPmremResults.clear(),this.renderer.destroy(),this.fallbackMaterial.dispose()}}export function inspectWebGpuScene(e,t,i){const n={meshes:0,skinnedMeshes:0,instancedMeshes:0,batchedMeshes:0,sprites:0,points:0,lines:0,missingPositionGeometry:0,transparentMaterials:0,shaderMaterialsReplaced:0,materialsReplaced:0,unsupportedCamera:ExperimentalWebGpuBackend.supportsCamera(t)?0:1};return e.traverse(e=>{if(e.isSprite)return void n.sprites++;if(e.isPoints)return void n.points++;if(e.isLine)return void n.lines++;if(!e.isMesh)return;const t=e;t.isBatchedMesh?n.batchedMeshes++:t.isInstancedMesh?n.instancedMeshes++:t.isSkinnedMesh?n.skinnedMeshes++:n.meshes++,null==t.geometry?.getAttribute("position")&&n.missingPositionGeometry++;const r=Array.isArray(t.material)?t.material:[t.material];for(const e of r){if(null==e)continue;e.transparent&&n.transparentMaterials++;const t=!0===e.isWGSLShaderMaterial||!0===e.isLineMaterial,r=!t&&!0===i?.canResolve(e);t||r||(n.materialsReplaced++,e.isShaderMaterial&&n.shaderMaterialsReplaced++)}}),n}export function formatWebGpuSceneCapabilitySummary(e){return`[Hology WebGPU experiment] ${JSON.stringify(e)}`}const c="\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) color: vec4<f32>,\n#ifdef USE_SKINNING\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n#endif\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n#ifdef USE_SKINNING\n let localPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let localNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let localPosition = input.position;\n let localNormal = input.normal;\n#endif\n let world = rendererWorldPosition(localPosition, input.instanceIndex);\n output.position = rendererClipPosition(localPosition, input.instanceIndex);\n output.worldPosition = world.xyz;\n output.worldNormal = rendererWorldNormal(localNormal, input.instanceIndex);\n output.color = input.color * rendererObjectColor(input.instanceIndex);\n return output;\n}\n",h="\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\nfn distanceAttenuation(distanceToLight: f32, range: f32) -> f32 {\n let linear = max(0.0, 1.0 - distanceToLight / max(range, 0.001));\n return linear * linear;\n}\n\n@fragment\nfn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n let normal = normalize(input.worldNormal);\n let normalTint = normal * 0.5 + vec3<f32>(0.5);\n let base = mix(vec3<f32>(0.52, 0.58, 0.64), normalTint, 0.22) * input.color.rgb;\n var lighting = rendererIndirectDiffuse(normal) + vec3<f32>(0.08);\n var directionalLighting = vec3<f32>(0.0);\n let directionalCount = rendererDirectionalLightCount();\n\n for (var index: u32 = 0u; index < directionalCount; index = index + 1u) {\n let lightDirection = rendererDirectionalLightDirectionForLight(index);\n let shadow = rendererSampleDirectionalShadowForLightWithNormal(index, input.worldPosition, normal);\n directionalLighting += rendererDirectionalLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * shadow;\n }\n if (directionalCount > 0u) {\n lighting += directionalLighting / f32(directionalCount);\n }\n\n for (var index: u32 = 0u; index < rendererPointLightCount(); index = index + 1u) {\n let lightVector = rendererPointLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let shadow = rendererSamplePointShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererPointLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * distanceAttenuation(distanceToLight, rendererPointLightRangeForLight(index)) * shadow;\n }\n\n for (var index: u32 = 0u; index < rendererSpotLightCount(); index = index + 1u) {\n let lightVector = rendererSpotLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let angleCos = dot(-lightDirection, rendererSpotLightDirectionForLight(index));\n let cone = smoothstep(rendererSpotLightConeCosForLight(index), rendererSpotLightPenumbraCosForLight(index), angleCos);\n let shadow = rendererSampleSpotShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererSpotLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * cone * distanceAttenuation(distanceToLight, rendererSpotLightRangeForLight(index)) * shadow;\n }\n\n return vec4<f32>(base * max(lighting, vec3<f32>(0.08)), input.color.a);\n}\n";/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -11,11 +11,13 @@ import { Cluster } from "./rendering/cluster-generator.js";
11
11
  import { LightVolume } from "./rendering/light-probes/light-volume-capture.js";
12
12
  import { type PostProcessMaterialSource } from "./shader/post-process-shader.js";
13
13
  import { type UpscalingOptions } from "./rendering/upscaling-pass.js";
14
- import { type ExperimentalWebGpuPostProcessingOptions } from './rendering/webgpu-experimental-backend.js';
14
+ import { type AntiAliasingMode, type ExperimentalWebGpuPostProcessingOptions, type GTAOOptions, type GTAOQuality, type MotionBlurOptions, type MotionBlurOverride, type MotionBlurOverrideHandle, type VolumetricFogOptions, type VolumetricFogQuality } from './rendering/webgpu-experimental-backend.js';
15
15
  import type { WorldEnvironmentState } from './rendering/environment.js';
16
16
  export type { UpscalingOptions } from "./rendering/upscaling-pass.js";
17
- export type { ExperimentalWebGpuPostProcessingOptions } from './rendering/webgpu-experimental-backend.js';
17
+ export type { AntiAliasingMode, ExperimentalWebGpuPostProcessingOptions } from './rendering/webgpu-experimental-backend.js';
18
+ export type { GTAOOptions, GTAOQuality, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, VolumetricFogOptions, VolumetricFogQuality } from './rendering/webgpu-experimental-backend.js';
18
19
  export type RenderingBackend = 'webgl' | 'webgpu-experimental';
20
+ export type MotionBlurObjectMode = 'disabled' | 'cameraOnly' | 'objectAndCamera' | 'forceObjectBlur';
19
21
  export type DynamicResolutionOptions = {
20
22
  enabled?: boolean;
21
23
  /**
@@ -240,6 +242,16 @@ export declare class RenderingView {
240
242
  setCamera(camera: Camera): void;
241
243
  setSelectedObjects(obj: Object3D[]): void;
242
244
  setExperimentalWebGpuDynamicBatchingEnabled(enabled: boolean): void;
245
+ setMotionBlurOptions(options: MotionBlurOptions): void;
246
+ setGTAOOptions(options: GTAOOptions): void;
247
+ setAntiAliasingMode(mode: AntiAliasingMode): void;
248
+ setGTAOQuality(quality: GTAOQuality): void;
249
+ setVolumetricFogOptions(options: VolumetricFogOptions): void;
250
+ setVolumetricFogQuality(quality: VolumetricFogQuality): void;
251
+ pushMotionBlurOverride(override: MotionBlurOverride): MotionBlurOverrideHandle | null;
252
+ setObjectMotionBlur(object: Object3D, mode: MotionBlurObjectMode, scale?: number): void;
253
+ /** Call after a teleport or discontinuous animation reset. */
254
+ invalidateObjectMotion(object: Object3D): void;
243
255
  /**
244
256
  * Select individual InstancedMesh instances or BatchedMesh geometry ids for
245
257
  * WebGPU outlines. The legacy WebGL OutlinePass still selects whole objects.