@hology/core 0.0.190 → 0.0.191

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.
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{AudioLoader as s,LoadingManager as a,TextureLoader as r}from"three";import{FBXLoader as i,GLTFLoader as o,MTLLoader as n,OBJLoader as c,TGALoader as d}from"three-stdlib";import{KTX2Loader as h}from"three/examples/jsm/Addons.js";import{Service as u}from"typedi";import{AssetResourceLoader as l}from"../../scene/asset-resource-loader.js";import{applyMaterial as w}from"../../scene/materializer";import{materialFromAsset as g}from"../../scene/materializer.js";import{Prefab as f}from"../../scene/objects/prefab.js";import{pathJoin as m}from"../../utils/files.js";import{Sequence as y}from"../../effects/sequence/sequence-data.js";let A=class{constructor(e,t,u){this.assetResourceLoader=e,this.assetService=t,this.shaders=u,this.baseUrl="",this.urlSuffix="",this.loadingManager=new a,this.glbLoader=new o(this.loadingManager),this.fbxLoader=new i(this.loadingManager),this.objLoader=new c(this.loadingManager),this.mtlLoader=new n(this.loadingManager),this.tgaLoader=new d(this.loadingManager),this.ktx2Loader=new h(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new s(this.loadingManager)}resolvePath(e){return m(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No model could be found with asset name ${e}`);const s=await this.assetResourceLoader.getMesh(t);return this.applyMaterials(t,s.scene),s}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);const s=await this.assetResourceLoader.getMesh(t);return this.applyMaterials(t,s.scene),s}async getAnimationClipByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No animation clip could be found with asset id ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async applyMaterials(e,t){for(const s of e.materialAssignments??[])await w(t,s,async e=>this.getMaterialByAssetId(e))}async getTextureByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No texture could be found with asset name ${e}`);return this.assetResourceLoader.getTexture(t)}async getTextureByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No texture could be found with asset id ${e}`);return this.assetResourceLoader.getTexture(t)}async getSequenceById(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No sequence could be found with asset id ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new y(t.sequence)}async getSequenceByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No sequence could be found with asset name ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new y(t.sequence)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return g(t,null,this.assetService,this.assetResourceLoader,this.shaders,!1)}async getAsset(e){return this.assetService.getAsset(e)}async getPrefabByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if("prefab"!==t.type)throw`Asset with name ${e} is not a prefab`;return new f(t)}async getPrefabById(e){const t=await this.getAsset(e);if("prefab"!==t.type)throw`Asset with name ${name} is not a prefab`;return new f(t)}};A=e([u(),t("design:paramtypes",[l,Function,Array])],A);export{A as AssetLoader};/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{AudioLoader as s,LoadingManager as a,TextureLoader as r}from"three";import{FBXLoader as i,GLTFLoader as o,MTLLoader as n,OBJLoader as d,TGALoader as l}from"three-stdlib";import{KTX2Loader as c}from"three/examples/jsm/Addons.js";import{Service as h}from"typedi";import{AssetResourceLoader as u}from"../../scene/asset-resource-loader.js";import{applyMaterial as w}from"../../scene/materializer";import{materialFromAsset as g}from"../../scene/materializer.js";import{Prefab as f}from"../../scene/objects/prefab.js";import{pathJoin as m}from"../../utils/files.js";import{Sequence as y}from"../../effects/sequence/sequence-data.js";let A=class{constructor(e,t,h){this.assetResourceLoader=e,this.assetService=t,this.shaders=h,this.baseUrl="",this.urlSuffix="",this.loadingManager=new a,this.glbLoader=new o(this.loadingManager),this.fbxLoader=new i(this.loadingManager),this.objLoader=new d(this.loadingManager),this.mtlLoader=new n(this.loadingManager),this.tgaLoader=new l(this.loadingManager),this.ktx2Loader=new c(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new s(this.loadingManager),this.assetResourceLoader.materialProvider=e=>this.getMaterialByAssetId(e)}resolvePath(e){return m(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No model could be found with asset name ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getAnimationClipByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No animation clip could be found with asset id ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async applyMaterials(e,t){for(const s of e.materialAssignments??[])await w(t,s,async e=>this.getMaterialByAssetId(e))}async getTextureByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No texture could be found with asset name ${e}`);return this.assetResourceLoader.getTexture(t)}async getTextureByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No texture could be found with asset id ${e}`);return this.assetResourceLoader.getTexture(t)}async getSequenceById(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No sequence could be found with asset id ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new y(t.sequence)}async getSequenceByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No sequence could be found with asset name ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new y(t.sequence)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return g(t,null,this.assetService,this.assetResourceLoader,this.shaders,!1)}async getAsset(e){return this.assetService.getAsset(e)}async getPrefabByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if("prefab"!==t.type)throw`Asset with name ${e} is not a prefab`;return new f(t)}async getPrefabById(e){const t=await this.getAsset(e);if("prefab"!==t.type)throw`Asset with name ${name} is not a prefab`;return new f(t)}};A=e([h(),t("design:paramtypes",[u,Function,Array])],A);export{A as AssetLoader};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import*as t from"three";import{Matrix4 as e,PerspectiveCamera as n,PointLight as i,Vector3 as o,WebGLRenderTarget as a}from"three";import{FullScreenQuad as r,Pass as s}from"three/examples/jsm/Addons.js";import{ambientLightName as l}from"../../scene/sky.js";import{FogVolumeObject as c}from"./fog-volume-object";const h=new o;export class VolumetricFogPass extends s{constructor(n){super(),this.resolution=n,this.fsQuad=new r(null),this.downSampleRatio=4,this._oldClearColor=new t.Color,this.oldClearAlpha=1,this.volumesCache=new WeakMap,this._viewProjection=new e,this._invViewProjection=new e;const i={minFilter:t.LinearFilter,magFilter:t.LinearFilter,format:t.RGBAFormat,depthBuffer:!1,stencilBuffer:!1,type:t.HalfFloatType},s=Math.round(this.resolution.x/this.downSampleRatio),l=Math.round(this.resolution.y/this.downSampleRatio);this.renderTargetFog=new a(s,l,i),this.renderTargetFog.texture.generateMipmaps=!1,this.renderTargetBlur=new a(s,l,i),this.renderTargetBlur.texture.generateMipmaps=!1,this.material=new t.ShaderMaterial({defines:{PERSPECTIVE_CAMERA:1,NUM_FOG_VOLUMES:0,MAX_POINT_LIGHTS:8,MAX_SPOT_LIGHTS:2,VOLUMETRIC:1,SHADOW_FAR:100},uniforms:{tDepth:{value:null},tDiffuse:{value:null},cameraPos:{value:new o},cameraMatrix:{value:new e},invProjection:{value:new e},fogVolumes:{value:[]},stepCount:{value:30},cameraNear:{value:null},cameraFar:{value:null},pointLights:{value:new Array(8).fill(null).map(()=>({color:new o(0,0,0),distance:0,position:new o}))},activePointLightCount:{value:0},spotLights:{value:new Array(2).fill(null).map(()=>({position:new o,direction:new o,color:new o,distance:0,decay:0,coneCos:0,penumbraCos:0}))},activeSpotLightCount:{value:0},directionalLight:{value:{direction:new o(0,-1,1).normalize(),color:new o(1,1,1)}},ambientLight:{value:new o(1,1,1).multiplyScalar(1.35)},directionalShadowMatrix:{value:new e},directionalShadowMap:{value:null},depthMappingParams:{value:new o}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);\n }\n ",fragmentShader:"\n #define MAX_STEP_COUNT 64\n\n struct IncidentLight {\n vec3 color;\n vec3 direction;\n bool visible;\n };\n\n #if MAX_POINT_LIGHTS > 0\n struct PointLight {\n\t\t\tvec3 position;\n vec3 color;\n float distance;\n\t\t};\n #endif\n\n #if MAX_SPOT_LIGHTS > 0\n struct SpotLight {\n vec3 position;\n vec3 direction;\n vec3 color;\n float distance;\n float decay;\n float coneCos;\n float penumbraCos;\n };\n uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ];\n uniform int activeSpotLightCount;\n float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n return smoothstep( coneCosine, penumbraCosine, angleCosine );\n }\n #ifndef saturate\n #define saturate( a ) clamp( a, 0.0, 1.0 )\n #endif\n float pow2( const in float x ) { return x*x; }\n vec3 pow2( const in vec3 x ) { return x*x; }\n float pow4( const in float x ) { float x2 = x*x; return x2*x2; }\n float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n // based upon Frostbite 3 Moving to Physically-based Rendering\n // page 32, equation 26: E[window1]\n // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf\n float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n if ( cutoffDistance > 0.0 ) {\n distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n }\n return distanceFalloff;\n }\n void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = spotLight.position - geometryPosition;\n light.direction = normalize( lVector );\n float angleCos = dot( light.direction, spotLight.direction );\n float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n if ( spotAttenuation > 0.0 ) {\n float lightDistance = length( lVector );\n light.color = spotLight.color * spotAttenuation;\n light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n } else {\n light.color = vec3( 0.0 );\n light.visible = false;\n }\n }\n vec3 calcSpotLight(vec3 p, vec3 rayDir, float g, SpotLight spotLight) {\n IncidentLight directLight;\n getSpotLightInfo(spotLight, p, directLight);\n return directLight.color * 3.14;\n }\n #endif\n\n struct DirectionalLight {\n vec3 color; // pre multiplied with intensity\n vec3 direction; // should point *from the light*, normalized\n };\n\n struct FogVolume {\n vec3 sphereCenter;\n float sphereRadius;\n float baseDensity;\n float heightFalloff;\n float heightOffset;\n float scatteringDistribution;\n float startDistance;\n vec3 albedo;\n vec3 emissive; // Self-illumination color\n float ambientIntensity; // Multiplier for ambient light contribution\n float scatteringMode; // 0 = volumetric (occludes), 1 = lightShaft (god rays)\n };\n\n varying vec2 vUv;\n uniform sampler2D tDiffuse;\n uniform vec3 cameraPos;\n\n uniform float stepCount;\n uniform float nearMinDistance;\n\n uniform mat4 cameraMatrix;\n uniform mat4 invProjection;\n uniform sampler2D tDepth;\n\t\tuniform float cameraNear;\n\t\tuniform float cameraFar;\n \n uniform DirectionalLight directionalLight;\n\n uniform mat4 directionalShadowMatrix;\n uniform sampler2D directionalShadowMap;\n\n uniform vec3 ambientLight;\n uniform vec3 depthMappingParams;\n\n #if NUM_FOG_VOLUMES > 0\n uniform FogVolume fogVolumes[ NUM_FOG_VOLUMES ];\n #endif\n #if MAX_POINT_LIGHTS > 0\n uniform PointLight pointLights[ MAX_POINT_LIGHTS ];\n uniform int activePointLightCount;\n #endif\n\n #include <packing>\n\n // Ray-sphere intersection\n bool intersectSphere(vec3 rayOrigin, vec3 rayDir, vec3 sphereCenter, float sphereRadius, out float t0, out float t1) {\n // Vector from ray origin to sphere center\n vec3 L = rayOrigin - sphereCenter;\n float a = dot(rayDir, rayDir); // should be 1 if rayDir is normalized\n float b = 2.0 * dot(rayDir, L);\n float c = dot(L, L) - sphereRadius * sphereRadius;\n \n float discriminant = b * b - 4.0 * a * c;\n if (discriminant < 0.0) {\n return false; // no intersection\n }\n \n float sqrtD = sqrt(discriminant);\n t0 = (-b - sqrtD) / (2.0 * a);\n t1 = (-b + sqrtD) / (2.0 * a);\n \n // Make sure t0 <= t1\n if (t0 > t1) {\n float tmp = t0;\n t0 = t1;\n t1 = tmp;\n }\n return true;\n }\n\n float getLinearDepth( const in vec2 uv ) {\n\n float fragCoordZ = texture2D( tDepth, uv ).x;\n return perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );\n\n\t\t}\n\n float linearizeDepth(float depth) {\n float z = depth * 2.0 - 1.0; // back to NDC (-1..1)\n return (2.0 * cameraNear * cameraFar) / (cameraFar + cameraNear - z * (cameraFar - cameraNear));\n }\n\n float getSliceAtDepth(float depth) {\n return log2(max(1.0, depth * depthMappingParams.x + depthMappingParams.y)) * depthMappingParams.z;\n }\n\n float getDepthAtSlice(float slice) {\n return (exp2(slice / depthMappingParams.z) - depthMappingParams.y) / depthMappingParams.x;\n }\n\n\n\n float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n }\n\n vec3 calcDirectionalLight(vec3 p, vec3 rayDir, float g, DirectionalLight dirLight, out float outInShadow) {\n vec3 toLight = dirLight.direction; // direction from sample point to light\n float cosTheta = dot(toLight, -rayDir); // angle between view ray and light\n cosTheta = clamp(cosTheta, -1.0, 1.0); // keep it safe\n\n // phase function (Henyey-Greenstein or isotropic)\n float denom = 1.0 + g*g - 2.0*g*cosTheta;\n float phase = (1.0 - g*g) / (4.0 * 3.14159265 * pow(denom, 1.5));\n phase *= 3.0 * 3.14159265; // scale to total energy\n\n vec4 shadowCoord = directionalShadowMatrix * vec4(p, 1.0);\n shadowCoord.xyz /= shadowCoord.w; // perspective divide\n\n float bias = 0.0; \n outInShadow = texture2DCompare(directionalShadowMap, shadowCoord.xy, shadowCoord.z - bias);\n\n return dirLight.color * phase * outInShadow;\n }\n\n vec3 calcPointLight(vec3 p, vec3 rayDir, float g, PointLight pointLight) {\n vec3 lightPos = pointLight.position;\n vec3 lightColor = pointLight.color;\n float lightRadius = pointLight.distance;\n\n vec3 L = normalize(lightPos - p);\n float lightDist = length(lightPos - p);\n \n float attenuation = clamp(1.0 - lightDist / lightRadius, 0.0, 1.0);\n attenuation *= attenuation; // smoother falloff\n attenuation /= (1.0 + lightDist*lightDist); // inverse-square style\n\n attenuation *= 4.0 * 3.14159; // Manually scaled to match point light intensity\n // float attenuation = 1.0 / (4.0 * 3.14159 * lightDist * lightDist);\n\n\n float cosTheta = dot(L, -rayDir); // angle between light and view ray\n float phase = (1.0 - g*g) / pow(1.0 + g*g - 2.0*g*cosTheta, 1.5);\n phase *= 0.25 / 3.14159; // normalize\n\n // Intensity is part of color\n vec3 light = lightColor * attenuation * phase;\n return light;\n }\n\n float random01(vec2 p) {\n return fract(sin(dot(p, vec2(41.0, 289.0))) * 45758.5453);\n }\n\n float hash(vec3 p) { return fract(sin(dot(p, vec3(12.9898,78.233,37.719))) * 43758.5453); }\n\n // Compute perceived brightness of a color (luminosity, Rec. 709)\n float luminosity(vec3 color) {\n return dot(color, vec3(0.2126, 0.7152, 0.0722));\n }\n \n void main() {\n // reconstruct ray in world space\n vec2 ndc = vUv * 2.0 - 1.0;\n vec4 nearPoint = invProjection * vec4(ndc, -1.0, 1.0);\n nearPoint /= nearPoint.w;\n vec4 farPoint = invProjection * vec4(ndc, 1.0, 1.0);\n farPoint /= farPoint.w;\n\n vec3 rayOrigin = cameraPos;\n vec3 rayDir = normalize(farPoint.xyz - cameraPos);\n\n float sceneDepth = -getLinearDepth(vUv); // in view space\n\n // vec4 scenePosView = invProjection * vec4(ndc, sceneDepth * 2.0 - 1.0, 1.0);\n // scenePosView /= scenePosView.w;\n\n // distance from camera to surface\n // float sceneDist = length(scenePosView.xyz - cameraPosition);\n\n float transmittance = 1.0;\n vec3 inscatter = vec3(0.0);\n float random = random01(vUv);\n\n\n #if NUM_FOG_VOLUMES > 0\n for (int v = 0; v < NUM_FOG_VOLUMES; v++) {\n FogVolume volume = fogVolumes[v];\n vec3 sphereCenter = volume.sphereCenter;\n float sphereRadius = volume.sphereRadius;\n float heightFalloff = volume.heightFalloff;\n float heightOffset = volume.heightOffset;\n float baseDensity = volume.baseDensity;\n float startDistance = volume.startDistance;\n float g = volume.scatteringDistribution;\n bool isLightShaft = volume.scatteringMode > 0.5;\n\n float t0, t1;\n if (!intersectSphere(rayOrigin, rayDir, sphereCenter, sphereRadius, t0, t1) || t1 <= 0.0) {\n continue;\n }\n // if camera inside sphere\n t0 = max(t0, cameraNear);\n float t_end = min(t1, sceneDepth);\n if (t_end <= t0) continue;\n\n float sliceStart = getSliceAtDepth(t0);\n float sliceEnd = getSliceAtDepth(t_end);\n float sliceRange = sliceEnd - sliceStart;\n \n // Determine number of steps based on distance, but capped at MAX_STEP_COUNT\n float maxStepSize = 0.3;\n int desiredSteps = int(ceil((t_end - t0) / maxStepSize));\n int numSteps = clamp(desiredSteps, 1, MAX_STEP_COUNT);\n float sliceStep = sliceRange / float(numSteps);\n\n float jitter = random;\n\n for (int i = 0; i < MAX_STEP_COUNT; i++) {\n if (i >= numSteps) break;\n\n float s0 = sliceStart + float(i) * sliceStep;\n float s1 = sliceStart + float(i + 1) * sliceStep;\n \n float tSampleT0 = getDepthAtSlice(s0);\n float tSampleT1 = getDepthAtSlice(s1);\n float t = getDepthAtSlice(s0 + jitter * sliceStep);\n \n float stepSize = tSampleT1 - tSampleT0;\n \n if (t > sceneDepth) break;\n\n vec3 p = rayOrigin + rayDir * t;\n\n float geomDelta = sceneDepth - t; // how far fog sample is from hitting geometry\n float fade = clamp(geomDelta, 0.0, 1.0); \n // float fade = clamp((sceneDepth - t) / 0.1, 0.0, 1.0);\n\n float closeFade = smoothstep(0.0, 0.3, (t - startDistance) / t);\n float edgeFade = clamp(sphereRadius - length(p - sphereCenter), 0.0, 1.0);\n\n // density with exponential height falloff\n float h = p.y - (sphereCenter.y + heightOffset);\n float heightFactor = clamp(exp(-h * heightFalloff), 0.0, 1.0);\n float density = baseDensity * heightFactor * fade * closeFade * edgeFade;\n\n vec3 light = vec3(0.0);\n float inDirectLight = 1.0; // 1.0 = in light, 0.0 = in shadow\n \n #if VOLUMETRIC == 1\n // Skip if we're too far away for directional light shadows\n // Or the entire volume will show instead of just the shafts\n if (isLightShaft && t > float(SHADOW_FAR)) {\n continue;\n }\n // Get directional light first - this also gives us the shadow value for god rays\n light += calcDirectionalLight(p, rayDir, g, directionalLight, inDirectLight);\n \n // For god rays mode, skip everything else if we're in shadow\n // For atmospheric mode, always include all lights\n if (!isLightShaft || inDirectLight > 0.5) {\n #if MAX_POINT_LIGHTS > 0\n for (int pi = 0; pi < activePointLightCount; pi++) {\n light += calcPointLight(p, rayDir, g, pointLights[pi]);\n } \n #endif\n\n #if MAX_SPOT_LIGHTS > 0\n for (int pi = 0; pi < activeSpotLightCount; pi++) {\n light += calcSpotLight(p, rayDir, g, spotLights[pi]);\n } \n #endif\n\n // Ambient and emissive only for atmospheric mode, not god rays\n if (!isLightShaft) {\n light += ambientLight * volume.ambientIntensity;\n light += volume.emissive;\n }\n }\n\n #else\n light = vec3(1.0);\n #endif\n\n light *= volume.albedo;\n \n // In god rays mode, only accumulate when in direct light\n // In atmospheric mode, always accumulate\n if (!isLightShaft || inDirectLight > 0.5) {\n transmittance *= exp(-density * stepSize);\n inscatter += transmittance * light * density * stepSize;\n }\n }\n }\n #endif\n\n float alpha = 1.0 - transmittance;\n\n gl_FragColor = vec4(inscatter, alpha);\n }\n "}),this.material.onBeforeCompile=t=>{},this.materialBlur=new t.ShaderMaterial({uniforms:{tInput:{value:null},tDepth:{value:null},texelSize:{value:new t.Vector2(1,1).divideScalar(1e3)},direction:{value:new t.Vector2(1,0)},depthSigma:{value:2},blurSigma:{value:1}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n uniform sampler2D tInput;\n uniform sampler2D tDepth;\n uniform vec2 texelSize;\n uniform vec2 direction;\n uniform float depthSigma;\n uniform float blurSigma;\n varying vec2 vUv;\n\n #include <packing>\n\n void main() {\n float centerDepth = texture2D(tDepth, vUv).x;\n vec4 center = texture2D(tInput, vUv);\n vec4 centerColor = center;\n\n vec4 sum = vec4(0.0);\n float wsum = 0.0;\n\n // int radius = int(ceil(2.0 * blurSigma));\n\n for (int i = -5; i <= 5; i++) {\n // if (i > radius || i < -radius) continue;\n\n vec2 offset = direction * float(i) * texelSize; // this should be based on resolution\n vec2 uv = vUv + offset;\n\n vec4 sampleColor = texture2D(tInput, uv);\n float sampleDepth = texture2D(tDepth, uv).x;\n\n float spatialWeight = exp(-0.5 * (float(i) * float(i)) / (blurSigma * blurSigma));\n float depthDiff = abs(sampleDepth - centerDepth) * 100.0;\n float depthWeight = exp(-0.5 * (depthDiff * depthDiff) / (depthSigma * depthSigma));\n\n float w = spatialWeight * depthWeight;\n\n sum += sampleColor * w;\n wsum += w;\n }\n\n gl_FragColor = sum / wsum;\n }\n ",transparent:!0}),this.materialComposite=new t.ShaderMaterial({uniforms:{tDiffuse:{value:null},tFog:{value:null},tDepth:{value:null},fogResolution:{value:new t.Vector2}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n uniform sampler2D tDiffuse;\n uniform sampler2D tFog;\n uniform sampler2D tDepth;\n uniform vec2 fogResolution;\n varying vec2 vUv;\n\n #include <packing>\n\n void main() {\n vec2 fogTexelSize = 1.0 / fogResolution;\n vec2 fogUv = vUv * fogResolution - vec2(0.5);\n vec2 uv00 = (floor(fogUv) + vec2(0.5)) * fogTexelSize;\n vec2 uv10 = uv00 + vec2(fogTexelSize.x, 0.0);\n vec2 uv01 = uv00 + vec2(0.0, fogTexelSize.y);\n vec2 uv11 = uv00 + vec2(fogTexelSize.x, fogTexelSize.y);\n\n float d00 = texture2D(tDepth, uv00).x;\n float d10 = texture2D(tDepth, uv10).x;\n float d01 = texture2D(tDepth, uv01).x;\n float d11 = texture2D(tDepth, uv11).x;\n\n float dCenter = texture2D(tDepth, vUv).x;\n\n float diff00 = abs(dCenter - d00);\n float diff10 = abs(dCenter - d10);\n float diff01 = abs(dCenter - d01);\n float diff11 = abs(dCenter - d11);\n\n float minDiff = min(min(diff00, diff10), min(diff01, diff11));\n\n vec2 closestUv = uv00;\n if (minDiff == diff10) closestUv = uv10;\n else if (minDiff == diff01) closestUv = uv01;\n else if (minDiff == diff11) closestUv = uv11;\n\n vec4 sceneColor = texture2D(tDiffuse, vUv);\n \n // Depth-aware upscaling:\n // By default use hardware bilinear, but near depth edges, snap to the closest depth texel.\n // This avoids leaking fog across sharp silhouettes while keeping smooth areas artifact-free.\n float maxDiff = max(max(diff00, diff10), max(diff01, diff11));\n vec2 sampleUv = vUv;\n if (maxDiff > 0.001) {\n sampleUv = closestUv;\n }\n\n vec4 fogColor = texture2D(tFog, sampleUv);\n\n // Composite: fogColor.a is the fog alpha, blend over scene\n // vec3 color = mix(sceneColor.rgb, fogColor.rgb, fogColor.a);\n // Not sure why multipling alpha like this helps but it is necessary to avoid a dark\n // borders around the fog\n gl_FragColor = vec4(fogColor.rgb + (1.0 - fogColor.a * fogColor.a) * sceneColor.rgb, 1.0);\n }\n ",transparent:!0}),this.materialComposite.uniforms.fogResolution.value.set(s,l)}render(t,e,n){t.getClearColor(this._oldClearColor),this.oldClearAlpha=t.getClearAlpha();const i=t.autoClear;t.autoClear=!1,t.setClearColor(16777215,0),this.fsQuad.material=this.material,t.setRenderTarget(this.renderTargetFog),t.clear(),this.fsQuad.render(t),this.materialBlur.uniforms.tInput.value=this.renderTargetFog.texture,this.materialBlur.uniforms.direction.value=f,this.fsQuad.material=this.materialBlur,t.setRenderTarget(this.renderTargetBlur),t.clear(),this.fsQuad.render(t),this.materialBlur.uniforms.tInput.value=this.renderTargetBlur.texture,this.materialBlur.uniforms.direction.value=u,t.setRenderTarget(this.renderTargetFog),t.clear(),this.fsQuad.render(t),this.materialComposite.uniforms.tDiffuse.value=n.texture,this.materialComposite.uniforms.tFog.value=this.renderTargetFog.texture,this.fsQuad.material=this.materialComposite,this.renderToScreen?(t.setRenderTarget(null),this.fsQuad.render(t)):(t.setRenderTarget(e),this.clear&&t.clear(),this.fsQuad.render(t)),t.setClearColor(this._oldClearColor,this.oldClearAlpha),t.autoClear=i}setSize(t,e){let n=Math.round(t/this.downSampleRatio),i=Math.round(e/this.downSampleRatio);this.renderTargetFog.setSize(n,i),this.renderTargetBlur.setSize(n,i),this.materialBlur.uniforms.texelSize.value.set(1/n,1/i),this.materialComposite.uniforms.fogResolution.value.set(n,i)}set volumetric(t){this.material.defines.VOLUMETRIC=t?1:0}get volumetric(){return!!this.material.defines.VOLUMETRIC}getVolumeUniforms(t){let e=this.volumesCache.get(t);return null==e&&(e={albedo:new o,baseDensity:t.baseDensity,heightFalloff:t.heightFalloff,heightOffset:t.heightOffset,startDistance:t.startDistance??3,scatteringDistribution:t.scatteringDistribution,sphereRadius:1,sphereCenter:new o,emissive:new o,ambientIntensity:t.ambientIntensity??1,scatteringMode:"lightShaft"===t.scatteringMode?1:0},this.volumesCache.set(t,e)),t.object.getWorldPosition(e.sphereCenter),t.object.getWorldScale(h),e.sphereRadius=5*h.x,e.albedo.set(t.albedo.r,t.albedo.g,t.albedo.b),e.baseDensity=t.baseDensity,e.heightFalloff=t.heightFalloff,e.heightOffset=t.heightOffset,e.scatteringDistribution=t.scatteringDistribution,e.startDistance=t.startDistance,e.emissive.set(t.emissive.r,t.emissive.g,t.emissive.b),e.ambientIntensity=t.ambientIntensity??1,e.scatteringMode="lightShaft"===t.scatteringMode?1:0,e}getPointLightUniforms(t){const e={position:new o,color:new o,distance:0};return t.getWorldPosition(e.position),e.color.set(t.color.r,t.color.g,t.color.b).multiplyScalar(t.intensity*(t.userData?.volumetricIntensity??1)),e.distance=void 0!==t.distance&&t.distance>0?t.distance:1,e}getSpotLightUniforms(t){const e={position:new o,direction:new o,color:new o,distance:0,coneCos:0,penumbraCos:0,decay:1};return t.getWorldPosition(e.position),e.direction.setFromMatrixPosition(t.matrixWorld),h.setFromMatrixPosition(t.target.matrixWorld),e.direction.sub(h),e.color.set(t.color.r,t.color.g,t.color.b).multiplyScalar(t.intensity*(t.userData?.volumetricIntensity??1)),e.distance=void 0!==t.distance&&t.distance>0?t.distance:0,e.coneCos=Math.cos(t.angle),e.penumbraCos=Math.cos(t.angle*(1-t.penumbra)),e.decay=void 0!==t.decay?t.decay:1,e}updateArrayUniforms(e){const n=this.material.uniforms.fogVolumes.value;let o=0;const a=this.material.uniforms.pointLights.value;let r=0;const s=this.material.uniforms.spotLights.value;let l=0;e.traverseVisible(e=>{if(e instanceof c){const t=e.volume,i=this.getVolumeUniforms(t);n[o]=i,o++}else if(e instanceof i){if(r<a.length){if(0===e.userData.volumetricIntensity)return;const t=this.getPointLightUniforms(e);a[r].position.copy(t.position),a[r].color.copy(t.color),a[r].distance=t.distance,r++}}else if(e instanceof t.SpotLight&&l<s.length){if(0===e.userData.volumetricIntensity)return;const t=this.getSpotLightUniforms(e);s[l].position.copy(t.position),s[l].direction.copy(t.direction),s[l].color.copy(t.color),s[l].distance=t.distance,s[l].coneCos=t.coneCos,s[l].penumbraCos=t.penumbraCos,s[l].decay=t.decay,l++}}),this.material.uniforms.activePointLightCount.value=r,this.material.uniforms.activeSpotLightCount.value=l,this.material.defines.NUM_FOG_VOLUMES!==o&&(this.material.needsUpdate=!0,this.material.uniformsNeedUpdate=!0),this.material.defines.NUM_FOG_VOLUMES=o}get uniforms(){return this.material.uniforms}update(t,e,i,a){if(this.updateArrayUniforms(a),this.enabled=0!=this.material.defines.NUM_FOG_VOLUMES,!this.enabled)return;null==this.uniforms.cameraPosition&&(this.uniforms.cameraPos={value:new o}),this.uniforms.cameraPos.value.copy(t.position),this._viewProjection.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),this.uniforms.invProjection.value.copy(this._invViewProjection.copy(this._viewProjection).invert()),this.uniforms.tDepth.value=e.depthTexture,this.materialBlur.uniforms.tDepth.value=e.depthTexture,this.materialComposite.uniforms.tDepth.value=e.depthTexture,t instanceof n&&(this.uniforms.cameraNear.value=t.near,this.uniforms.cameraFar.value=t.far),this.uniforms.directionalLight.value.direction=i.lightDirection,this.uniforms.directionalLight.value.color.set(1,1,1).multiplyScalar(i.lightIntensity);const r=i.lights[i.lights.length-1];r&&r.shadow&&r.castShadow&&r.visible&&(this.uniforms.directionalShadowMap.value=r.shadow.map?.texture,this.uniforms.directionalShadowMatrix.value=r.shadow.matrix),r&&!r.visible?this.uniforms.directionalLight.value.color.set(0,0,0):this.uniforms.directionalLight.value.color.set(r.color.r,r.color.g,r.color.b).multiplyScalar(r.intensity*(r.userData?.volumetricIntensity??1));const s=a.children.find(t=>t.name===l);if(null!=s&&s.visible?this.uniforms.ambientLight.value.set(s.color.r,s.color.g,s.color.b).multiplyScalar(s.intensity*(s.userData?.volumetricIntensity??1)):this.uniforms.ambientLight.value.set(0,0,0),t instanceof n){const e=4.05,n=this.material.uniforms.stepCount.value;this.calculateDepthMappingParams(t.near,t.far,e,n,this.uniforms.depthMappingParams.value)}}calculateDepthMappingParams(t,e,n,i,o){const a=Math.max(t,.01),r=e,s=n,l=(r-a*Math.pow(2,i/s))/(r-a),c=(1-l)/a;o.set(c,l,s)}}const f=new t.Vector2(1,0),u=new t.Vector2(0,1);/*
1
+ import*as e from"three";import{Matrix4 as t,PerspectiveCamera as n,PointLight as i,Vector3 as o,WebGLRenderTarget as a}from"three";import{FullScreenQuad as r,Pass as s}from"three/examples/jsm/Addons.js";import{ambientLightName as l}from"../../scene/sky.js";import{FogVolumeObject as c}from"./fog-volume-object";const f=new o;export class VolumetricFogPass extends s{constructor(n){super(),this.resolution=n,this.fsQuad=new r(null),this.downSampleRatio=4,this._oldClearColor=new e.Color,this.oldClearAlpha=1,this.volumesCache=new WeakMap,this._viewProjection=new t,this._invViewProjection=new t;const i={minFilter:e.LinearFilter,magFilter:e.LinearFilter,format:e.RGBAFormat,depthBuffer:!1,stencilBuffer:!1,type:e.HalfFloatType},s=Math.round(this.resolution.x/this.downSampleRatio),l=Math.round(this.resolution.y/this.downSampleRatio);this.renderTargetFog=new a(s,l,i),this.renderTargetFog.texture.generateMipmaps=!1,this.renderTargetBlur=new a(s,l,i),this.renderTargetBlur.texture.generateMipmaps=!1,this.material=new e.ShaderMaterial({defines:{PERSPECTIVE_CAMERA:1,NUM_FOG_VOLUMES:0,MAX_POINT_LIGHTS:8,MAX_SPOT_LIGHTS:2,VOLUMETRIC:1,SHADOW_FAR:100},uniforms:{tDepth:{value:null},tDiffuse:{value:null},cameraPos:{value:new o},cameraMatrix:{value:new t},invProjection:{value:new t},fogVolumes:{value:[]},stepCount:{value:30},cameraNear:{value:null},cameraFar:{value:null},pointLights:{value:new Array(8).fill(null).map(()=>({color:new o(0,0,0),distance:0,position:new o}))},activePointLightCount:{value:0},spotLights:{value:new Array(2).fill(null).map(()=>({position:new o,direction:new o,color:new o,distance:0,decay:0,coneCos:0,penumbraCos:0}))},activeSpotLightCount:{value:0},directionalLight:{value:{direction:new o(0,-1,1).normalize(),color:new o(1,1,1)}},ambientLight:{value:new o(1,1,1).multiplyScalar(1.35)},directionalShadowMatrix:{value:new t},directionalShadowMap:{value:null},depthMappingParams:{value:new o}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);\n }\n ",fragmentShader:"\n #define MAX_STEP_COUNT 64\n\n struct IncidentLight {\n vec3 color;\n vec3 direction;\n bool visible;\n };\n\n #if MAX_POINT_LIGHTS > 0\n struct PointLight {\n\t\t\tvec3 position;\n vec3 color;\n float distance;\n\t\t};\n #endif\n\n #if MAX_SPOT_LIGHTS > 0\n struct SpotLight {\n vec3 position;\n vec3 direction;\n vec3 color;\n float distance;\n float decay;\n float coneCos;\n float penumbraCos;\n };\n uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ];\n uniform int activeSpotLightCount;\n float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n return smoothstep( coneCosine, penumbraCosine, angleCosine );\n }\n #ifndef saturate\n #define saturate( a ) clamp( a, 0.0, 1.0 )\n #endif\n float pow2( const in float x ) { return x*x; }\n vec3 pow2( const in vec3 x ) { return x*x; }\n float pow4( const in float x ) { float x2 = x*x; return x2*x2; }\n float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n // based upon Frostbite 3 Moving to Physically-based Rendering\n // page 32, equation 26: E[window1]\n // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf\n float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n if ( cutoffDistance > 0.0 ) {\n distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n }\n return distanceFalloff;\n }\n void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = spotLight.position - geometryPosition;\n light.direction = normalize( lVector );\n float angleCos = dot( light.direction, spotLight.direction );\n float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n if ( spotAttenuation > 0.0 ) {\n float lightDistance = length( lVector );\n light.color = spotLight.color * spotAttenuation;\n light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n } else {\n light.color = vec3( 0.0 );\n light.visible = false;\n }\n }\n vec3 calcSpotLight(vec3 p, vec3 rayDir, float g, SpotLight spotLight) {\n IncidentLight directLight;\n getSpotLightInfo(spotLight, p, directLight);\n return directLight.color * 3.14;\n }\n #endif\n\n struct DirectionalLight {\n vec3 color; // pre multiplied with intensity\n vec3 direction; // should point *from the light*, normalized\n };\n\n struct FogVolume {\n vec3 sphereCenter;\n float sphereRadius;\n float baseDensity;\n float heightFalloff;\n float heightOffset;\n float scatteringDistribution;\n float startDistance;\n vec3 albedo;\n vec3 emissive; // Self-illumination color\n float ambientIntensity; // Multiplier for ambient light contribution\n float scatteringMode; // 0 = volumetric (occludes), 1 = lightShaft (god rays)\n };\n\n varying vec2 vUv;\n uniform sampler2D tDiffuse;\n uniform vec3 cameraPos;\n\n uniform float stepCount;\n uniform float nearMinDistance;\n\n uniform mat4 cameraMatrix;\n uniform mat4 invProjection;\n uniform sampler2D tDepth;\n\t\tuniform float cameraNear;\n\t\tuniform float cameraFar;\n \n uniform DirectionalLight directionalLight;\n\n uniform mat4 directionalShadowMatrix;\n uniform sampler2D directionalShadowMap;\n\n uniform vec3 ambientLight;\n uniform vec3 depthMappingParams;\n\n #if NUM_FOG_VOLUMES > 0\n uniform FogVolume fogVolumes[ NUM_FOG_VOLUMES ];\n #endif\n #if MAX_POINT_LIGHTS > 0\n uniform PointLight pointLights[ MAX_POINT_LIGHTS ];\n uniform int activePointLightCount;\n #endif\n\n #include <packing>\n\n // Ray-sphere intersection\n bool intersectSphere(vec3 rayOrigin, vec3 rayDir, vec3 sphereCenter, float sphereRadius, out float t0, out float t1) {\n // Vector from ray origin to sphere center\n vec3 L = rayOrigin - sphereCenter;\n float a = dot(rayDir, rayDir); // should be 1 if rayDir is normalized\n float b = 2.0 * dot(rayDir, L);\n float c = dot(L, L) - sphereRadius * sphereRadius;\n \n float discriminant = b * b - 4.0 * a * c;\n if (discriminant < 0.0) {\n return false; // no intersection\n }\n \n float sqrtD = sqrt(discriminant);\n t0 = (-b - sqrtD) / (2.0 * a);\n t1 = (-b + sqrtD) / (2.0 * a);\n \n // Make sure t0 <= t1\n if (t0 > t1) {\n float tmp = t0;\n t0 = t1;\n t1 = tmp;\n }\n return true;\n }\n\n float getLinearDepth( const in vec2 uv ) {\n\n float fragCoordZ = texture2D( tDepth, uv ).x;\n return perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );\n\n\t\t}\n\n float linearizeDepth(float depth) {\n float z = depth * 2.0 - 1.0; // back to NDC (-1..1)\n return (2.0 * cameraNear * cameraFar) / (cameraFar + cameraNear - z * (cameraFar - cameraNear));\n }\n\n float getSliceAtDepth(float depth) {\n return log2(max(1.0, depth * depthMappingParams.x + depthMappingParams.y)) * depthMappingParams.z;\n }\n\n float getDepthAtSlice(float slice) {\n return (exp2(slice / depthMappingParams.z) - depthMappingParams.y) / depthMappingParams.x;\n }\n\n\n\n float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n }\n\n vec3 calcDirectionalLight(vec3 p, vec3 rayDir, float g, DirectionalLight dirLight, out float outInShadow) {\n vec3 toLight = dirLight.direction; // direction from sample point to light\n float cosTheta = dot(toLight, -rayDir); // angle between view ray and light\n cosTheta = clamp(cosTheta, -1.0, 1.0); // keep it safe\n\n // phase function (Henyey-Greenstein or isotropic)\n float denom = 1.0 + g*g - 2.0*g*cosTheta;\n float phase = (1.0 - g*g) / (4.0 * 3.14159265 * pow(denom, 1.5));\n phase *= 3.0 * 3.14159265; // scale to total energy\n\n vec4 shadowCoord = directionalShadowMatrix * vec4(p, 1.0);\n shadowCoord.xyz /= shadowCoord.w; // perspective divide\n\n float bias = 0.0; \n outInShadow = texture2DCompare(directionalShadowMap, shadowCoord.xy, shadowCoord.z - bias);\n\n return dirLight.color * phase * outInShadow;\n }\n\n vec3 calcPointLight(vec3 p, vec3 rayDir, float g, PointLight pointLight) {\n vec3 lightPos = pointLight.position;\n vec3 lightColor = pointLight.color;\n float lightRadius = pointLight.distance;\n\n vec3 L = normalize(lightPos - p);\n float lightDist = length(lightPos - p);\n \n float attenuation = clamp(1.0 - lightDist / lightRadius, 0.0, 1.0);\n attenuation *= attenuation; // smoother falloff\n attenuation /= (1.0 + lightDist*lightDist); // inverse-square style\n\n attenuation *= 4.0 * 3.14159; // Manually scaled to match point light intensity\n // float attenuation = 1.0 / (4.0 * 3.14159 * lightDist * lightDist);\n\n\n float cosTheta = dot(L, -rayDir); // angle between light and view ray\n float phase = (1.0 - g*g) / pow(1.0 + g*g - 2.0*g*cosTheta, 1.5);\n phase *= 0.25 / 3.14159; // normalize\n\n // Intensity is part of color\n vec3 light = lightColor * attenuation * phase;\n return light;\n }\n\n float random01(vec2 p) {\n return fract(sin(dot(p, vec2(41.0, 289.0))) * 45758.5453);\n }\n\n float hash(vec3 p) { return fract(sin(dot(p, vec3(12.9898,78.233,37.719))) * 43758.5453); }\n\n // Compute perceived brightness of a color (luminosity, Rec. 709)\n float luminosity(vec3 color) {\n return dot(color, vec3(0.2126, 0.7152, 0.0722));\n }\n \n void main() {\n // reconstruct ray in world space\n vec2 ndc = vUv * 2.0 - 1.0;\n vec4 nearPoint = invProjection * vec4(ndc, -1.0, 1.0);\n nearPoint /= nearPoint.w;\n vec4 farPoint = invProjection * vec4(ndc, 1.0, 1.0);\n farPoint /= farPoint.w;\n\n vec3 rayOrigin = cameraPos;\n vec3 rayDir = normalize(farPoint.xyz - cameraPos);\n\n float sceneDepth = -getLinearDepth(vUv); // in view space\n\n // vec4 scenePosView = invProjection * vec4(ndc, sceneDepth * 2.0 - 1.0, 1.0);\n // scenePosView /= scenePosView.w;\n\n // distance from camera to surface\n // float sceneDist = length(scenePosView.xyz - cameraPosition);\n\n float transmittance = 1.0;\n vec3 inscatter = vec3(0.0);\n float random = random01(vUv);\n\n\n #if NUM_FOG_VOLUMES > 0\n for (int v = 0; v < NUM_FOG_VOLUMES; v++) {\n FogVolume volume = fogVolumes[v];\n vec3 sphereCenter = volume.sphereCenter;\n float sphereRadius = volume.sphereRadius;\n float heightFalloff = volume.heightFalloff;\n float heightOffset = volume.heightOffset;\n float baseDensity = volume.baseDensity;\n float startDistance = volume.startDistance;\n float g = volume.scatteringDistribution;\n bool isLightShaft = volume.scatteringMode > 0.5;\n\n float t0, t1;\n if (!intersectSphere(rayOrigin, rayDir, sphereCenter, sphereRadius, t0, t1) || t1 <= 0.0) {\n continue;\n }\n // if camera inside sphere\n t0 = max(t0, cameraNear);\n float t_end = min(t1, sceneDepth);\n if (t_end <= t0) continue;\n\n float sliceStart = getSliceAtDepth(t0);\n float sliceEnd = getSliceAtDepth(t_end);\n float sliceRange = sliceEnd - sliceStart;\n \n // Determine number of steps based on distance, but capped at MAX_STEP_COUNT\n float maxStepSize = 0.3;\n int desiredSteps = int(ceil((t_end - t0) / maxStepSize));\n int numSteps = clamp(desiredSteps, 1, MAX_STEP_COUNT);\n float sliceStep = sliceRange / float(numSteps);\n\n float jitter = random;\n\n for (int i = 0; i < MAX_STEP_COUNT; i++) {\n if (i >= numSteps) break;\n\n float s0 = sliceStart + float(i) * sliceStep;\n float s1 = sliceStart + float(i + 1) * sliceStep;\n \n float tSampleT0 = getDepthAtSlice(s0);\n float tSampleT1 = getDepthAtSlice(s1);\n float t = getDepthAtSlice(s0 + jitter * sliceStep);\n \n float stepSize = tSampleT1 - tSampleT0;\n \n if (t > sceneDepth) break;\n\n vec3 p = rayOrigin + rayDir * t;\n\n float geomDelta = sceneDepth - t; // how far fog sample is from hitting geometry\n float fade = clamp(geomDelta, 0.0, 1.0); \n // float fade = clamp((sceneDepth - t) / 0.1, 0.0, 1.0);\n\n float closeFade = smoothstep(0.0, 0.3, (t - startDistance) / t);\n float edgeFade = clamp(sphereRadius - length(p - sphereCenter), 0.0, 1.0);\n\n // density with exponential height falloff\n float h = p.y - (sphereCenter.y + heightOffset);\n float heightFactor = clamp(exp(-h * heightFalloff), 0.0, 1.0);\n float density = baseDensity * heightFactor * fade * closeFade * edgeFade;\n\n vec3 light = vec3(0.0);\n float inDirectLight = 1.0; // 1.0 = in light, 0.0 = in shadow\n \n #if VOLUMETRIC == 1\n // Skip if we're too far away for directional light shadows\n // Or the entire volume will show instead of just the shafts\n if (isLightShaft && t > float(SHADOW_FAR)) {\n continue;\n }\n // Get directional light first - this also gives us the shadow value for god rays\n light += calcDirectionalLight(p, rayDir, g, directionalLight, inDirectLight);\n \n // For god rays mode, skip everything else if we're in shadow\n // For atmospheric mode, always include all lights\n if (!isLightShaft || inDirectLight > 0.5) {\n #if MAX_POINT_LIGHTS > 0\n for (int pi = 0; pi < activePointLightCount; pi++) {\n light += calcPointLight(p, rayDir, g, pointLights[pi]);\n } \n #endif\n\n #if MAX_SPOT_LIGHTS > 0\n for (int pi = 0; pi < activeSpotLightCount; pi++) {\n light += calcSpotLight(p, rayDir, g, spotLights[pi]);\n } \n #endif\n\n // Ambient and emissive only for atmospheric mode, not god rays\n if (!isLightShaft) {\n light += ambientLight * volume.ambientIntensity;\n light += volume.emissive;\n }\n }\n\n #else\n light = vec3(1.0);\n #endif\n\n light *= volume.albedo;\n \n if (!isLightShaft || inDirectLight > 0.5) {\n float extinction = exp(-density * stepSize);\n inscatter += light * (1.0 - extinction) * transmittance;\n transmittance *= extinction;\n }\n }\n }\n #endif\n\n float alpha = 1.0 - transmittance;\n\n gl_FragColor = vec4(inscatter, alpha);\n }\n "}),this.material.onBeforeCompile=e=>{},this.materialBlur=new e.ShaderMaterial({uniforms:{tInput:{value:null},tDepth:{value:null},texelSize:{value:new e.Vector2(1,1).divideScalar(1e3)},direction:{value:new e.Vector2(1,0)},depthSigma:{value:2},blurSigma:{value:1},cameraNear:{value:.1},cameraFar:{value:1e3}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n uniform sampler2D tInput;\n uniform sampler2D tDepth;\n uniform vec2 texelSize;\n uniform vec2 direction;\n uniform float depthSigma;\n uniform float blurSigma;\n uniform float cameraNear;\n uniform float cameraFar;\n varying vec2 vUv;\n\n #include <packing>\n\n float getLinearDepth( const in vec2 uv ) {\n float fragCoordZ = texture2D( tDepth, uv ).x;\n return perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );\n }\n\n void main() {\n float centerDepth = getLinearDepth(vUv);\n vec4 center = texture2D(tInput, vUv);\n vec4 centerColor = center;\n\n vec4 sum = vec4(0.0);\n float wsum = 0.0;\n\n for (int i = -5; i <= 5; i++) {\n vec2 offset = direction * float(i) * texelSize;\n vec2 uv = vUv + offset;\n\n vec4 sampleColor = texture2D(tInput, uv);\n float sampleDepth = getLinearDepth(uv);\n\n float spatialWeight = exp(-0.5 * (float(i) * float(i)) / (blurSigma * blurSigma));\n float depthDiff = abs(sampleDepth - centerDepth);\n float depthWeight = exp(-0.5 * (depthDiff * depthDiff) / (depthSigma * depthSigma));\n\n float w = spatialWeight * depthWeight;\n\n sum += sampleColor * w;\n wsum += w;\n }\n\n gl_FragColor = sum / (wsum + 0.0001);\n }\n ",transparent:!0}),this.materialComposite=new e.ShaderMaterial({uniforms:{tDiffuse:{value:null},tFog:{value:null},tDepth:{value:null},fogResolution:{value:new e.Vector2}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n uniform sampler2D tDiffuse;\n uniform sampler2D tFog;\n uniform sampler2D tDepth;\n uniform vec2 fogResolution;\n varying vec2 vUv;\n\n #include <packing>\n\n void main() {\n vec2 fogTexelSize = 1.0 / fogResolution;\n vec2 fogUv = vUv * fogResolution - vec2(0.5);\n vec2 uv00 = (floor(fogUv) + vec2(0.5)) * fogTexelSize;\n vec2 uv10 = uv00 + vec2(fogTexelSize.x, 0.0);\n vec2 uv01 = uv00 + vec2(0.0, fogTexelSize.y);\n vec2 uv11 = uv00 + vec2(fogTexelSize.x, fogTexelSize.y);\n\n float d00 = texture2D(tDepth, uv00).x;\n float d10 = texture2D(tDepth, uv10).x;\n float d01 = texture2D(tDepth, uv01).x;\n float d11 = texture2D(tDepth, uv11).x;\n\n float dCenter = texture2D(tDepth, vUv).x;\n\n float diff00 = abs(dCenter - d00);\n float diff10 = abs(dCenter - d10);\n float diff01 = abs(dCenter - d01);\n float diff11 = abs(dCenter - d11);\n\n float minDiff = min(min(diff00, diff10), min(diff01, diff11));\n\n vec2 closestUv = uv00;\n if (minDiff == diff10) closestUv = uv10;\n else if (minDiff == diff01) closestUv = uv01;\n else if (minDiff == diff11) closestUv = uv11;\n\n vec4 sceneColor = texture2D(tDiffuse, vUv);\n \n // Depth-aware upscaling:\n // By default use hardware bilinear, but near depth edges, snap to the closest depth texel.\n // This avoids leaking fog across sharp silhouettes while keeping smooth areas artifact-free.\n float maxDiff = max(max(diff00, diff10), max(diff01, diff11));\n vec2 sampleUv = vUv;\n if (maxDiff > 0.001) {\n sampleUv = closestUv;\n }\n\n vec4 fogColor = texture2D(tFog, sampleUv);\n\n // Composite: fogColor.a is the fog alpha, blend over scene\n // vec3 color = mix(sceneColor.rgb, fogColor.rgb, fogColor.a);\n // Multiplying with fogColor.a again helps to avoid dark borders around the fog\n gl_FragColor = vec4(fogColor.rgb + (1.0 - fogColor.a * fogColor.a) * sceneColor.rgb, 1.0);\n }\n ",transparent:!0}),this.materialComposite.uniforms.fogResolution.value.set(s,l)}render(e,t,n){e.getClearColor(this._oldClearColor),this.oldClearAlpha=e.getClearAlpha();const i=e.autoClear;e.autoClear=!1,e.setClearColor(16777215,0),this.fsQuad.material=this.material,e.setRenderTarget(this.renderTargetFog),e.clear(),this.fsQuad.render(e),this.materialBlur.uniforms.tInput.value=this.renderTargetFog.texture,this.materialBlur.uniforms.direction.value=h,this.fsQuad.material=this.materialBlur,e.setRenderTarget(this.renderTargetBlur),e.clear(),this.fsQuad.render(e),this.materialBlur.uniforms.tInput.value=this.renderTargetBlur.texture,this.materialBlur.uniforms.direction.value=u,e.setRenderTarget(this.renderTargetFog),e.clear(),this.fsQuad.render(e),this.materialComposite.uniforms.tDiffuse.value=n.texture,this.materialComposite.uniforms.tFog.value=this.renderTargetFog.texture,this.fsQuad.material=this.materialComposite,this.renderToScreen?(e.setRenderTarget(null),this.fsQuad.render(e)):(e.setRenderTarget(t),this.clear&&e.clear(),this.fsQuad.render(e)),e.setClearColor(this._oldClearColor,this.oldClearAlpha),e.autoClear=i}setSize(e,t){let n=Math.round(e/this.downSampleRatio),i=Math.round(t/this.downSampleRatio);this.renderTargetFog.setSize(n,i),this.renderTargetBlur.setSize(n,i),this.materialBlur.uniforms.texelSize.value.set(1/n,1/i),this.materialComposite.uniforms.fogResolution.value.set(n,i)}set volumetric(e){this.material.defines.VOLUMETRIC=e?1:0}get volumetric(){return!!this.material.defines.VOLUMETRIC}getVolumeUniforms(e){let t=this.volumesCache.get(e);return null==t&&(t={albedo:new o,baseDensity:e.baseDensity,heightFalloff:e.heightFalloff,heightOffset:e.heightOffset,startDistance:e.startDistance??3,scatteringDistribution:e.scatteringDistribution,sphereRadius:1,sphereCenter:new o,emissive:new o,ambientIntensity:e.ambientIntensity??1,scatteringMode:"lightShaft"===e.scatteringMode?1:0},this.volumesCache.set(e,t)),e.object.getWorldPosition(t.sphereCenter),e.object.getWorldScale(f),t.sphereRadius=5*f.x,t.albedo.set(e.albedo.r,e.albedo.g,e.albedo.b),t.baseDensity=e.baseDensity,t.heightFalloff=e.heightFalloff,t.heightOffset=e.heightOffset,t.scatteringDistribution=e.scatteringDistribution,t.startDistance=e.startDistance,t.emissive.set(e.emissive.r,e.emissive.g,e.emissive.b),t.ambientIntensity=e.ambientIntensity??1,t.scatteringMode="lightShaft"===e.scatteringMode?1:0,t}getPointLightUniforms(e){const t={position:new o,color:new o,distance:0};return e.getWorldPosition(t.position),t.color.set(e.color.r,e.color.g,e.color.b).multiplyScalar(e.intensity*(e.userData?.volumetricIntensity??1)),t.distance=void 0!==e.distance&&e.distance>0?e.distance:1,t}getSpotLightUniforms(e){const t={position:new o,direction:new o,color:new o,distance:0,coneCos:0,penumbraCos:0,decay:1};return e.getWorldPosition(t.position),t.direction.setFromMatrixPosition(e.matrixWorld),f.setFromMatrixPosition(e.target.matrixWorld),t.direction.sub(f),t.color.set(e.color.r,e.color.g,e.color.b).multiplyScalar(e.intensity*(e.userData?.volumetricIntensity??1)),t.distance=void 0!==e.distance&&e.distance>0?e.distance:0,t.coneCos=Math.cos(e.angle),t.penumbraCos=Math.cos(e.angle*(1-e.penumbra)),t.decay=void 0!==e.decay?e.decay:1,t}updateArrayUniforms(t){const n=this.material.uniforms.fogVolumes.value;let o=0;const a=this.material.uniforms.pointLights.value;let r=0;const s=this.material.uniforms.spotLights.value;let l=0;t.traverseVisible(t=>{if(t instanceof c){const e=t.volume,i=this.getVolumeUniforms(e);n[o]=i,o++}else if(t instanceof i){if(r<a.length){if(0===t.userData.volumetricIntensity)return;const e=this.getPointLightUniforms(t);a[r].position.copy(e.position),a[r].color.copy(e.color),a[r].distance=e.distance,r++}}else if(t instanceof e.SpotLight&&l<s.length){if(0===t.userData.volumetricIntensity)return;const e=this.getSpotLightUniforms(t);s[l].position.copy(e.position),s[l].direction.copy(e.direction),s[l].color.copy(e.color),s[l].distance=e.distance,s[l].coneCos=e.coneCos,s[l].penumbraCos=e.penumbraCos,s[l].decay=e.decay,l++}}),this.material.uniforms.activePointLightCount.value=r,this.material.uniforms.activeSpotLightCount.value=l,this.material.defines.NUM_FOG_VOLUMES!==o&&(this.material.needsUpdate=!0,this.material.uniformsNeedUpdate=!0),this.material.defines.NUM_FOG_VOLUMES=o}get uniforms(){return this.material.uniforms}update(e,t,i,a){if(this.updateArrayUniforms(a),this.enabled=0!=this.material.defines.NUM_FOG_VOLUMES,!this.enabled)return;null==this.uniforms.cameraPosition&&(this.uniforms.cameraPos={value:new o}),this.uniforms.cameraPos.value.copy(e.position),this._viewProjection.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),this.uniforms.invProjection.value.copy(this._invViewProjection.copy(this._viewProjection).invert()),this.uniforms.tDepth.value=t.depthTexture,this.materialBlur.uniforms.tDepth.value=t.depthTexture,this.materialComposite.uniforms.tDepth.value=t.depthTexture,e instanceof n&&(this.uniforms.cameraNear.value=e.near,this.uniforms.cameraFar.value=e.far,this.materialBlur.uniforms.cameraNear.value=e.near,this.materialBlur.uniforms.cameraFar.value=e.far),this.uniforms.directionalLight.value.direction=i.lightDirection,this.uniforms.directionalLight.value.color.set(1,1,1).multiplyScalar(i.lightIntensity);const r=i.lights[i.lights.length-1];r&&r.shadow&&r.castShadow&&r.visible&&(this.uniforms.directionalShadowMap.value=r.shadow.map?.texture,this.uniforms.directionalShadowMatrix.value=r.shadow.matrix),r&&!r.visible?this.uniforms.directionalLight.value.color.set(0,0,0):this.uniforms.directionalLight.value.color.set(r.color.r,r.color.g,r.color.b).multiplyScalar(r.intensity*(r.userData?.volumetricIntensity??1));const s=a.children.find(e=>e.name===l);if(null!=s&&s.visible?this.uniforms.ambientLight.value.set(s.color.r,s.color.g,s.color.b).multiplyScalar(s.intensity*(s.userData?.volumetricIntensity??1)):this.uniforms.ambientLight.value.set(0,0,0),e instanceof n){const t=4.05,n=this.material.uniforms.stepCount.value;this.calculateDepthMappingParams(e.near,e.far,t,n,this.uniforms.depthMappingParams.value)}}calculateDepthMappingParams(e,t,n,i,o){const a=Math.max(e,.01),r=t,s=n,l=(r-a*Math.pow(2,i/s))/(r-a),c=(1-l)/a;o.set(c,l,s)}}const h=new e.Vector2(1,0),u=new e.Vector2(0,1);/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -33,6 +33,8 @@ export type RenderingViewOptions = {
33
33
  export declare class RenderingView {
34
34
  container: HTMLElement;
35
35
  readonly options: RenderingViewOptions;
36
+ private static activeView;
37
+ private isIntersecting;
36
38
  camera: THREE.Camera;
37
39
  windowVisible: boolean;
38
40
  renderer: WebGLRenderer;
package/dist/rendering.js CHANGED
@@ -1,4 +1,4 @@
1
- var e;import{__decorate as t,__metadata as s}from"tslib";import*as i from"three";import{Color as a,Material as r,Matrix4 as n,Mesh as o,PerspectiveCamera as l,ShaderChunk as h,ShaderMaterial as u,WebGLRenderTarget as d,Texture as c,Euler as p,MeshStandardMaterial as m}from"three";import{CopyShader as f,EffectComposer as g,FXAAShader as M,GammaCorrectionShader as v,LUTPass as T,RenderPass as y,ShaderPass as b,VRButton as P}from"three-stdlib";import{CSMShader as x,CSMUtil as w}from"./csm.js";import{colorToNormal as S,float as R,NodeShaderMaterial as C,standardMaterial as A,uniformFloat as U,uniformVec3 as F,toonMaterial as B,lambertMaterial as I,normalize as O,rgb as E,rgba as D,transformed as L,varying as V,varyingAttributes as _,varyingTransformed as j,vec4 as G,BooleanExpression as W,select as q,ifDefApply as k,uniformSampler2d as N,RgbaNode as H,mix as z,attributes as $}from"three-shader-graph";import{Reflector as X}from"three-stdlib";import{BokehPass as Y,OutputPass as Q}from"three/examples/jsm/Addons.js";import{CSM as K}from"three/examples/jsm/csm/CSM.js";import{RectAreaLightUniformsLib as J}from"three/examples/jsm/lights/RectAreaLightUniformsLib.js";import Z from"three/examples/jsm/libs/stats.module.js";import{GTAOPass as ee}from"three/examples/jsm/postprocessing/GTAOPass.js";import{Service as te}from"typedi";import{depthUniformName as se,farUniformName as ie,nearUniformName as ae,resolutionUniformName as re,sceneNormalUniformName as ne,screenUV as oe,supportsDepthTextureExtension as le}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as he}from"./shader-nodes/time.js";import{aoMapUniformName as ue,sceneMapUniformName as de}from"./shader-nodes/scene-sample.js";import{DepthPass as ce}from"./utils/three/depth-pass.js";import{GPUStatsPanel as pe}from"./utils/three/gpu-stats-panel.js";import{OutlinePass as me}from"./utils/three/outline-pass.js";import{findFirstVisibleObject as fe,traverseVisibleStop as ge}from"./utils/three/traverse.js";import{clamp as Me}from"./utils/math.js";import{ColorPass as ve}from"./rendering/color-pass.js";import{SSRPass as Te}from"./rendering/ssr/SSRPass.js";import{SSRShader as ye}from"./rendering/ssr/SSRShader.js";import{VolumetricFogPass as be}from"./rendering/fog/volumetric-fog-pass.js";import{OutlineEffect as Pe}from"./rendering/outline-effect.js";import{UnrealBloomPass as xe}from"./rendering/bloom/UnrealBloomPass.js";import{highPrecisionEyeDepth as we}from"./shader-nodes/depth.js";import{packDepthToRGBA as Se}from"three-shader-graph";import{FogVolumeObject as Re}from"./rendering/fog/fog-volume-object";import{ParallaxStandardMaterial as Ce}from"./shader/builtin/standard-shader.js";import{parallaxOcclusionMapping as Ae}from"./shader-nodes/pom.js";import{FullScreenQuad as Ue}from"three-stdlib";import{edgeDepthEffect as Fe}from"./shader-nodes/effects";import{decalDiscard as Be}from"./shader-nodes/decal.js";import{Pass as Ie}from"three/examples/jsm/Addons.js";w.patchSetupMaterial();const Oe=document.createElement("div");Oe.style.position="absolute",Oe.style.left="50%",Oe.style.top="50%",Oe.style.color="black",Oe.style.zIndex="999";(new i.Layers).set(9);const Ee=new i.MeshBasicMaterial({color:"black"}),De=new i.MeshDepthMaterial;var Le;De.depthPacking=i.RGBADepthPacking,De.blending=i.NoBlending,De.side=i.DoubleSide,function(e){e[e.opaque=0]="opaque",e[e.transparent=1]="transparent"}(Le||(Le={}));const Ve=(()=>{const e=new Uint8Array([255,255,255,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),_e=(()=>{const e=new Uint8Array([0,0,0,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),je=(()=>{const e=new Uint8Array([128,128,255,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),Ge=new C({color:R(0),position:G(R(0))});Ge.visible=!1;const We=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let qe=0,ke=null;const Ne=new Map;function He(){return null==ke&&(ke=new IntersectionObserver(e=>{for(const t of e)if(t.isIntersecting){const e=Ne.get(t.target);e&&e()}},{threshold:0})),ke}let ze=e=class{setPaused(e){this.paused=e}resizeRender(){if(!this.running)return;const e=this.container.clientWidth,t=this.container.clientHeight;this.previousClientWith===e&&this.previousClientHeight===t||0!==e&&0!==t&&(this.previousClientWith=e,this.previousClientHeight=t,this.camera instanceof l&&(this.camera.aspect=e/t,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(e,t),this.composer.setSize(e,t),this.dofPass.setSize(e*this.renderer.getPixelRatio(),t*this.renderer.getPixelRatio()),this.fxaaPass.setSize(e*this.renderer.getPixelRatio(),t*this.renderer.getPixelRatio()),this.fxaaPass.uniforms.resolution.value.set(1/(e*this.renderer.getPixelRatio()),1/(t*this.renderer.getPixelRatio())),this.createGRenderTarget(),this.phasedRenderPass.gRenderTarget=this.gRenderTarget,this.bloomPass.emissiveTexture=this.gRenderTarget.textures[1],this.ssrPass.setSize(this.gRenderTarget.width,this.gRenderTarget.height),this.ssrPass.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.aoPass.setSize(this.gRenderTarget.width,this.gRenderTarget.height),this.aoPass.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.sceneColorRenderTarget.dispose(),this.sceneColorRenderTarget=this.createSceneColorRenderTarget(this.renderer,this.container),this.copyPass.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass.material.uniformsNeedUpdate=!0)}addPostProcessVolume(e){if(0===this.postProcessVolumes.length)this.postProcessVolumes.push(e);else{let t=!1;for(let s=0;s<this.postProcessVolumes.length;s++)if(e.priority<this.postProcessVolumes[s].priority){this.postProcessVolumes.splice(s,0,e),t=!0;break}t||this.postProcessVolumes.push(e)}}removePostProcessVolume(e){const t=this.postProcessVolumes.indexOf(e);t>-1&&this.postProcessVolumes.splice(t,1)}constructor(t,s={}){this.container=t,this.options=s,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.postProcessVolumes=[],this.postProcessSettings={},this.csmUpdateInvervals=this.options.shadows?.cascadeUpdateIntervals,this._id=qe++,this.fquadCopy=new Ue(new u(f)),this.fquadCopyOpaque=new Ue(new C({outputs:[N("tSceneColor",new c).sample(_.uv),G(N("tDepthTexture",new i.DepthTexture(1,1)).sample(_.uv).r)]})),this.lightProbeIntensity=2,this.fquadBlendAO=(()=>{const e=G(1),t=new C({outputs:[N("tAO",new c).sample(oe),e,e],transparent:!0});t.depthWrite=!1,t.depthTest=!1,t.blending=i.MultiplyBlending;return new Ue(t)})(),this.resolutionScale=1,this.maxPixelRatio=We?1:window.devicePixelRatio,this.onResize=()=>{if(this.resizeRender(),!this.paused)try{this.render()}catch(e){}},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!0,this.onLoopCallbacks=[],this.stats=new Z,this._showStats=!0,this.gbufferMaterialCache=new Map,this.tbufferMaterialCache=new Map,this.gBufferCachedMaterials=new Map,this.gBufferCachedVisibility=[],this._initiatedMaterialTextures=new Set,this._initiatedTextures=new Set,this.compileInProgress=!1,this.pmremGeneratorResults=new WeakMap,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new a,this.hadBloom=!1,this.bloomStoredMaterials={},this.bloomHidden=[],this._customDepthMaterialCache=new WeakMap,null!=s.maxPixelRatio&&(this.maxPixelRatio=s.maxPixelRatio),this.resolutionScale=s.resolutionScale??1,J.init(),window.renderer=this.renderer=window.renderer??new i.WebGLRenderer({antialias:!1,powerPreference:"high-performance"});new i.MeshStandardMaterial({color:"#ccc"});this.scene=new i.Scene,this.scene.matrixWorldAutoUpdate=!0,this.scene.updateMatrixWorld=function(e){const t=this.children;for(let s=0,i=t.length;s<i;s++){t[s].updateMatrixWorld(e)}}.bind(this.scene),this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(t.clientWidth,t.clientHeight),this.renderer.xr.enabled=this.options.enableXR??!1,!0===this.options.enableXR&&document.body.appendChild(P.createButton(this.renderer));const r=new Pe(this.renderer,{defaultThickness:.005,defaultColor:[0,0,0],defaultAlpha:1,defaultKeepAlive:!0});this.outlineEffect=r,this.createGRenderTarget(),this.composer=new g(this.renderer),this.composer.setSize(t.clientWidth,t.clientHeight);var n=(t.clientWidth||1)/(t.clientHeight||1);const o=new i.PerspectiveCamera(45,n,.5,800);o.layers.enable(19),this.setCamera(o),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=i.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=s.shadows?.autoUpdate??!1,this.renderer.outputColorSpace=i.SRGBColorSpace,this.renderer.toneMapping=i.NoToneMapping,this.renderer.toneMappingExposure=1,this.renderer.gammaFactor=1.4,w.renderingView=this,this.isDepthTextureExtensionSupported=le(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.aoMaskDepthRenderTarget=e.createAOMaskDepthRenderTarget(this.renderer,this.container),this.sceneColorRenderTarget=this.createSceneColorRenderTarget(this.renderer,this.container);const l=new i.Vector2(t.clientWidth,t.clientHeight),h=(new y(this.scene,this.camera),new b(f,"prevtexture"));h.enabled=!0,h.needsSwap=!0,h.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass=h;const d=new xe(l,1.5,.4,.85);d.threshold=1,d.strength=.9,d.radius=.5,this.bloomPass=d;const p=new ee(this.scene,this.camera,this.gRenderTarget.width,this.gRenderTarget.height,{});p.normalRenderTarget?.dispose(),p.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),p.output=ee.OUTPUT.Off,p.enabled=!1,this.aoPass=p,this.fquadBlendAO.material.uniforms.tAO.value=p.pdRenderTarget.texture,ye.fragmentShader=ye.fragmentShader.replace("if(metalness==0.) return;","if(metalness<0.1) return;");const m=new Te({renderer:this.renderer,scene:this.scene,camera:this.camera,width:this.gRenderTarget.width,height:this.gRenderTarget.height,groundReflector:null,selects:[],normalTexture:this.gRenderTarget.textures[2],depthTexture:this.gRenderTarget.depthTexture});m.output=Te.OUTPUT.Default,m.blur=!0,m.fresnel=!1,m.distanceAttenuation=!0,m.maxDistance=50,m.selective=!0,m.bouncing=!1,m.opacity=.4,m.enabled=!1!==this.options?.reflection?.enabled,this.ssrPass=m,!1!==this.options.ao?.enabled&&this.composer.addPass(p);const x=new ot((e,t,s,i,a)=>{this.aoPass.enabled&&(this.initResolutionUniform(this.fquadBlendAO.material),this.renderer.setRenderTarget(this.gRenderTarget),this.fquadBlendAO.render(this.renderer),this.renderer.setRenderTarget(null))});this.composer.addPass(x);const S=new ot((e,t,s,i,a)=>{this.renderer.setRenderTarget(this.gRenderTarget),this.renderScene(Le.transparent),this.renderer.setRenderTarget(null)});this.composer.addPass(S),this.composer.addPass(h),this.composer.addPass(m),this.phasedRenderPass=new nt(this.scene,this.camera,this.gRenderTarget),this.composer.addPass(this.phasedRenderPass),this.composer.addPass(d),d.emissiveTexture=this.gRenderTarget.textures[1],this.renderer.info.autoReset=!1,this.volumetricFogPass=new be(l),this.composer.addPass(this.volumetricFogPass),this.volumetricFogPass.enabled=!0,this.dofPass=new Y(this.scene,this.camera,{focus:1,aperture:.025,maxblur:.01}),this.dofPass.enabled=!1,this.composer.addPass(this.dofPass);const R=new ve;this.composer.addPass(R),this.colorPass=R,R.vignetteEnabled=!1,this.outlinePass=new me(new i.Vector2(t.clientWidth,t.clientHeight),this.scene,this.camera),this.outlinePass.edgeGlow=0,this.outlinePass.edgeThickness=1.5,this.outlinePass.edgeStrength=5,this.outlinePass.clear=!1,this.outlinePass.enabled=!1,this.composer.addPass(this.outlinePass);const A=new b(M);A.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(A),this.fxaaPass=A,this.fxaaPass.enabled=!1,!0===s.enableOutlines&&this.setEnableOutlines(!0),new b(v).clear=!1,this.fixStatsStyle(),this.lutPass=new T({}),this.lutPass.enabled=!1,this.composer.addPass(this.lutPass);const U=new b(f,"prevtexture");U.enabled=!0,U.needsSwap=!1,U.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[1],U.renderToScreen=!0;const F=new Q;this.composer.addPass(F)}fixStatsStyle(){const e=this.stats.dom;e.style.position="absolute";const t=e.getElementsByTagName("canvas");for(let e=0;e<t.length;e++)t.item(e).style.display="inline-block"}setEnableOutlines(e){this.outlinePass.enabled=e,this.fxaaPass.enabled=e}setCamera(e){if(this.camera=e,this.composer.passes.forEach(t=>{t instanceof y?t.camera=e:t instanceof me?t.renderCamera=e:(t instanceof ce||t instanceof ee)&&(t.camera=e)}),this.ssrPass&&(this.ssrPass.camera=e),this.aoPass&&(this.aoPass.camera=e),this.phasedRenderPass&&(this.phasedRenderPass.camera=e),null==this.csm){if(this.csm=new K({maxFar:100,lightFar:250,lightMargin:20,cascades:We?2:4,shadowMapSize:2048*(We?.5:1),lightDirection:new i.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5*Math.PI,camera:this.camera,parent:this.scene,mode:"practical"}),null!=this.csmUpdateInvervals){this.csmCascadeLastUpdate=new Array(this.csm.lights.length).fill(0);for(const e of this.csm.lights)e.shadow.autoUpdate=!1}this.csm&&Array.isArray(this.csm.lights),this.csm.fade=!0,h.lights_fragment_begin=x.lights_fragment_begin}else this.csm.camera=this.camera,this.camera;this.csm.updateFrustums()}setSelectedObjects(e){if(null==this.outlinePass)return;const t=new Map;for(const s of e)t.set(s.uuid,s);for(const s of e)s.traverse(e=>{e.uuid!==s.uuid&&t.has(e.uuid)&&t.delete(e.uuid)});this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(e,t,s){const a=Math.max(1,Math.floor(t.clientWidth*s)),r=Math.max(1,Math.floor(t.clientHeight*s)),n=new i.WebGLRenderTarget(a,r);return n.texture.minFilter=i.NearestFilter,n.texture.magFilter=i.NearestFilter,n.texture.generateMipmaps=!1,n.stencilBuffer=!1,n.depthTexture=new i.DepthTexture(a,r),n.depthTexture.type=i.UnsignedShortType,n.depthTexture.minFilter=i.NearestFilter,n.depthTexture.magFilter=i.NearestFilter,n}static createAOMaskDepthRenderTarget(e,t){const s=Math.max(1,t.clientWidth*e.getPixelRatio()),a=Math.max(1,t.clientHeight*e.getPixelRatio()),r=new i.DepthTexture(s,a);r.type=i.UnsignedInt248Type,r.minFilter=i.NearestFilter,r.magFilter=i.NearestFilter;const n=new i.WebGLRenderTarget(s,a,{type:i.HalfFloatType,depthTexture:r});return n.texture.minFilter=i.NearestFilter,n.texture.magFilter=i.NearestFilter,n.texture.generateMipmaps=!1,n.stencilBuffer=!1,n}createSceneColorRenderTarget(e,t){const s=this.gRenderTarget.width,a=this.gRenderTarget.height,r=new i.WebGLRenderTarget(s,a,{count:2,type:i.FloatType,format:i.RGBAFormat,colorSpace:i.SRGBColorSpace,depthBuffer:!1,stencilBuffer:!1});return r.texture.minFilter=i.LinearFilter,r.texture.magFilter=i.LinearFilter,r.texture.generateMipmaps=!1,r.textures[1].minFilter=i.NearestFilter,r.textures[1].magFilter=i.NearestFilter,r}createGRenderTarget(){const e=this.container;null!=this.gRenderTarget&&this.gRenderTarget.dispose();const t=Math.max(1,e.clientWidth*this.renderer.getPixelRatio()),s=Math.max(1,e.clientHeight*this.renderer.getPixelRatio()),a=new i.DepthTexture(t,s);a.type=i.UnsignedIntType,a.minFilter=i.NearestFilter,a.magFilter=i.NearestFilter,this.gRenderTarget=new d(t,s,{count:3,samples:2,minFilter:i.NearestFilter,magFilter:i.NearestFilter,type:i.HalfFloatType,format:i.RGBAFormat,depthTexture:a}),this.gRenderTarget.texture.generateMipmaps=!1,this.gRenderTarget.stencilBuffer=!1}setupEventListeners(){window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize),document.addEventListener("visibilitychange",this.onVisiblityChane)}stop(e=!0){this.running=!1,this.lightVolume?.shTexture.dispose(),window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],e&&this.renderer.dispose(),this.gRenderTarget.dispose(),this.aoMaskDepthRenderTarget.dispose(),this.sceneColorRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren();He().unobserve(this.container),Ne.delete(this.container),this.volumetricFogPass.dispose(),w.clearSceneCache(this.scene)}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);t>=0&&this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}applyEnvMap(e){if(null!=this.scene.environment&&(e instanceof C&&(null==e.envMap||e.userData.useSceneEnv)&&(e.userData.useSceneEnv=!0,null==e.uniforms.envMap&&(e.uniforms.envMap={value:this.scene.environment},e.uniformsNeedUpdate=!0,e.uniforms.envMapRotation={value:tt(this.scene.environmentRotation,this.scene.environment,new i.Matrix3)}),null==e.uniforms.envMapIntensity&&(e.uniforms.envMapIntensity={value:1},e.uniformsNeedUpdate=!0),e.uniforms.envMap.value=this.scene.environment,e.uniforms.envMapIntensity.value=this.scene.environmentIntensity,e.envMap=this.scene.environment),e instanceof C||e instanceof i.MeshStandardMaterial)){const t=this.gbufferMaterialCache.get(e);null==t||this.gbufferMaterialCache.has(t)||this.applyEnvMap(t)}}setupCsm(e){if(e instanceof i.Mesh||e instanceof i.SkinnedMesh)if(e.material instanceof Array)for(const t of e.material)this.csm.setupMaterial(t);else this.csm.setupMaterial(e.material)}updateMaterialProperties(e,t){(e instanceof i.MeshBasicMaterial||e instanceof m||e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)&&(t.uniforms.color.value.setFromColor(e.color),t.uniforms.opacity.value=e.opacity,t.uniforms.map.value=e.map,null!=t.uniforms.alphaMap&&(t.uniforms.alphaMap.value=e.alphaMap),null!=t.uniforms.lightMap&&(t.uniforms.lightMap.value=e.lightMap,t.uniforms.lightMapIntensity.value=e.lightMapIntensity),null!=t.uniforms.aoMap&&(t.uniforms.aoMap.value=e.aoMap,t.uniforms.aoMapIntensity.value=e.aoMapIntensity),null!=t.uniforms.alphaTest&&(t.uniforms.alphaTest.value=e.alphaTest)),(e instanceof m||e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)&&(t.uniforms.normalMap&&(t.uniforms.normalMap.value=e.normalMap,t.uniforms.normalScale.value=e.normalScale.x),t.uniforms.emissiveMap&&(t.uniforms.emissiveMap.value=e.emissiveMap,t.uniforms.emissive.value.setFromColor(e.emissive),t.uniforms.emissiveIntensity.value=e.emissiveIntensity)),e instanceof m&&(t.uniforms.roughnessMap.value=e.roughnessMap,t.uniforms.metalnessMap.value=e.metalnessMap,t.uniforms.roughness.value=e.roughness,t.uniforms.metalness.value=e.metalness),e instanceof Ce&&(t.uniforms.heightMap.value=e.heightMap,t.uniforms.heightScale.value=e.heightScale),this.updateMaterialCommonProperties(e,t)}updateUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e in s){const t=i[e],a=s[e].value;null!=t&&t.value!==a&&"receiveShadow"!==e&&!1===lt.includes(e)&&(t.value=a)}this.updateMaterialCommonProperties(e,t)}updateMaterialCommonProperties(e,t){t.alphaTest=e.alphaTest,t.side=e.side,t.depthTest=e.depthTest,t.blending=e.blending,t.colorWrite=e.colorWrite,t.premultipliedAlpha=e.premultipliedAlpha}updateLightUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e of lt){const t=i[e],a=s[e];null!=a&&null!=t&&(t.value=a.value)}}createGBufferMaterial(e,t){const s=t===Le.opaque?this.gbufferMaterialCache:this.tbufferMaterialCache;let a=s.get(e);if(!0===e.userData.isGBufferMaterial)return e;if(null==a){let n=_.uv;if(e instanceof Ce&&null!=e.heightMap){const t=U("heightScale",e.heightScale??1);n=Ae(n,N("heightMap",e.heightMap),t)}let o=j.normal;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=e.normalMap??je,s=U("useNormalMap",null!=e.normalMap?1:0),i=U("normalScale",e.normalScale?.x??1),a=S(N("normalMap",t).sample(n),i);o=z(j.normal,a,s)}else e instanceof C&&null!=e.outputNormal&&(o=e.outputNormal);!0!==e.userData.disableAO&&(o=k("DOUBLE_SIDED",o,e=>q(new W("gl_FrontFacing"),e,e.multiplyScalar(-1))));let l=e.userData?.reflective?R(0):R(1);if(e instanceof i.MeshStandardMaterial){const t=U("roughness",e.roughness??1),s=e.roughnessMap??Ve,i=U("useRoughnessMap",null!=e.roughnessMap?1:0),a=N("roughnessMap",s).sample(n).g.multiply(t);l=z(t,a,i)}else e instanceof C&&null!=e.outputRoughness&&(l=e.outputRoughness);let h=null;if((e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial)&&null!=e.lightMap){const t=e.lightMap,s=U("useLightMap",null!=e.lightMap?1:0),i=U("lightMapIntensity",e.lightMapIntensity??1),a=N("lightMap",t).sample(n).rgb.multiplyScalar(i);h=z(E(0),a,s)}let d=R(0);if(e instanceof i.MeshStandardMaterial){const t=U("metalness",e.metalness??0),s=e.metalnessMap??_e,i=U("useMetalnessMap",null!=e.metalnessMap?1:0),a=N("metalnessMap",s).sample(n).b.multiply(t);d=z(t,a,i)}else e instanceof C&&e.outputRoughness;let c=null,p=R(1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial){const t=e.aoMap??Ve,s=U("useAoMap",null!=e.aoMap?1:0);p=U("aoMapIntensity",e.aoMapIntensity??1);const i=N("aoMap",t).sample(n).r;c=z(R(1),i,s)}else e instanceof C&&e.outputRoughness;const f=U("opacity",e.opacity??1);let g=R(1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){if(null!=e.alphaMap){const t=e.alphaMap;g=N("alphaMap",t).sample(n).r}g=g.multiply(f)}else e instanceof C&&null!=e.outputOpacity&&(g=e.outputOpacity);let M=D(0,1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial){let t=F("color",(new i.Vector3).setFromColor(e.color));const s=e.map??Ve,a=U("useAlbedoMap",null!=e.map?1:0),r=N("map",s).sample(n),o=r.multiply(D(t,1)),l=D(t,1);M=z(l,o,a),e.vertexColors&&(M=M.multiply(G(V($.color.rgb),1)));const h=z(R(1),r.w,a);g=g.multiply(h)}const v=!0===e.userData.hasBloom;let T=E(0);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=F("emissive",(new i.Vector3).setFromColor(e.emissive)),s=U("emissiveIntensity",e.emissiveIntensity),a=e.emissiveMap??_e,r=U("useEmissiveMap",null!=e.emissiveMap?1:0),o=N("emissiveMap",a).sample(n).rgb.multiply(t);T=z(t,o,r),T=T.multiplyScalar(s)}else e instanceof C&&null!=e.outputEmissive&&(T=e.outputEmissive);const y=e instanceof u&&null!=e.uniforms[se],b=e instanceof u&&null!=e.uniforms[de],P=e instanceof u&&null!=e.uniforms[ue],x=e.transparent&&e.alphaTest<=.01||e.blending===i.AdditiveBlending,w=U("alphaTest",e.alphaTest);let L,H=e.alphaTest>0?g.lt(w):x&&t===Le.opaque?g.lt(.8):null;!0===e.userData.isDecal&&(H=H?H.or(Be):Be),L=x?G(0,0,0,0):(r=o,O(r).multiplyScalar(.5).addScalar(.5)).rgba(e.userData?.reflective?l:1);const X=e instanceof C?e.outputPosition:void 0,Y=e instanceof C?e.outputTransform:void 0;let Q,K=D("black",1);if(e instanceof C&&null!=e.outputColor)K=e.outputColor;else if(e instanceof i.MeshStandardMaterial)K=A({color:M,metalness:d,roughness:l,emissive:T.rgb,normal:o,ambientOcclusion:c,ambientOcclusionIntensity:p,bakedLight:h});else if(e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)K=I({color:M.rgb,ambientOcclusion:c,ambientOcclusionIntensity:p});else if(e instanceof i.MeshBasicMaterial){let e=M.rgb,t=h??E("black");null!=c&&(t=t.multiplyScalar(c.subtract(1).multiply(p).add(1))),e=e.add(t),K=e.rgba(g)}else e instanceof i.MeshToonMaterial&&(K=B({color:M,emissive:T.rgb,normal:o,ambientOcclusion:c,ambientOcclusionIntensity:p,bakedLight:h}));(e instanceof C||e instanceof i.MeshStandardMaterial)&&(Q=e.envMap);let J=!0;(e instanceof m||e instanceof i.MeshBasicMaterial||e instanceof i.ShaderMaterial)&&(J=e.fog);let Z=D(K.rgb,g);J&&(Z=new FogNode(Z));let ee=!0;if(t===Le.opaque?(ee&&(ee=!y&&!b&&!P),ee&&(ee=!x)):t===Le.transparent&&ee&&(ee=x||y||b||P),!ee)return a=Ge,s.set(e,a),a;a=new C({transform:Y,position:null==Y?X:void 0,outputs:[Z,T.rgba(t===Le.opaque?w:v?1:0),L],opacity:g,outputEncoding:!1,fog:J,transparent:e.transparent,lights:!0,envMap:Q,discard:H}),e instanceof i.MeshStandardMaterial&&null!=e.envMap&&null!=a.uniforms.envMapIntensity&&(a.uniforms.envMapIntensity.value=e.envMapIntensity),"alphaMap"in e&&null!=e.alphaMap&&(a.alphaMap=e.alphaMap),(e instanceof C||e instanceof i.MeshStandardMaterial)&&this.applyEnvMap(a),e instanceof C&&(Object.assign(a.defines,e.defines),null!=a.uniforms[ue]&&(a.uniforms[ue].value=this.aoPass.pdRenderTarget.texture,a.defines.USE_SSAO_MAP="")),a.userData.mrtOutputs=3,a.forceSinglePass=e.forceSinglePass,a.side=e.side,a.blending=e.blending,x?(a.depthWrite=!e.transparent,a.depthTest=e.depthTest,a.colorWrite=t===Le.transparent):(a.depthWrite=e.depthWrite,a.depthTest=e.depthTest),a.visible=e.visible,a.alphaTest=e.alphaTest,a.alphaHash=e.alphaHash,a.vertexColors=e.vertexColors,a.premultipliedAlpha=e.premultipliedAlpha,a.toneMapped=e.toneMapped,a.blendAlpha=e.blendAlpha,a.blendColor=e.blendColor,a.polygonOffset=e.polygonOffset,a.polygonOffsetFactor=e.polygonOffsetFactor,a.polygonOffsetUnits=e.polygonOffsetUnits,a.blending=e.blending,a.wireframe=e.wireframe??!1,a.userData.isGBufferMaterial=!0,a.visible=ee,Object.assign(a.userData,e.userData),a.visible&&(this.csm.setupMaterial(a),e instanceof u&&Object.assign(a.uniforms,e.uniforms)),s.set(e,a)}var r;return a.visible&&(e instanceof u?this.updateUniformValues(e,a):this.updateMaterialProperties(e,a)),this.initLightVolumeUniform(a),a}updateCsm(){const e=this.csmUpdateInvervals;if(this.renderer.shadowMap.autoUpdate&&null!=this.csmCascadeLastUpdate&&Array.isArray(e)){const t=performance.now();for(let s=0;s<this.csm.lights.length;++s){const i=e[s]??e[e.length-1]??16;if((t-this.csmCascadeLastUpdate[s]>=i||0===s)&&this.csm.lights[s].shadow){this.csm.lights[s].shadow.needsUpdate=!0,this.csmCascadeLastUpdate[s]=t;break}}}this.csm.update()}loop(e,t=!1){const s=this.stats,a=s.addPanel(new Z.Panel("Calls","#83f","#002")),r=s.addPanel(new Z.Panel("Triangles","#c32","#002"));let l;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(l=new pe(this.renderer.getContext()),s.addPanel(l)),this.showStats=t;let h=10,u=1e3;const d=()=>{const e=this.renderer.info.render.calls;e>h&&(h=e,setTimeout(()=>h=10,5e3)),a.update(e,h);const t=this.renderer.info.render.triangles;t>u&&(u=t,setTimeout(()=>u=1e3,5e3)),r.update(t,u)};performance.now();i.Ray.prototype.intersectTriangle;this.resizeRender();const c=[],p=[],m=[];let f=0;const g=new n,M=new n;let v=0;let T=this.paused,y=!1,b=0;const P=He();Ne.set(this.container,()=>{y&&(y=!1,requestAnimationFrame(()=>x(b)))}),P.observe(this.container);const x=t=>{y=!1;const a=this.renderer.getContext();if(this.paused&&this.running&&a.drawingBufferHeight>1)return y=!0,b=t,setTimeout(()=>{y&&x(t)},500),void(T=!0);if(this.renderer.clear(),this.applyPostProcessSettings(),this.renderer.autoClear=!1,this.renderer.clear(),null===this.container.offsetParent)return y=!0,b=t,void setTimeout(()=>{y&&x(t)},500);this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),s.begin(),this.showStats&&l?.startQuery(),this.ssrPass.gpuPanel=l;let r=(t*=.001)-f;if(f=t,T&&(r=.016,T=!1),g.copy(this.camera.matrixWorld),r>1){let t=r;for(;t>.05;)e($e),t-=$e;e(t)}else e(r);this.onLoopCallbacks.forEach(e=>e(r)),this.camera?.updateMatrixWorld(),M.copy(this.camera.matrixWorld),t-v>.08&&!M.equals(g)&&(this.renderer.shadowMap.needsUpdate=!0,v=t),this.updateCsm();let n=!1;c.length=0,p.length=0,m.length=0;const h=Ye;Ke.multiplyMatrices(this.camera.projectionMatrix,this.camera.matrixWorldInverse),h.setFromProjectionMatrix(Ke);let u=!1,P=!1,w=!1;this.scene.traverseVisible(e=>{if(this.setupCsm(e),this.outlineEffect.apply(e),e instanceof Re&&(u=!0),e instanceof o&&this.initCustomDepthMaterial(e),(e instanceof o||e instanceof i.Sprite)&&(this.initResolutionUniform(e.material),this.initNormalUniform(e.material),this.initShadowUniform(e,e.material),this.initLightVolumeUniform(e.material),null!=this.scene.environment&&function(e,t){if(Array.isArray(e.material))for(const s of e.material)t(s);else null!=e.material&&t(e.material)}(e,e=>this.applyEnvMap(e)),!0===e.material?.userData?.hasBloom&&(n=!0)),(e instanceof o||e instanceof i.Sprite)&&e.visible&&(e.material?.userData?.water||e.material?.uniforms&&null!=e.material?.uniforms[se])&&isObjectInFrustum(e,h)?(this.initDepthUniform(e.material),P=!0):e instanceof X&&(e.visible=!1,p.push(e)),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[ue]&&isObjectInFrustum(e,h)&&e.material instanceof C&&this.initAoUniform(e.material),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[de]&&isObjectInFrustum(e,h)&&(m.push(e),e.material.uniforms[de].value=this.sceneColorRenderTarget.texture,w=!0),e instanceof o&&e.material?.uniforms&&null!=e.material?.uniforms[he])e.material.uniforms[he].value=t;else if(e instanceof o&&Array.isArray(e.material))for(const s of e.material)s.uniforms&&null!=s.uniforms[he]&&(s.uniforms[he].value=t)}),this.bloomPass.enabled=n,this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.clear(),this.renderScene(Le.opaque),this.aoPass.output=ee.OUTPUT.Off,(P||w)&&(this.fquadCopyOpaque.material.uniforms.tSceneColor.value=this.gRenderTarget.textures[0],this.fquadCopyOpaque.material.uniforms.tDepthTexture.value=this.gRenderTarget.depthTexture,this.initResolutionUniform(this.fquadCopyOpaque.material),this.renderer.setRenderTarget(this.sceneColorRenderTarget),this.renderer.clear(),this.fquadCopyOpaque.render(this.renderer),this.renderer.setRenderTarget(this.gRenderTarget)),m.length,c.forEach(e=>e.visible=!0),p.forEach(e=>e.visible=!0),m.forEach(e=>e.visible=!0),this.aoPass.enabled,this.ssrPass&&(this.ssrPass.elapsedTime=t),this.volumetricFogPass&&u?(this.volumetricFogPass.update(this.camera,this.gRenderTarget,this.csm,this.scene),this.volumetricFogPass.enabled=!0):this.volumetricFogPass&&(this.volumetricFogPass.enabled=!1);try{!this.paused&&this.running&&(this.render(r),this.showStats&&l?.endQuery(),this.showStats&&d(),this.renderer.info.reset(),this.renderOverlay())}catch(e){console.warn(e)}s.end(),this.csm?.update(),this.running&&!0!==this.options.enableXR&&(this.fpsCap?setTimeout(()=>{requestAnimationFrame(x)},1e3/this.fpsCap):requestAnimationFrame(x))};!0===this.options.enableXR?this.renderer.setAnimationLoop(x):requestAnimationFrame(x)}applyGBufferMaterials(e){const t=this.gBufferCachedMaterials,s=this.gBufferCachedVisibility;t.clear(),s.length=0;ge(this.scene,i=>{if(at(i))return s.push(i),i.visible=!1,!1;if(i instanceof o){t.set(i,i.material);let a=!1;if(Array.isArray(i.material)){i.material=i.material.slice();for(let t=0;t<i.material.length;t++)i.material[t]=this.createGBufferMaterial(i.material[t],e),a||(a=i.material[t].visible),this.initShadowUniform(i,i.material[t])}else i.material=this.createGBufferMaterial(i.material,e),a||(a=i.material.visible),this.initShadowUniform(i,i.material);a?i.visible=!0:null!=i.children&&0!=i.children.length||(s.push(i),i.visible=!1)}})}unapplyGBufferMaterials(){this.gBufferCachedMaterials.forEach((e,t)=>{t.material=e}),this.gBufferCachedVisibility.forEach((e,t)=>{e.visible=!0,e.updateMatrixWorld(!0)})}initTextures(e=this.scene){e.traverse(e=>{if(e instanceof o)if(Array.isArray(e.material))for(let t=0;t<e.material.length;t++)this._initMaterialTextures(e.material[t]);else this._initMaterialTextures(e.material)})}_initMaterialTextures(e){if(!this._initiatedMaterialTextures.has(e))if(this._initiatedMaterialTextures.add(e),e instanceof u){for(const[t,s]of Object.entries(e.uniforms))if(s.value instanceof c){if(this._initiatedTextures.has(s.value))continue;this.renderer.initTexture(s.value),this._initiatedTextures.add(s.value)}}else for(const[t,s]of Object.entries(e))if(s instanceof c){if(this._initiatedTextures.has(s))continue;this.renderer.initTexture(s),this._initiatedTextures.add(s)}}async compileAsync(e=this.scene){if(this.compileInProgress)return;this.renderer.setRenderTarget(this.gRenderTarget),this.compileInProgress=!0,this.applyGBufferMaterials(Le.opaque),await this.renderer.compileAsync(e,this.camera),this.unapplyGBufferMaterials(),this.applyGBufferMaterials(Le.transparent),await this.renderer.compileAsync(e,this.camera),this.unapplyGBufferMaterials(),e===this.scene&&(this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.compileAsync(this.fquadBlendAO.mesh,this.fquadBlendAO.camera),this.renderer.setRenderTarget(this.sceneColorRenderTarget),this.renderer.compileAsync(this.fquadCopyOpaque.mesh,this.fquadCopyOpaque.camera));const t=this.csm.lights[0]?.shadow.camera;null!=t&&(this.applyDepthMaterial(),await this.renderer.compileAsync(e,t),this.unapplyDepthMaterial()),this.compileInProgress=!1,this.renderer.setRenderTarget(null)}applyDepthMaterial(){const e=this.gBufferCachedMaterials;e.clear(),this.scene.traverse(t=>{(t.isMesh||t.isPoints||t.isLine||t.isSprite)&&(this.initCustomDepthMaterial(t),e.set(t,t.material),t.castShadow?null!=t.customDepthMaterial?t.material=t.customDepthMaterial:t.material=ut:t.material=null)})}unapplyDepthMaterial(){this.gBufferCachedMaterials.forEach((e,t)=>{t.material=e})}renderScene(e){if(!this.running||this.paused)return;if(this.compileInProgress)return void console.error("Compile in progress, skipping render");this.applyGBufferMaterials(e);const t=this.scene.matrixWorldAutoUpdate,s=this.scene.matrixAutoUpdate,i=this.renderer.shadowMap.autoUpdate;e!==Le.opaque&&(this.renderer.shadowMap.autoUpdate=!1,this.scene.matrixWorldAutoUpdate=!1,this.scene.matrixAutoUpdate=!1);try{this.renderer.render(this.scene,this.camera)}catch(e){console.warn("Render failed",e)}e===Le.opaque&&this.gBufferCachedMaterials.forEach((e,t)=>{!Array.isArray(e)&&!Array.isArray(t.material)&&e instanceof u&&this.updateLightUniformValues(t.material,e)}),this.unapplyGBufferMaterials(),this.renderer.shadowMap.autoUpdate=i,this.scene.matrixWorldAutoUpdate=t,this.scene.matrixAutoUpdate=s}getEnvTexture(e){null==this.pmremGenerator&&(this.pmremGenerator=new i.PMREMGenerator(this.renderer),this.pmremGenerator.compileEquirectangularShader());let t=this.pmremGeneratorResults.get(e);return null==t&&(t=this.pmremGenerator.fromEquirectangular(e).texture,this.pmremGeneratorResults.set(e,t)),t.colorSpace=i.SRGBColorSpace,t}applyPostProcessSettings(){if(0==this.postProcessVolumes.length)return this.lutPass.enabled=!1,void(this.colorPass.enabled=!1);var e;(e=this.postProcessSettings).tonemapMapping=void 0,e.tonemapExposure=1,e.envIntensity=1,e.envTexture=void 0,e.vignetteIntensity=0,e.colorTint=new i.Color("white"),e.colorTintIntensity=0,e.depthFocus=void 0,e.depthAperture=void 0,e.depthMaxBlur=void 0,e.temperature=6500,e.temperatureTint=0,e.lut=void 0,e.lutIntensity=0;const t=this.postProcessSettings;let s,a=!1,r=!1,n=!1,o=!1;if(null==this.camera)return;const h=this.camera.getWorldPosition(Je);let u=[];for(const e of this.postProcessVolumes){if(!Xe(e.object))continue;let l=e.blendWeight??1;const d=e.distanceToPoint(h);d>e.blendRadius||(e.blendRadius>0&&(l*=Me(1-d/e.blendRadius,0,1)),l>1&&(l=1),l>0&&(u.push(e),void 0!==e.settings.tonemapMapping&&(t.tonemapMapping=e.settings.tonemapMapping),void 0!==e.settings.tonemapExposure&&(t.tonemapExposure=i.MathUtils.lerp(t.tonemapExposure,e.settings.tonemapExposure,l)),void 0!==e.settings.envTexture&&(t.envTexture=e.settings.envTexture),void 0!==e.settings.envIntensity&&(t.envIntensity=i.MathUtils.lerp(t.envIntensity,e.settings.envIntensity,l)),void 0!==e.settings.vignetteIntensity&&(t.vignetteIntensity=i.MathUtils.lerp(t.vignetteIntensity,e.settings.vignetteIntensity,l),r=!0),void 0!==e.settings.colorTint&&void 0!==e.settings.colorTintIntensity&&e.settings.colorTintIntensity>0&&(t.colorTint=t.colorTint.lerp(e.settings.colorTint,l),o=!0),void 0!==e.settings.colorTintIntensity&&(t.colorTintIntensity=i.MathUtils.lerp(t.colorTintIntensity,e.settings.colorTintIntensity,l)),void 0!==e.settings.depthFocus&&(a=!0,t.depthFocus=void 0!==t.depthFocus?i.MathUtils.lerp(t.depthFocus,e.settings.depthFocus,l):e.settings.depthFocus),void 0!==e.settings.depthAperture&&(a=!0,t.depthAperture=void 0!==t.depthAperture?i.MathUtils.lerp(t.depthAperture,e.settings.depthAperture,l):e.settings.depthAperture),void 0!==e.settings.depthMaxBlur&&(a=!0,t.depthMaxBlur=void 0!==t.depthMaxBlur?i.MathUtils.lerp(t.depthMaxBlur,e.settings.depthMaxBlur,l):e.settings.depthMaxBlur),void 0!==e.settings.temperature&&(t.temperature=i.MathUtils.lerp(t.temperature,e.settings.temperature,l)),void 0!==e.settings.temperatureTint&&(t.temperatureTint=i.MathUtils.lerp(t.temperatureTint,e.settings.temperatureTint,l)),void 0!==e.settings.lut&&(s=e.settings.lut,n=!0),void 0!==e.settings.lutIntensity&&(t.lutIntensity=i.MathUtils.lerp(t.lutIntensity,e.settings.lutIntensity,l),n=!0)))}this.renderer.toneMapping=t.tonemapMapping??i.NoToneMapping,this.renderer.toneMappingExposure=t.tonemapExposure,null!=t.envTexture&&(this.scene.environment=this.getEnvTexture(t.envTexture)),this.scene.environmentIntensity=t.envIntensity,this.colorPass.vignetteIntensity=t.vignetteIntensity,this.colorPass.vignetteEnabled=r,this.colorPass.colorTint=t.colorTint,this.colorPass.colorTintIntensity=t.colorTintIntensity,this.colorPass.enabled=r||o,a&&this.camera instanceof l?(this.dofPass.enabled=!0,void 0!==t.depthFocus&&(this.dofPass.uniforms.focus.value=t.depthFocus),void 0!==t.depthAperture&&(this.dofPass.uniforms.aperture.value=t.depthAperture),void 0!==t.depthMaxBlur&&(this.dofPass.uniforms.maxblur.value=t.depthMaxBlur)):this.dofPass.enabled=!1,this.colorPass.temperature=t.temperature,this.colorPass.temperatureTint=t.temperatureTint,this.lutPass.enabled=n,n&&(null!=s&&(s.flipY=!0,s.generateMipmaps=!1),this.lutPass.lut=s,this.lutPass.intensity=t.lutIntensity)}renderOverlay(){if(!this.running)return;if(0===this.overlayCameras.size)return;const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.previousClientWith/2,s=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let i=0;i<e.length;i++)this.renderer.clearDepth(),this.renderer.setViewport(t-s/2+this.insetWidth*i+this.insetMargin*i,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[i])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){if(!this.running||null===this.container.offsetParent)return;if(this.renderer.domElement.parentElement!==this.container&&(this.container.replaceChildren(this.renderer.domElement),this.resizeRender()),0===this.composer.renderTarget1.width||0===this.composer.renderTarget1.height)return;if(0===this.composer.renderTarget2.width||0===this.composer.renderTarget2.height)return;let t=!1;if(this.ssrPass.enabled&&!1!==this.options?.reflection?.enabled){const e=this.ssrPass.selects??[];e.length=0,this.scene.traverseVisible(t=>{t instanceof o&&!0===t.material.userData?.reflective&&isObjectInFrustum(t,Ye)&&e.push(t)}),this.ssrPass.selects=e,0==e.length&&(this.ssrPass.enabled=!1),t=!0}this.options.bloom,this.composer.render(e),this.scene.matrixWorldAutoUpdate=!0,this.scene.matrixAutoUpdate=!0,t&&(this.ssrPass.enabled=!0)}hasBloom(){return null!=fe(this.scene,e=>e instanceof o&&!0===e.material?.userData?.hasBloom)}darkenNonBloomed(e){if((e instanceof o||e instanceof i.Sprite||e instanceof i.Line)&&e.visible&&(null==e.material.userData||!0!==e.material.userData.hasBloom)){if(e.material?.id===Ee.id)return;this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=Ee:(e.visible=!1,this.bloomHidden.push(e))}else"TransformControlsPlane"!==e.type&&"TransformControlsGizmo"!==e.type||(e.visible=!1,this.bloomHidden.push(e))}restoreMaterial(e){this.bloomStoredMaterials[e.uuid]&&(e.material=this.bloomStoredMaterials[e.uuid],delete this.bloomStoredMaterials[e.uuid],e.visible=!0)}initDepthUniform(e){e instanceof u&&(e.uniforms[se].value=this.sceneColorRenderTarget.textures[1],this.camera instanceof l&&(null!=e.uniforms[ae]&&(e.uniforms[ae].value=this.camera.near),null!=e.uniforms[ie]&&(e.uniforms[ie].value=this.camera.far)))}initNormalUniform(e){e instanceof u&&null!=e.uniforms[ne]&&(e.uniforms[ne].value=this.gRenderTarget.textures[2])}initShadowUniform(e,t){t instanceof C&&(t.uniforms.receiveShadow?t.uniforms.receiveShadow.value=e.receiveShadow:t.uniforms.receiveShadow={value:e.receiveShadow})}initLightVolumeUniform(e){e instanceof C&&(null!=this.lightVolume?null==e.uniforms.uSH?(e.defines.USE_LIGHT_PROBE_VOLUME="",e.uniforms.gridOrigin={value:this.lightVolume.gridOrigin},e.uniforms.gridSize={value:this.lightVolume.gridSize},e.uniforms.gridRes={value:this.lightVolume.gridResolution},e.uniforms.giIntensity={value:this.lightProbeIntensity},e.uniforms.uSH={value:this.lightVolume.shTexture},e.uniformsNeedUpdate=!0,e.needsUpdate=!0):e.uniforms.giIntensity.value=this.lightProbeIntensity:null!=e.uniforms.uSH&&(delete e.defines.USE_LIGHT_PROBE_VOLUME,delete e.uniforms.gridOrigin,delete e.uniforms.gridSize,delete e.uniforms.gridRes,delete e.uniforms.giIntensity,delete e.uniforms.uSH,e.uniformsNeedUpdate=!0,e.needsUpdate=!0))}initResolutionUniform(e){e instanceof u&&null!=e.uniforms[re]&&e.uniforms[re].value.set(this.gRenderTarget.width,this.gRenderTarget.height)}initAoUniform(e){if(this.aoPass.enabled){e.uniforms[ue].value=this.aoPass.pdRenderTarget.texture,null==e.defines.USE_SSAO_MAP&&(e.defines.USE_SSAO_MAP="",e.needsUpdate=!0),e.defines.USE_SSAO_MAP="";const t=this.tbufferMaterialCache.get(e);null!=t&&this.initAoUniform(t)}else if(null!=e.defines.USE_SSAO_MAP){delete e.defines.USE_SSAO_MAP,e.needsUpdate=!0;const t=this.tbufferMaterialCache.get(e);null!=t&&this.initAoUniform(t)}}initCustomDepthMaterial(e){if(null!=e.customDepthMaterial||!e.castShadow)return;const t=e.material;if(t instanceof C&&!t.transparent&&t.depthWrite){let s=this._customDepthMaterialCache.get(t);if(null==s){const e=Se(we);let i;null!=t.alphaTest&&t.alphaTest>0&&null!=t.outputOpacity&&(i=t.outputOpacity.lt(t.alphaTest)),s=new C({color:e,discard:i}),this._customDepthMaterialCache.set(t,s)}e.customDepthMaterial=s}}};ze=e=t([te(),s("design:paramtypes",[HTMLElement,Object])],ze);export{ze as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const $e=.05;function Xe(e){let t=e;for(;t;){if(!1===t.visible)return!1;t=t.parent}return!0}ee.prototype.overrideVisibility=function(){const e=this.scene,t=this._visibilityCache;e.traverse(function(e){if(t.set(e,e.visible),(e.isPoints||e.isLine||e.isTransformControls||e.isSprite)&&(e.visible=!1),null!=e.material){let t=!1,s=!1;if(Array.isArray(e.material)){for(const s of e.material)if(null!=s.alphaTest&&s.alphaTest>0){t=!0;break}}else null!=e.material.alphaTest&&e.material.alphaTest>0?t=!0:!0===e.material.userData.isDecal&&(s=!0);s&&(e.visible=!1)}})};const Ye=new i.Frustum,Qe=new i.Box3,Ke=new i.Matrix4;export function isObjectInFrustum(e,t){const s=Qe.setFromObject(e);return t.intersectsBox(s)}const Je=new i.Vector3;const Ze=new n,et=new p;function tt(e,t,s=new i.Matrix3){return et.copy(e),et.x*=-1,et.y*=-1,et.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(et.y*=-1,et.z*=-1),s.setFromMatrix4(Ze.makeRotationFromEuler(et))}const st=new C({outputs:[G(0,0,0,0),G(0,0,0,0),D(E("white"),Fe(4))],transparent:!0}),it=new i.MeshBasicMaterial({color:"blue",transparent:!0,opacity:.5});st.depthWrite=!1;new o(new i.BoxGeometry(4,4,4),it);function at(e){return e instanceof i.Sprite||e.isPoints||e.isLine||e.isLineSegments2||e.isTransformControls||e.isTransformControlsGizmo||e instanceof o&&rt(e,e.material)}function rt(e,t){return null==t||(Array.isArray(t)?t.some(t=>rt(e,t)):t instanceof i.RawShaderMaterial||t instanceof i.ShaderMaterial&&!(t instanceof C))}class nt extends Ie{constructor(e,t,s){super(),this.scene=e,this.camera=t,this.gRenderTarget=s,this.cachedVisibility=[],this.toRender=[],this.needsSwap=!1}render(e,t,s,i,a){const r=e.autoClear;e.autoClear=!1;const n=this.scene.matrixWorldAutoUpdate,l=this.scene.matrixAutoUpdate,h=e.shadowMap.autoUpdate;this.scene.matrixAutoUpdate=!1,e.shadowMap.autoUpdate=!1;const u=s.depthTexture;s.depthTexture=this.gRenderTarget.depthTexture,e.setRenderTarget(s),this.cachedVisibility.length=0;let d=0,c=this.toRender;if(c.length=0,this.scene.traverseVisible(e=>{const t=at(e);e instanceof o&&!t?(this.cachedVisibility.push(e),e.visible=!1):t&&(d++,c.push(e))}),d>0)for(const t of c)e.render(t,this.camera);this.cachedVisibility.forEach((e,t)=>{e.visible=!0}),e.setRenderTarget(null),e.autoClear=r,s.depthTexture=u,this.scene.matrixWorldAutoUpdate=n,this.scene.matrixAutoUpdate=l,e.shadowMap.autoUpdate=h}}class ot extends Ie{constructor(e){super(),this.fn=e}render(e,t,s,i,a){this.fn(e,t,s,i,a)}}const lt=["ambientLightColor","cameraNear","directionalLightShadows","directionalLights","directionalShadowMap","directionalShadowMatrix","fogColor","fogDensity","fogFar","fogNear","hemisphereLights","lightProbe","ltc_1","ltc_2","pointLightShadows","pointLights","pointShadowMap","pointShadowMatrix","rectAreaLights","shadowFar","spotLightMap","spotLightMatrix","spotLightShadows","spotLights","spotShadowMap"],ht=F("fogColor");export class FogNode extends H{constructor(e,t=ht){super(),this.source=e,this.fogColor=t}compile(e){const t=e.variable(),s=e.get(this.source.rgb),i=e.get(this.source.a),a=e.get(this.fogColor),r=e.get(U("fogFar")),n=e.get(U("fogNear")),o=e.get(U("fogDensity")),l=e.get(V(L.mvPosition.z));return{pars:"\n ",chunk:`\n #ifdef FOG_EXP2\n float fogFactor_${t} = 1.0 - exp( - ${o} * ${o} * ${l} * ${l} );\n #else\n float fogFactor_${t} = smoothstep( ${n}, ${r}, ${l} );\n #endif\n vec4 color_vec4_${t} = vec4(mix(${s}, ${a}, fogFactor_${t}), ${i});\n `,out:`color_vec4_${t}`}}}const ut=new i.MeshDepthMaterial({depthPacking:i.RGBADepthPacking});/*
1
+ var e;import{__decorate as t,__metadata as s}from"tslib";import*as i from"three";import{Color as a,Material as r,Matrix4 as n,Mesh as o,PerspectiveCamera as l,ShaderChunk as h,ShaderMaterial as u,WebGLRenderTarget as d,Texture as c,Euler as p,MeshStandardMaterial as m}from"three";import{CopyShader as f,EffectComposer as g,FXAAShader as M,GammaCorrectionShader as v,LUTPass as T,RenderPass as y,ShaderPass as b,VRButton as w}from"three-stdlib";import{CSMShader as x,CSMUtil as P}from"./csm.js";import{colorToNormal as S,float as R,NodeShaderMaterial as C,standardMaterial as A,uniformFloat as U,uniformVec3 as F,toonMaterial as I,lambertMaterial as B,normalize as O,rgb as E,rgba as D,transformed as L,varying as V,varyingAttributes as _,varyingTransformed as j,vec4 as G,BooleanExpression as W,select as q,ifDefApply as k,uniformSampler2d as N,RgbaNode as H,mix as z,attributes as $}from"three-shader-graph";import{Reflector as X}from"three-stdlib";import{BokehPass as Y,OutputPass as Q}from"three/examples/jsm/Addons.js";import{CSM as K}from"three/examples/jsm/csm/CSM.js";import{RectAreaLightUniformsLib as J}from"three/examples/jsm/lights/RectAreaLightUniformsLib.js";import Z from"three/examples/jsm/libs/stats.module.js";import{GTAOPass as ee}from"three/examples/jsm/postprocessing/GTAOPass.js";import{Service as te}from"typedi";import{depthUniformName as se,farUniformName as ie,nearUniformName as ae,resolutionUniformName as re,sceneNormalUniformName as ne,screenUV as oe,supportsDepthTextureExtension as le}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as he}from"./shader-nodes/time.js";import{aoMapUniformName as ue,sceneMapUniformName as de}from"./shader-nodes/scene-sample.js";import{DepthPass as ce}from"./utils/three/depth-pass.js";import{GPUStatsPanel as pe}from"./utils/three/gpu-stats-panel.js";import{OutlinePass as me}from"./utils/three/outline-pass.js";import{findFirstVisibleObject as fe,traverseVisibleStop as ge}from"./utils/three/traverse.js";import{clamp as Me}from"./utils/math.js";import{ColorPass as ve}from"./rendering/color-pass.js";import{SSRPass as Te}from"./rendering/ssr/SSRPass.js";import{SSRShader as ye}from"./rendering/ssr/SSRShader.js";import{VolumetricFogPass as be}from"./rendering/fog/volumetric-fog-pass.js";import{OutlineEffect as we}from"./rendering/outline-effect.js";import{UnrealBloomPass as xe}from"./rendering/bloom/UnrealBloomPass.js";import{highPrecisionEyeDepth as Pe}from"./shader-nodes/depth.js";import{packDepthToRGBA as Se}from"three-shader-graph";import{FogVolumeObject as Re}from"./rendering/fog/fog-volume-object";import{ParallaxStandardMaterial as Ce}from"./shader/builtin/standard-shader.js";import{parallaxOcclusionMapping as Ae}from"./shader-nodes/pom.js";import{FullScreenQuad as Ue}from"three-stdlib";import{edgeDepthEffect as Fe}from"./shader-nodes/effects";import{decalDiscard as Ie}from"./shader-nodes/decal.js";import{Pass as Be}from"three/examples/jsm/Addons.js";P.patchSetupMaterial();const Oe=document.createElement("div");Oe.style.position="absolute",Oe.style.left="50%",Oe.style.top="50%",Oe.style.color="black",Oe.style.zIndex="999";(new i.Layers).set(9);const Ee=new i.MeshBasicMaterial({color:"black"}),De=new i.MeshDepthMaterial;var Le;De.depthPacking=i.RGBADepthPacking,De.blending=i.NoBlending,De.side=i.DoubleSide,function(e){e[e.opaque=0]="opaque",e[e.transparent=1]="transparent"}(Le||(Le={}));const Ve=(()=>{const e=new Uint8Array([255,255,255,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),_e=(()=>{const e=new Uint8Array([0,0,0,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),je=(()=>{const e=new Uint8Array([128,128,255,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),Ge=new C({color:R(0),position:G(R(0))});Ge.visible=!1;const We=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let qe=0,ke=null;const Ne=new Map;function He(){return null==ke&&(ke=new IntersectionObserver(e=>{for(const t of e){const e=Ne.get(t.target);e&&e(t.isIntersecting)}},{threshold:0})),ke}let ze=e=class{setPaused(e){this.paused=e}resizeRender(){if(!this.running)return;const e=this.container.clientWidth,t=this.container.clientHeight;this.previousClientWith===e&&this.previousClientHeight===t||0!==e&&0!==t&&(this.previousClientWith=e,this.previousClientHeight=t,this.camera instanceof l&&(this.camera.aspect=e/t,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(e,t),this.composer.setSize(e,t),this.dofPass.setSize(e*this.renderer.getPixelRatio(),t*this.renderer.getPixelRatio()),this.fxaaPass.setSize(e*this.renderer.getPixelRatio(),t*this.renderer.getPixelRatio()),this.fxaaPass.uniforms.resolution.value.set(1/(e*this.renderer.getPixelRatio()),1/(t*this.renderer.getPixelRatio())),this.createGRenderTarget(),this.phasedRenderPass.gRenderTarget=this.gRenderTarget,this.bloomPass.emissiveTexture=this.gRenderTarget.textures[1],this.ssrPass.setSize(this.gRenderTarget.width,this.gRenderTarget.height),this.ssrPass.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.aoPass.setSize(this.gRenderTarget.width,this.gRenderTarget.height),this.aoPass.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.sceneColorRenderTarget.dispose(),this.sceneColorRenderTarget=this.createSceneColorRenderTarget(this.renderer,this.container),this.copyPass.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass.material.uniformsNeedUpdate=!0)}addPostProcessVolume(e){if(0===this.postProcessVolumes.length)this.postProcessVolumes.push(e);else{let t=!1;for(let s=0;s<this.postProcessVolumes.length;s++)if(e.priority<this.postProcessVolumes[s].priority){this.postProcessVolumes.splice(s,0,e),t=!0;break}t||this.postProcessVolumes.push(e)}}removePostProcessVolume(e){const t=this.postProcessVolumes.indexOf(e);t>-1&&this.postProcessVolumes.splice(t,1)}constructor(t,s={}){this.container=t,this.options=s,this.isIntersecting=!1,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.postProcessVolumes=[],this.postProcessSettings={},this.csmUpdateInvervals=this.options.shadows?.cascadeUpdateIntervals,this._id=qe++,this.fquadCopy=new Ue(new u(f)),this.fquadCopyOpaque=new Ue(new C({outputs:[N("tSceneColor",new c).sample(_.uv),G(N("tDepthTexture",new i.DepthTexture(1,1)).sample(_.uv).r)]})),this.lightProbeIntensity=2,this.fquadBlendAO=(()=>{const e=G(1),t=new C({outputs:[N("tAO",new c).sample(oe),e,e],transparent:!0});t.depthWrite=!1,t.depthTest=!1,t.blending=i.MultiplyBlending;return new Ue(t)})(),this.resolutionScale=1,this.maxPixelRatio=We?1:window.devicePixelRatio,this.onResize=()=>{if(this.resizeRender(),!this.paused)try{this.render()}catch(e){}},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!0,this.onLoopCallbacks=[],this.stats=new Z,this._showStats=!0,this.gbufferMaterialCache=new Map,this.tbufferMaterialCache=new Map,this.gBufferCachedMaterials=new Map,this.gBufferCachedVisibility=[],this._initiatedMaterialTextures=new Set,this._initiatedTextures=new Set,this.compileInProgress=!1,this.pmremGeneratorResults=new WeakMap,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new a,this.hadBloom=!1,this.bloomStoredMaterials={},this.bloomHidden=[],this._customDepthMaterialCache=new WeakMap,null!=s.maxPixelRatio&&(this.maxPixelRatio=s.maxPixelRatio),this.resolutionScale=s.resolutionScale??1,e.activeView=this,J.init(),window.renderer=this.renderer=window.renderer??new i.WebGLRenderer({antialias:!1,powerPreference:"high-performance"});new i.MeshStandardMaterial({color:"#ccc"});this.scene=new i.Scene,this.scene.matrixWorldAutoUpdate=!0,this.scene.updateMatrixWorld=function(e){const t=this.children;for(let s=0,i=t.length;s<i;s++){t[s].updateMatrixWorld(e)}}.bind(this.scene),this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(t.clientWidth,t.clientHeight),this.renderer.xr.enabled=this.options.enableXR??!1,!0===this.options.enableXR&&document.body.appendChild(w.createButton(this.renderer));const r=new we(this.renderer,{defaultThickness:.005,defaultColor:[0,0,0],defaultAlpha:1,defaultKeepAlive:!0});this.outlineEffect=r,this.createGRenderTarget(),this.composer=new g(this.renderer),this.composer.setSize(t.clientWidth,t.clientHeight);var n=(t.clientWidth||1)/(t.clientHeight||1);const o=new i.PerspectiveCamera(45,n,.5,800);o.layers.enable(19),this.setCamera(o),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=i.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=s.shadows?.autoUpdate??!1,this.renderer.outputColorSpace=i.SRGBColorSpace,this.renderer.toneMapping=i.NoToneMapping,this.renderer.toneMappingExposure=1,this.renderer.gammaFactor=1.4,P.renderingView=this,this.isDepthTextureExtensionSupported=le(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.aoMaskDepthRenderTarget=e.createAOMaskDepthRenderTarget(this.renderer,this.container),this.sceneColorRenderTarget=this.createSceneColorRenderTarget(this.renderer,this.container);const l=new i.Vector2(t.clientWidth,t.clientHeight),h=(new y(this.scene,this.camera),new b(f,"prevtexture"));h.enabled=!0,h.needsSwap=!0,h.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass=h;const d=new xe(l,1.5,.4,.85);d.threshold=1,d.strength=.9,d.radius=.5,this.bloomPass=d;const p=new ee(this.scene,this.camera,this.gRenderTarget.width,this.gRenderTarget.height,{});p.normalRenderTarget?.dispose(),p.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),p.output=ee.OUTPUT.Off,p.enabled=!1,this.aoPass=p,this.fquadBlendAO.material.uniforms.tAO.value=p.pdRenderTarget.texture,ye.fragmentShader=ye.fragmentShader.replace("if(metalness==0.) return;","if(metalness<0.1) return;");const m=new Te({renderer:this.renderer,scene:this.scene,camera:this.camera,width:this.gRenderTarget.width,height:this.gRenderTarget.height,groundReflector:null,selects:[],normalTexture:this.gRenderTarget.textures[2],depthTexture:this.gRenderTarget.depthTexture});m.output=Te.OUTPUT.Default,m.blur=!0,m.fresnel=!1,m.distanceAttenuation=!0,m.maxDistance=50,m.selective=!0,m.bouncing=!1,m.opacity=.4,m.enabled=!1!==this.options?.reflection?.enabled,this.ssrPass=m,!1!==this.options.ao?.enabled&&this.composer.addPass(p);const x=new ot((e,t,s,i,a)=>{this.aoPass.enabled&&(this.initResolutionUniform(this.fquadBlendAO.material),this.renderer.setRenderTarget(this.gRenderTarget),this.fquadBlendAO.render(this.renderer),this.renderer.setRenderTarget(null))});this.composer.addPass(x);const S=new ot((e,t,s,i,a)=>{this.renderer.setRenderTarget(this.gRenderTarget),this.renderScene(Le.transparent),this.renderer.setRenderTarget(null)});this.composer.addPass(S),this.composer.addPass(h),this.composer.addPass(m),this.phasedRenderPass=new nt(this.scene,this.camera,this.gRenderTarget),this.composer.addPass(this.phasedRenderPass),this.composer.addPass(d),d.emissiveTexture=this.gRenderTarget.textures[1],this.renderer.info.autoReset=!1,this.volumetricFogPass=new be(l),this.composer.addPass(this.volumetricFogPass),this.volumetricFogPass.enabled=!0,this.dofPass=new Y(this.scene,this.camera,{focus:1,aperture:.025,maxblur:.01}),this.dofPass.enabled=!1,this.composer.addPass(this.dofPass);const R=new ve;this.composer.addPass(R),this.colorPass=R,R.vignetteEnabled=!1,this.outlinePass=new me(new i.Vector2(t.clientWidth,t.clientHeight),this.scene,this.camera),this.outlinePass.edgeGlow=0,this.outlinePass.edgeThickness=1.5,this.outlinePass.edgeStrength=5,this.outlinePass.clear=!1,this.outlinePass.enabled=!1,this.composer.addPass(this.outlinePass);const A=new b(M);A.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(A),this.fxaaPass=A,this.fxaaPass.enabled=!1,!0===s.enableOutlines&&this.setEnableOutlines(!0),new b(v).clear=!1,this.fixStatsStyle(),this.lutPass=new T({}),this.lutPass.enabled=!1,this.composer.addPass(this.lutPass);const U=new b(f,"prevtexture");U.enabled=!0,U.needsSwap=!1,U.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[1],U.renderToScreen=!0;const F=new Q;this.composer.addPass(F)}fixStatsStyle(){const e=this.stats.dom;e.style.position="absolute";const t=e.getElementsByTagName("canvas");for(let e=0;e<t.length;e++)t.item(e).style.display="inline-block"}setEnableOutlines(e){this.outlinePass.enabled=e,this.fxaaPass.enabled=e}setCamera(e){if(this.camera=e,this.composer.passes.forEach(t=>{t instanceof y?t.camera=e:t instanceof me?t.renderCamera=e:(t instanceof ce||t instanceof ee)&&(t.camera=e)}),this.ssrPass&&(this.ssrPass.camera=e),this.aoPass&&(this.aoPass.camera=e),this.phasedRenderPass&&(this.phasedRenderPass.camera=e),null==this.csm){if(this.csm=new K({maxFar:100,lightFar:250,lightMargin:20,cascades:We?2:4,shadowMapSize:2048*(We?.5:1),lightDirection:new i.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5*Math.PI,camera:this.camera,parent:this.scene,mode:"practical"}),null!=this.csmUpdateInvervals){this.csmCascadeLastUpdate=new Array(this.csm.lights.length).fill(0);for(const e of this.csm.lights)e.shadow.autoUpdate=!1}this.csm&&Array.isArray(this.csm.lights),this.csm.fade=!0,h.lights_fragment_begin=x.lights_fragment_begin}else this.csm.camera=this.camera,this.camera;this.csm.updateFrustums()}setSelectedObjects(e){if(null==this.outlinePass)return;const t=new Map;for(const s of e)t.set(s.uuid,s);for(const s of e)s.traverse(e=>{e.uuid!==s.uuid&&t.has(e.uuid)&&t.delete(e.uuid)});this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(e,t,s){const a=Math.max(1,Math.floor(t.clientWidth*s)),r=Math.max(1,Math.floor(t.clientHeight*s)),n=new i.WebGLRenderTarget(a,r);return n.texture.minFilter=i.NearestFilter,n.texture.magFilter=i.NearestFilter,n.texture.generateMipmaps=!1,n.stencilBuffer=!1,n.depthTexture=new i.DepthTexture(a,r),n.depthTexture.type=i.UnsignedShortType,n.depthTexture.minFilter=i.NearestFilter,n.depthTexture.magFilter=i.NearestFilter,n}static createAOMaskDepthRenderTarget(e,t){const s=Math.max(1,t.clientWidth*e.getPixelRatio()),a=Math.max(1,t.clientHeight*e.getPixelRatio()),r=new i.DepthTexture(s,a);r.type=i.UnsignedInt248Type,r.minFilter=i.NearestFilter,r.magFilter=i.NearestFilter;const n=new i.WebGLRenderTarget(s,a,{type:i.HalfFloatType,depthTexture:r});return n.texture.minFilter=i.NearestFilter,n.texture.magFilter=i.NearestFilter,n.texture.generateMipmaps=!1,n.stencilBuffer=!1,n}createSceneColorRenderTarget(e,t){const s=this.gRenderTarget.width,a=this.gRenderTarget.height,r=new i.WebGLRenderTarget(s,a,{count:2,type:i.FloatType,format:i.RGBAFormat,colorSpace:i.SRGBColorSpace,depthBuffer:!1,stencilBuffer:!1});return r.texture.minFilter=i.LinearFilter,r.texture.magFilter=i.LinearFilter,r.texture.generateMipmaps=!1,r.textures[1].minFilter=i.NearestFilter,r.textures[1].magFilter=i.NearestFilter,r}createGRenderTarget(){const e=this.container;null!=this.gRenderTarget&&this.gRenderTarget.dispose();const t=Math.max(1,e.clientWidth*this.renderer.getPixelRatio()),s=Math.max(1,e.clientHeight*this.renderer.getPixelRatio()),a=new i.DepthTexture(t,s);a.type=i.UnsignedIntType,a.minFilter=i.NearestFilter,a.magFilter=i.NearestFilter,this.gRenderTarget=new d(t,s,{count:3,samples:2,minFilter:i.NearestFilter,magFilter:i.NearestFilter,type:i.HalfFloatType,format:i.RGBAFormat,depthTexture:a}),this.gRenderTarget.texture.generateMipmaps=!1,this.gRenderTarget.stencilBuffer=!1}setupEventListeners(){window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize),document.addEventListener("visibilitychange",this.onVisiblityChane)}stop(e=!0){this.running=!1,this.lightVolume?.shTexture.dispose(),window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],e&&this.renderer.dispose(),this.gRenderTarget.dispose(),this.aoMaskDepthRenderTarget.dispose(),this.sceneColorRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren();He().unobserve(this.container),Ne.delete(this.container),this.volumetricFogPass.dispose(),P.clearSceneCache(this.scene)}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);t>=0&&this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}applyEnvMap(e){if(null!=this.scene.environment&&(e instanceof C&&(null==e.envMap||e.userData.useSceneEnv)&&(e.userData.useSceneEnv=!0,null==e.uniforms.envMap&&(e.uniforms.envMap={value:this.scene.environment},e.uniformsNeedUpdate=!0,e.uniforms.envMapRotation={value:tt(this.scene.environmentRotation,this.scene.environment,new i.Matrix3)}),null==e.uniforms.envMapIntensity&&(e.uniforms.envMapIntensity={value:1},e.uniformsNeedUpdate=!0),e.uniforms.envMap.value=this.scene.environment,e.uniforms.envMapIntensity.value=this.scene.environmentIntensity,e.envMap=this.scene.environment),e instanceof C||e instanceof i.MeshStandardMaterial)){const t=this.gbufferMaterialCache.get(e);null==t||this.gbufferMaterialCache.has(t)||this.applyEnvMap(t)}}setupCsm(e){if(e instanceof i.Mesh||e instanceof i.SkinnedMesh)if(e.material instanceof Array)for(const t of e.material)this.csm.setupMaterial(t);else this.csm.setupMaterial(e.material)}updateMaterialProperties(e,t){(e instanceof i.MeshBasicMaterial||e instanceof m||e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)&&(t.uniforms.color.value.setFromColor(e.color),t.uniforms.opacity.value=e.opacity,t.uniforms.map.value=e.map,null!=t.uniforms.alphaMap&&(t.uniforms.alphaMap.value=e.alphaMap),null!=t.uniforms.lightMap&&(t.uniforms.lightMap.value=e.lightMap,t.uniforms.lightMapIntensity.value=e.lightMapIntensity),null!=t.uniforms.aoMap&&(t.uniforms.aoMap.value=e.aoMap,t.uniforms.aoMapIntensity.value=e.aoMapIntensity),null!=t.uniforms.alphaTest&&(t.uniforms.alphaTest.value=e.alphaTest)),(e instanceof m||e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)&&(t.uniforms.normalMap&&(t.uniforms.normalMap.value=e.normalMap,t.uniforms.normalScale.value=e.normalScale.x),t.uniforms.emissiveMap&&(t.uniforms.emissiveMap.value=e.emissiveMap,t.uniforms.emissive.value.setFromColor(e.emissive),t.uniforms.emissiveIntensity.value=e.emissiveIntensity)),e instanceof m&&(t.uniforms.roughnessMap.value=e.roughnessMap,t.uniforms.metalnessMap.value=e.metalnessMap,t.uniforms.roughness.value=e.roughness,t.uniforms.metalness.value=e.metalness),e instanceof Ce&&(t.uniforms.heightMap.value=e.heightMap,t.uniforms.heightScale.value=e.heightScale),this.updateMaterialCommonProperties(e,t)}updateUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e in s){const t=i[e],a=s[e].value;null!=t&&t.value!==a&&"receiveShadow"!==e&&!1===lt.includes(e)&&(t.value=a)}this.updateMaterialCommonProperties(e,t)}updateMaterialCommonProperties(e,t){t.alphaTest=e.alphaTest,t.side=e.side,t.depthTest=e.depthTest,t.blending=e.blending,t.colorWrite=e.colorWrite,t.premultipliedAlpha=e.premultipliedAlpha}updateLightUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e of lt){const t=i[e],a=s[e];null!=a&&null!=t&&(t.value=a.value)}}createGBufferMaterial(e,t){const s=t===Le.opaque?this.gbufferMaterialCache:this.tbufferMaterialCache;let a=s.get(e);if(!0===e.userData.isGBufferMaterial)return e;if(null==a){let n=_.uv;if(e instanceof Ce&&null!=e.heightMap){const t=U("heightScale",e.heightScale??1);n=Ae(n,N("heightMap",e.heightMap),t)}let o=j.normal;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=e.normalMap??je,s=U("useNormalMap",null!=e.normalMap?1:0),i=U("normalScale",e.normalScale?.x??1),a=S(N("normalMap",t).sample(n),i);o=z(j.normal,a,s)}else e instanceof C&&null!=e.outputNormal&&(o=e.outputNormal);!0!==e.userData.disableAO&&(o=k("DOUBLE_SIDED",o,e=>q(new W("gl_FrontFacing"),e,e.multiplyScalar(-1))));let l=e.userData?.reflective?R(0):R(1);if(e instanceof i.MeshStandardMaterial){const t=U("roughness",e.roughness??1),s=e.roughnessMap??Ve,i=U("useRoughnessMap",null!=e.roughnessMap?1:0),a=N("roughnessMap",s).sample(n).g.multiply(t);l=z(t,a,i)}else e instanceof C&&null!=e.outputRoughness&&(l=e.outputRoughness);let h=null;if((e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial)&&null!=e.lightMap){const t=e.lightMap,s=U("useLightMap",null!=e.lightMap?1:0),i=U("lightMapIntensity",e.lightMapIntensity??1),a=N("lightMap",t).sample(n).rgb.multiplyScalar(i);h=z(E(0),a,s)}let d=R(0);if(e instanceof i.MeshStandardMaterial){const t=U("metalness",e.metalness??0),s=e.metalnessMap??_e,i=U("useMetalnessMap",null!=e.metalnessMap?1:0),a=N("metalnessMap",s).sample(n).b.multiply(t);d=z(t,a,i)}else e instanceof C&&e.outputRoughness;let c=null,p=R(1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial){const t=e.aoMap??Ve,s=U("useAoMap",null!=e.aoMap?1:0);p=U("aoMapIntensity",e.aoMapIntensity??1);const i=N("aoMap",t).sample(n).r;c=z(R(1),i,s)}else e instanceof C&&e.outputRoughness;const f=U("opacity",e.opacity??1);let g=R(1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){if(null!=e.alphaMap){const t=e.alphaMap;g=N("alphaMap",t).sample(n).r}g=g.multiply(f)}else e instanceof C&&null!=e.outputOpacity&&(g=e.outputOpacity);let M=D(0,1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial){let t=F("color",(new i.Vector3).setFromColor(e.color));const s=e.map??Ve,a=U("useAlbedoMap",null!=e.map?1:0),r=N("map",s).sample(n),o=r.multiply(D(t,1)),l=D(t,1);M=z(l,o,a),e.vertexColors&&(M=M.multiply(G(V($.color.rgb),1)));const h=z(R(1),r.w,a);g=g.multiply(h)}const v=!0===e.userData.hasBloom;let T=E(0);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=F("emissive",(new i.Vector3).setFromColor(e.emissive)),s=U("emissiveIntensity",e.emissiveIntensity),a=e.emissiveMap??_e,r=U("useEmissiveMap",null!=e.emissiveMap?1:0),o=N("emissiveMap",a).sample(n).rgb.multiply(t);T=z(t,o,r),T=T.multiplyScalar(s)}else e instanceof C&&null!=e.outputEmissive&&(T=e.outputEmissive);const y=e instanceof u&&null!=e.uniforms[se],b=e instanceof u&&null!=e.uniforms[de],w=e instanceof u&&null!=e.uniforms[ue],x=e.transparent&&e.alphaTest<=.01||e.blending===i.AdditiveBlending,P=U("alphaTest",e.alphaTest);let L,H=e.alphaTest>0?g.lt(P):x&&t===Le.opaque?g.lt(.8):null;!0===e.userData.isDecal&&(H=H?H.or(Ie):Ie),L=x?G(0,0,0,0):(r=o,O(r).multiplyScalar(.5).addScalar(.5)).rgba(e.userData?.reflective?l:1);const X=e instanceof C?e.outputPosition:void 0,Y=e instanceof C?e.outputTransform:void 0;let Q,K=D("black",1);if(e instanceof C&&null!=e.outputColor)K=e.outputColor;else if(e instanceof i.MeshStandardMaterial)K=A({color:M,metalness:d,roughness:l,emissive:T.rgb,normal:o,ambientOcclusion:c,ambientOcclusionIntensity:p,bakedLight:h});else if(e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)K=B({color:M.rgb,ambientOcclusion:c,ambientOcclusionIntensity:p});else if(e instanceof i.MeshBasicMaterial){let e=M.rgb,t=h??E("black");null!=c&&(t=t.multiplyScalar(c.subtract(1).multiply(p).add(1))),e=e.add(t),K=e.rgba(g)}else e instanceof i.MeshToonMaterial&&(K=I({color:M,emissive:T.rgb,normal:o,ambientOcclusion:c,ambientOcclusionIntensity:p,bakedLight:h}));(e instanceof C||e instanceof i.MeshStandardMaterial)&&(Q=e.envMap);let J=!0;(e instanceof m||e instanceof i.MeshBasicMaterial||e instanceof i.ShaderMaterial)&&(J=e.fog);let Z=D(K.rgb,g);J&&(Z=new FogNode(Z));let ee=!0;if(t===Le.opaque?(ee&&(ee=!y&&!b&&!w),ee&&(ee=!x)):t===Le.transparent&&ee&&(ee=x||y||b||w),!ee)return a=Ge,s.set(e,a),a;a=new C({transform:Y,position:null==Y?X:void 0,outputs:[Z,T.rgba(t===Le.opaque?P:v?1:0),L],opacity:g,outputEncoding:!1,fog:J,transparent:e.transparent,lights:!0,envMap:Q,discard:H}),e instanceof i.MeshStandardMaterial&&null!=e.envMap&&null!=a.uniforms.envMapIntensity&&(a.uniforms.envMapIntensity.value=e.envMapIntensity),"alphaMap"in e&&null!=e.alphaMap&&(a.alphaMap=e.alphaMap),(e instanceof C||e instanceof i.MeshStandardMaterial)&&this.applyEnvMap(a),e instanceof C&&(Object.assign(a.defines,e.defines),null!=a.uniforms[ue]&&(a.uniforms[ue].value=this.aoPass.pdRenderTarget.texture,a.defines.USE_SSAO_MAP="")),a.userData.mrtOutputs=3,a.forceSinglePass=e.forceSinglePass,a.side=e.side,a.blending=e.blending,x?(a.depthWrite=!e.transparent,a.depthTest=e.depthTest,a.colorWrite=t===Le.transparent):(a.depthWrite=e.depthWrite,a.depthTest=e.depthTest),a.visible=e.visible,a.alphaTest=e.alphaTest,a.alphaHash=e.alphaHash,a.vertexColors=e.vertexColors,a.premultipliedAlpha=e.premultipliedAlpha,a.toneMapped=e.toneMapped,a.blendAlpha=e.blendAlpha,a.blendColor=e.blendColor,a.polygonOffset=e.polygonOffset,a.polygonOffsetFactor=e.polygonOffsetFactor,a.polygonOffsetUnits=e.polygonOffsetUnits,a.blending=e.blending,a.wireframe=e.wireframe??!1,a.userData.isGBufferMaterial=!0,a.visible=ee,Object.assign(a.userData,e.userData),a.visible&&(this.csm.setupMaterial(a),e instanceof u&&Object.assign(a.uniforms,e.uniforms)),s.set(e,a)}var r;return a.visible&&(e instanceof u?this.updateUniformValues(e,a):this.updateMaterialProperties(e,a)),this.initLightVolumeUniform(a),a}updateCsm(){const e=this.csmUpdateInvervals;if(this.renderer.shadowMap.autoUpdate&&null!=this.csmCascadeLastUpdate&&Array.isArray(e)){const t=performance.now();for(let s=0;s<this.csm.lights.length;++s){const i=e[s]??e[e.length-1]??16;if((t-this.csmCascadeLastUpdate[s]>=i||0===s)&&this.csm.lights[s].shadow){this.csm.lights[s].shadow.needsUpdate=!0,this.csmCascadeLastUpdate[s]=t;break}}}this.csm.update()}loop(t,s=!1){const a=this.stats,r=a.addPanel(new Z.Panel("Calls","#83f","#002")),l=a.addPanel(new Z.Panel("Triangles","#c32","#002"));let h;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(h=new pe(this.renderer.getContext()),a.addPanel(h)),this.showStats=s;let u=10,d=1e3;const c=()=>{const e=this.renderer.info.render.calls;e>u&&(u=e,setTimeout(()=>u=10,5e3)),r.update(e,u);const t=this.renderer.info.render.triangles;t>d&&(d=t,setTimeout(()=>d=1e3,5e3)),l.update(t,d)};performance.now();i.Ray.prototype.intersectTriangle;this.resizeRender();const p=[],m=[],f=[];let g=0;const M=new n,v=new n;let T=0;let y=this.paused,b=!1,w=0;const x=()=>{e.activeView=this,b&&(b=!1,requestAnimationFrame(()=>S(w)))},P=He();Ne.set(this.container,e=>{this.isIntersecting=e,e&&x()}),P.observe(this.container),this.container.addEventListener("pointerdown",()=>{x()},{capture:!0});const S=s=>{b=!1;const r=this.renderer.getContext();if(!this.running||null===this.container.offsetParent||this.paused&&r.drawingBufferHeight>1)return b=!0,w=s,setTimeout(()=>{b&&S(s)},500),void(this.paused&&(y=!0));if(this.renderer.domElement.parentElement!==this.container){if(e.activeView!==this&&null!==e.activeView)return b=!0,void(w=s);this.container.replaceChildren(this.renderer.domElement),this.resizeRender()}this.applyPostProcessSettings(),this.renderer.autoClear=!1,this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),a.begin(),this.showStats&&h?.startQuery(),this.ssrPass.gpuPanel=h;let n=(s*=.001)-g;if(g=s,y&&(n=.016,y=!1),M.copy(this.camera.matrixWorld),n>1){let e=n;for(;e>.05;)t($e),e-=$e;t(e)}else t(n);this.onLoopCallbacks.forEach(e=>e(n)),this.camera?.updateMatrixWorld(),v.copy(this.camera.matrixWorld),s-T>.08&&!v.equals(M)&&(this.renderer.shadowMap.needsUpdate=!0,T=s),this.updateCsm();let l=!1;p.length=0,m.length=0,f.length=0;const u=Ye;Ke.multiplyMatrices(this.camera.projectionMatrix,this.camera.matrixWorldInverse),u.setFromProjectionMatrix(Ke);let d=!1,x=!1,P=!1;this.scene.traverseVisible(e=>{if(this.setupCsm(e),this.outlineEffect.apply(e),e instanceof Re&&(d=!0),e instanceof o&&this.initCustomDepthMaterial(e),(e instanceof o||e instanceof i.Sprite)&&(this.initResolutionUniform(e.material),this.initNormalUniform(e.material),this.initShadowUniform(e,e.material),this.initLightVolumeUniform(e.material),null!=this.scene.environment&&function(e,t){if(Array.isArray(e.material))for(const s of e.material)t(s);else null!=e.material&&t(e.material)}(e,e=>this.applyEnvMap(e)),!0===e.material?.userData?.hasBloom&&(l=!0)),(e instanceof o||e instanceof i.Sprite)&&e.visible&&(e.material?.userData?.water||e.material?.uniforms&&null!=e.material?.uniforms[se])&&isObjectInFrustum(e,u)?(this.initDepthUniform(e.material),x=!0):e instanceof X&&(e.visible=!1,m.push(e)),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[ue]&&isObjectInFrustum(e,u)&&e.material instanceof C&&this.initAoUniform(e.material),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[de]&&isObjectInFrustum(e,u)&&(f.push(e),e.material.uniforms[de].value=this.sceneColorRenderTarget.texture,P=!0),e instanceof o&&e.material?.uniforms&&null!=e.material?.uniforms[he])e.material.uniforms[he].value=s;else if(e instanceof o&&Array.isArray(e.material))for(const t of e.material)t.uniforms&&null!=t.uniforms[he]&&(t.uniforms[he].value=s)}),this.bloomPass.enabled=l,this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.clear(),this.renderScene(Le.opaque),this.aoPass.output=ee.OUTPUT.Off,(x||P)&&(this.fquadCopyOpaque.material.uniforms.tSceneColor.value=this.gRenderTarget.textures[0],this.fquadCopyOpaque.material.uniforms.tDepthTexture.value=this.gRenderTarget.depthTexture,this.initResolutionUniform(this.fquadCopyOpaque.material),this.renderer.setRenderTarget(this.sceneColorRenderTarget),this.renderer.clear(),this.fquadCopyOpaque.render(this.renderer),this.renderer.setRenderTarget(this.gRenderTarget)),f.length,p.forEach(e=>e.visible=!0),m.forEach(e=>e.visible=!0),f.forEach(e=>e.visible=!0),this.aoPass.enabled,this.ssrPass&&(this.ssrPass.elapsedTime=s),this.volumetricFogPass&&d?(this.volumetricFogPass.update(this.camera,this.gRenderTarget,this.csm,this.scene),this.volumetricFogPass.enabled=!0):this.volumetricFogPass&&(this.volumetricFogPass.enabled=!1);try{!this.paused&&this.running&&(this.render(n),this.showStats&&h?.endQuery(),this.showStats&&c(),this.renderer.info.reset(),this.renderOverlay())}catch(e){console.warn(e)}a.end(),this.csm?.update(),this.running&&!0!==this.options.enableXR&&(this.fpsCap?setTimeout(()=>{requestAnimationFrame(S)},1e3/this.fpsCap):requestAnimationFrame(S))};!0===this.options.enableXR?this.renderer.setAnimationLoop(S):requestAnimationFrame(S)}applyGBufferMaterials(e){const t=this.gBufferCachedMaterials,s=this.gBufferCachedVisibility;t.clear(),s.length=0;ge(this.scene,i=>{if(at(i))return s.push(i),i.visible=!1,!1;if(i instanceof o){t.set(i,i.material);let a=!1;if(Array.isArray(i.material)){i.material=i.material.slice();for(let t=0;t<i.material.length;t++)i.material[t]=this.createGBufferMaterial(i.material[t],e),a||(a=i.material[t].visible),this.initShadowUniform(i,i.material[t])}else i.material=this.createGBufferMaterial(i.material,e),a||(a=i.material.visible),this.initShadowUniform(i,i.material);a?i.visible=!0:null!=i.children&&0!=i.children.length||(s.push(i),i.visible=!1)}})}unapplyGBufferMaterials(){this.gBufferCachedMaterials.forEach((e,t)=>{t.material=e}),this.gBufferCachedVisibility.forEach((e,t)=>{e.visible=!0,e.updateMatrixWorld(!0)})}initTextures(e=this.scene){e.traverse(e=>{if(e instanceof o)if(Array.isArray(e.material))for(let t=0;t<e.material.length;t++)this._initMaterialTextures(e.material[t]);else this._initMaterialTextures(e.material)})}_initMaterialTextures(e){if(!this._initiatedMaterialTextures.has(e))if(this._initiatedMaterialTextures.add(e),e instanceof u){for(const[t,s]of Object.entries(e.uniforms))if(s.value instanceof c){if(this._initiatedTextures.has(s.value))continue;this.renderer.initTexture(s.value),this._initiatedTextures.add(s.value)}}else for(const[t,s]of Object.entries(e))if(s instanceof c){if(this._initiatedTextures.has(s))continue;this.renderer.initTexture(s),this._initiatedTextures.add(s)}}async compileAsync(e=this.scene){if(this.compileInProgress)return;this.renderer.setRenderTarget(this.gRenderTarget),this.compileInProgress=!0,this.applyGBufferMaterials(Le.opaque),await this.renderer.compileAsync(e,this.camera),this.unapplyGBufferMaterials(),this.applyGBufferMaterials(Le.transparent),await this.renderer.compileAsync(e,this.camera),this.unapplyGBufferMaterials(),e===this.scene&&(this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.compileAsync(this.fquadBlendAO.mesh,this.fquadBlendAO.camera),this.renderer.setRenderTarget(this.sceneColorRenderTarget),this.renderer.compileAsync(this.fquadCopyOpaque.mesh,this.fquadCopyOpaque.camera));const t=this.csm.lights[0]?.shadow.camera;null!=t&&(this.applyDepthMaterial(),await this.renderer.compileAsync(e,t),this.unapplyDepthMaterial()),this.compileInProgress=!1,this.renderer.setRenderTarget(null)}applyDepthMaterial(){const e=this.gBufferCachedMaterials;e.clear(),this.scene.traverse(t=>{(t.isMesh||t.isPoints||t.isLine||t.isSprite)&&(this.initCustomDepthMaterial(t),e.set(t,t.material),t.castShadow?null!=t.customDepthMaterial?t.material=t.customDepthMaterial:t.material=ut:t.material=null)})}unapplyDepthMaterial(){this.gBufferCachedMaterials.forEach((e,t)=>{t.material=e})}renderScene(e){if(!this.running||this.paused)return;if(this.compileInProgress)return void console.error("Compile in progress, skipping render");this.applyGBufferMaterials(e);const t=this.scene.matrixWorldAutoUpdate,s=this.scene.matrixAutoUpdate,i=this.renderer.shadowMap.autoUpdate;e!==Le.opaque&&(this.renderer.shadowMap.autoUpdate=!1,this.scene.matrixWorldAutoUpdate=!1,this.scene.matrixAutoUpdate=!1);try{this.renderer.render(this.scene,this.camera)}catch(e){console.warn("Render failed",e)}e===Le.opaque&&this.gBufferCachedMaterials.forEach((e,t)=>{!Array.isArray(e)&&!Array.isArray(t.material)&&e instanceof u&&this.updateLightUniformValues(t.material,e)}),this.unapplyGBufferMaterials(),this.renderer.shadowMap.autoUpdate=i,this.scene.matrixWorldAutoUpdate=t,this.scene.matrixAutoUpdate=s}getEnvTexture(e){null==this.pmremGenerator&&(this.pmremGenerator=new i.PMREMGenerator(this.renderer),this.pmremGenerator.compileEquirectangularShader());let t=this.pmremGeneratorResults.get(e);return null==t&&(t=this.pmremGenerator.fromEquirectangular(e).texture,this.pmremGeneratorResults.set(e,t)),t.colorSpace=i.SRGBColorSpace,t}applyPostProcessSettings(){if(0==this.postProcessVolumes.length)return this.lutPass.enabled=!1,void(this.colorPass.enabled=!1);var e;(e=this.postProcessSettings).tonemapMapping=void 0,e.tonemapExposure=1,e.envIntensity=1,e.envTexture=void 0,e.vignetteIntensity=0,e.colorTint=new i.Color("white"),e.colorTintIntensity=0,e.depthFocus=void 0,e.depthAperture=void 0,e.depthMaxBlur=void 0,e.temperature=6500,e.temperatureTint=0,e.lut=void 0,e.lutIntensity=0;const t=this.postProcessSettings;let s,a=!1,r=!1,n=!1,o=!1;if(null==this.camera)return;const h=this.camera.getWorldPosition(Je);let u=[];for(const e of this.postProcessVolumes){if(!Xe(e.object))continue;let l=e.blendWeight??1;const d=e.distanceToPoint(h);d>e.blendRadius||(e.blendRadius>0&&(l*=Me(1-d/e.blendRadius,0,1)),l>1&&(l=1),l>0&&(u.push(e),void 0!==e.settings.tonemapMapping&&(t.tonemapMapping=e.settings.tonemapMapping),void 0!==e.settings.tonemapExposure&&(t.tonemapExposure=i.MathUtils.lerp(t.tonemapExposure,e.settings.tonemapExposure,l)),void 0!==e.settings.envTexture&&(t.envTexture=e.settings.envTexture),void 0!==e.settings.envIntensity&&(t.envIntensity=i.MathUtils.lerp(t.envIntensity,e.settings.envIntensity,l)),void 0!==e.settings.vignetteIntensity&&(t.vignetteIntensity=i.MathUtils.lerp(t.vignetteIntensity,e.settings.vignetteIntensity,l),r=!0),void 0!==e.settings.colorTint&&void 0!==e.settings.colorTintIntensity&&e.settings.colorTintIntensity>0&&(t.colorTint=t.colorTint.lerp(e.settings.colorTint,l),o=!0),void 0!==e.settings.colorTintIntensity&&(t.colorTintIntensity=i.MathUtils.lerp(t.colorTintIntensity,e.settings.colorTintIntensity,l)),void 0!==e.settings.depthFocus&&(a=!0,t.depthFocus=void 0!==t.depthFocus?i.MathUtils.lerp(t.depthFocus,e.settings.depthFocus,l):e.settings.depthFocus),void 0!==e.settings.depthAperture&&(a=!0,t.depthAperture=void 0!==t.depthAperture?i.MathUtils.lerp(t.depthAperture,e.settings.depthAperture,l):e.settings.depthAperture),void 0!==e.settings.depthMaxBlur&&(a=!0,t.depthMaxBlur=void 0!==t.depthMaxBlur?i.MathUtils.lerp(t.depthMaxBlur,e.settings.depthMaxBlur,l):e.settings.depthMaxBlur),void 0!==e.settings.temperature&&(t.temperature=i.MathUtils.lerp(t.temperature,e.settings.temperature,l)),void 0!==e.settings.temperatureTint&&(t.temperatureTint=i.MathUtils.lerp(t.temperatureTint,e.settings.temperatureTint,l)),void 0!==e.settings.lut&&(s=e.settings.lut,n=!0),void 0!==e.settings.lutIntensity&&(t.lutIntensity=i.MathUtils.lerp(t.lutIntensity,e.settings.lutIntensity,l),n=!0)))}this.renderer.toneMapping=t.tonemapMapping??i.NoToneMapping,this.renderer.toneMappingExposure=t.tonemapExposure,null!=t.envTexture&&(this.scene.environment=this.getEnvTexture(t.envTexture)),this.scene.environmentIntensity=t.envIntensity,this.colorPass.vignetteIntensity=t.vignetteIntensity,this.colorPass.vignetteEnabled=r,this.colorPass.colorTint=t.colorTint,this.colorPass.colorTintIntensity=t.colorTintIntensity,this.colorPass.enabled=r||o,a&&this.camera instanceof l?(this.dofPass.enabled=!0,void 0!==t.depthFocus&&(this.dofPass.uniforms.focus.value=t.depthFocus),void 0!==t.depthAperture&&(this.dofPass.uniforms.aperture.value=t.depthAperture),void 0!==t.depthMaxBlur&&(this.dofPass.uniforms.maxblur.value=t.depthMaxBlur)):this.dofPass.enabled=!1,this.colorPass.temperature=t.temperature,this.colorPass.temperatureTint=t.temperatureTint,this.lutPass.enabled=n,n&&(null!=s&&(s.flipY=!0,s.generateMipmaps=!1),this.lutPass.lut=s,this.lutPass.intensity=t.lutIntensity)}renderOverlay(){if(!this.running)return;if(0===this.overlayCameras.size)return;const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.previousClientWith/2,s=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let i=0;i<e.length;i++)this.renderer.clearDepth(),this.renderer.setViewport(t-s/2+this.insetWidth*i+this.insetMargin*i,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[i])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){if(0===this.composer.renderTarget1.width||0===this.composer.renderTarget1.height)return;if(0===this.composer.renderTarget2.width||0===this.composer.renderTarget2.height)return;let t=!1;if(this.ssrPass.enabled&&!1!==this.options?.reflection?.enabled){const e=this.ssrPass.selects??[];e.length=0,this.scene.traverseVisible(t=>{t instanceof o&&!0===t.material.userData?.reflective&&isObjectInFrustum(t,Ye)&&e.push(t)}),this.ssrPass.selects=e,0==e.length&&(this.ssrPass.enabled=!1),t=!0}this.options.bloom,this.composer.render(e),this.scene.matrixWorldAutoUpdate=!0,this.scene.matrixAutoUpdate=!0,t&&(this.ssrPass.enabled=!0)}hasBloom(){return null!=fe(this.scene,e=>e instanceof o&&!0===e.material?.userData?.hasBloom)}darkenNonBloomed(e){if((e instanceof o||e instanceof i.Sprite||e instanceof i.Line)&&e.visible&&(null==e.material.userData||!0!==e.material.userData.hasBloom)){if(e.material?.id===Ee.id)return;this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=Ee:(e.visible=!1,this.bloomHidden.push(e))}else"TransformControlsPlane"!==e.type&&"TransformControlsGizmo"!==e.type||(e.visible=!1,this.bloomHidden.push(e))}restoreMaterial(e){this.bloomStoredMaterials[e.uuid]&&(e.material=this.bloomStoredMaterials[e.uuid],delete this.bloomStoredMaterials[e.uuid],e.visible=!0)}initDepthUniform(e){e instanceof u&&(e.uniforms[se].value=this.sceneColorRenderTarget.textures[1],this.camera instanceof l&&(null!=e.uniforms[ae]&&(e.uniforms[ae].value=this.camera.near),null!=e.uniforms[ie]&&(e.uniforms[ie].value=this.camera.far)))}initNormalUniform(e){e instanceof u&&null!=e.uniforms[ne]&&(e.uniforms[ne].value=this.gRenderTarget.textures[2])}initShadowUniform(e,t){t instanceof C&&(t.uniforms.receiveShadow?t.uniforms.receiveShadow.value=e.receiveShadow:t.uniforms.receiveShadow={value:e.receiveShadow})}initLightVolumeUniform(e){e instanceof C&&(null!=this.lightVolume?null==e.uniforms.uSH?(e.defines.USE_LIGHT_PROBE_VOLUME="",e.uniforms.gridOrigin={value:this.lightVolume.gridOrigin},e.uniforms.gridSize={value:this.lightVolume.gridSize},e.uniforms.gridRes={value:this.lightVolume.gridResolution},e.uniforms.giIntensity={value:this.lightProbeIntensity},e.uniforms.uSH={value:this.lightVolume.shTexture},e.uniformsNeedUpdate=!0,e.needsUpdate=!0):e.uniforms.giIntensity.value=this.lightProbeIntensity:null!=e.uniforms.uSH&&(delete e.defines.USE_LIGHT_PROBE_VOLUME,delete e.uniforms.gridOrigin,delete e.uniforms.gridSize,delete e.uniforms.gridRes,delete e.uniforms.giIntensity,delete e.uniforms.uSH,e.uniformsNeedUpdate=!0,e.needsUpdate=!0))}initResolutionUniform(e){e instanceof u&&null!=e.uniforms[re]&&e.uniforms[re].value.set(this.gRenderTarget.width,this.gRenderTarget.height)}initAoUniform(e){if(this.aoPass.enabled){e.uniforms[ue].value=this.aoPass.pdRenderTarget.texture,null==e.defines.USE_SSAO_MAP&&(e.defines.USE_SSAO_MAP="",e.needsUpdate=!0),e.defines.USE_SSAO_MAP="";const t=this.tbufferMaterialCache.get(e);null!=t&&this.initAoUniform(t)}else if(null!=e.defines.USE_SSAO_MAP){delete e.defines.USE_SSAO_MAP,e.needsUpdate=!0;const t=this.tbufferMaterialCache.get(e);null!=t&&this.initAoUniform(t)}}initCustomDepthMaterial(e){if(null!=e.customDepthMaterial||!e.castShadow)return;const t=e.material;if(t instanceof C&&!t.transparent&&t.depthWrite){let s=this._customDepthMaterialCache.get(t);if(null==s){const e=Se(Pe);let i;null!=t.alphaTest&&t.alphaTest>0&&null!=t.outputOpacity&&(i=t.outputOpacity.lt(t.alphaTest)),s=new C({color:e,discard:i}),this._customDepthMaterialCache.set(t,s)}e.customDepthMaterial=s}}};ze.activeView=null,ze=e=t([te(),s("design:paramtypes",[HTMLElement,Object])],ze);export{ze as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const $e=.05;function Xe(e){let t=e;for(;t;){if(!1===t.visible)return!1;t=t.parent}return!0}ee.prototype.overrideVisibility=function(){const e=this.scene,t=this._visibilityCache;e.traverse(function(e){if(t.set(e,e.visible),(e.isPoints||e.isLine||e.isTransformControls||e.isSprite)&&(e.visible=!1),null!=e.material){let t=!1,s=!1;if(Array.isArray(e.material)){for(const s of e.material)if(null!=s.alphaTest&&s.alphaTest>0){t=!0;break}}else null!=e.material.alphaTest&&e.material.alphaTest>0?t=!0:!0===e.material.userData.isDecal&&(s=!0);s&&(e.visible=!1)}})};const Ye=new i.Frustum,Qe=new i.Box3,Ke=new i.Matrix4;export function isObjectInFrustum(e,t){const s=Qe.setFromObject(e);return t.intersectsBox(s)}const Je=new i.Vector3;const Ze=new n,et=new p;function tt(e,t,s=new i.Matrix3){return et.copy(e),et.x*=-1,et.y*=-1,et.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(et.y*=-1,et.z*=-1),s.setFromMatrix4(Ze.makeRotationFromEuler(et))}const st=new C({outputs:[G(0,0,0,0),G(0,0,0,0),D(E("white"),Fe(4))],transparent:!0}),it=new i.MeshBasicMaterial({color:"blue",transparent:!0,opacity:.5});st.depthWrite=!1;new o(new i.BoxGeometry(4,4,4),it);function at(e){return e instanceof i.Sprite||e.isPoints||e.isLine||e.isLineSegments2||e.isTransformControls||e.isTransformControlsGizmo||e instanceof o&&rt(e,e.material)}function rt(e,t){return null==t||(Array.isArray(t)?t.some(t=>rt(e,t)):t instanceof i.RawShaderMaterial||t instanceof i.ShaderMaterial&&!(t instanceof C))}class nt extends Be{constructor(e,t,s){super(),this.scene=e,this.camera=t,this.gRenderTarget=s,this.cachedVisibility=[],this.toRender=[],this.needsSwap=!1}render(e,t,s,i,a){const r=e.autoClear;e.autoClear=!1;const n=this.scene.matrixWorldAutoUpdate,l=this.scene.matrixAutoUpdate,h=e.shadowMap.autoUpdate;this.scene.matrixAutoUpdate=!1,e.shadowMap.autoUpdate=!1;const u=s.depthTexture;s.depthTexture=this.gRenderTarget.depthTexture,e.setRenderTarget(s),this.cachedVisibility.length=0;let d=0,c=this.toRender;if(c.length=0,this.scene.traverseVisible(e=>{const t=at(e);e instanceof o&&!t?(this.cachedVisibility.push(e),e.visible=!1):t&&(d++,c.push(e))}),d>0)for(const t of c)e.render(t,this.camera);this.cachedVisibility.forEach((e,t)=>{e.visible=!0}),e.setRenderTarget(null),e.autoClear=r,s.depthTexture=u,this.scene.matrixWorldAutoUpdate=n,this.scene.matrixAutoUpdate=l,e.shadowMap.autoUpdate=h}}class ot extends Be{constructor(e){super(),this.fn=e}render(e,t,s,i,a){this.fn(e,t,s,i,a)}}const lt=["ambientLightColor","cameraNear","directionalLightShadows","directionalLights","directionalShadowMap","directionalShadowMatrix","fogColor","fogDensity","fogFar","fogNear","hemisphereLights","lightProbe","ltc_1","ltc_2","pointLightShadows","pointLights","pointShadowMap","pointShadowMatrix","rectAreaLights","shadowFar","spotLightMap","spotLightMatrix","spotLightShadows","spotLights","spotShadowMap"],ht=F("fogColor");export class FogNode extends H{constructor(e,t=ht){super(),this.source=e,this.fogColor=t}compile(e){const t=e.variable(),s=e.get(this.source.rgb),i=e.get(this.source.a),a=e.get(this.fogColor),r=e.get(U("fogFar")),n=e.get(U("fogNear")),o=e.get(U("fogDensity")),l=e.get(V(L.mvPosition.z));return{pars:"\n ",chunk:`\n #ifdef FOG_EXP2\n float fogFactor_${t} = 1.0 - exp( - ${o} * ${o} * ${l} * ${l} );\n #else\n float fogFactor_${t} = smoothstep( ${n}, ${r}, ${l} );\n #endif\n vec4 color_vec4_${t} = vec4(mix(${s}, ${a}, fogFactor_${t}), ${i});\n `,out:`color_vec4_${t}`}}}const ut=new i.MeshDepthMaterial({depthPacking:i.RGBADepthPacking});/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,5 +1,5 @@
1
- import { Object3D, Texture } from 'three';
2
- import { Asset } from './model.js';
1
+ import { Material, Object3D, Texture } from 'three';
2
+ import { Asset, AssetId } from './model.js';
3
3
  import { CollisionShape } from './collision/collision-shape.js';
4
4
  import * as THREE from 'three';
5
5
  import { SceneObjectPhysicsSettings } from './materializer.js';
@@ -20,6 +20,7 @@ export declare class AssetResourceLoader {
20
20
  private _textureLoader;
21
21
  private audioLoader;
22
22
  private initialisedKtx2;
23
+ materialProvider?: (id: AssetId) => Promise<Material>;
23
24
  /**
24
25
  * Keeping track of all resources ever loaded
25
26
  * so that they can be cleaned up.
@@ -111,5 +112,14 @@ export type GetMeshOptions = {
111
112
  * @default false
112
113
  */
113
114
  rescale?: boolean;
115
+ /**
116
+ * Whether to apply asset materials to the mesh.
117
+ * @default false
118
+ */
119
+ applyMaterials?: boolean;
120
+ /**
121
+ * Resolver for material assets. Defaults to the global provider on the AssetResourceLoader if not provided.
122
+ */
123
+ materialResolver?: (materialId: AssetId) => Promise<Material>;
114
124
  };
115
125
  //# sourceMappingURL=asset-resource-loader.d.ts.map
@@ -1,4 +1,4 @@
1
- import{AudioLoader as e,BufferGeometry as t,Group as s,LoadingManager as r,Mesh as i,Object3D as a,Texture as n,TextureLoader as o}from"three";import{GLTFLoader as l,MTLLoader as h,OBJLoader as c,DRACOLoader as u,LUTCubeLoader as d}from"three-stdlib";import{FBXLoader as m}from"three-stdlib";import{cloneMesh as f}from"../utils/mesh.js";import{pathJoin as p}from"../utils/files.js";import{Subject as g,firstValueFrom as y}from"rxjs";import{importCollisionShapes as w,isCollisionMesh as x}from"./collision/collision-shape-import.js";import*as M from"three";import{iterateMaterials as L}from"../utils/materials.js";import{BufferGeometryUtils as A,EXRLoader as b,KTX2Loader as v,TGALoader as _,UltraHDRLoader as T}from"three/examples/jsm/Addons.js";import{disposeScene as C}from"../utils/three/cleanup.js";const S=new u;S.setDecoderConfig({type:"js"}),S.setDecoderPath("/assets/draco/");const K=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new r,this.glbLoader=new l(this.loadingManager).setDRACOLoader(S),this.fbxLoader=new m(this.loadingManager),this.objLoader=new c(this.loadingManager),this.textureLoader=new o(this.loadingManager),this.tgaLoader=new _(this.loadingManager),this.exrLoader=new b(this.loadingManager),this.cubeLoader=new d(this.loadingManager),this.hdrLoader=new T(this.loadingManager),this.ktx2Loader=new v(this.loadingManager),this._textureLoader=new M.ImageBitmapLoader(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new g,this.ready=y(this.makeReady),this._texturePromises=new Map,this._arrayTexturesByFileKey=new Map,this._animationPromises=new Map,this._animationCache=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}initKtx2(e){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.detectSupport(e)}setDataDir(e){this.basePath=p(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){const t=function(e){return R.get(e)}(e),s=getElectronArg("windowId");return null!=s||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?p(this.basePath,e)+(null!=s?`?windowId=${s}&v=${t}`:""):new URL(p("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if(this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;if(await this.ready,this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);null!=e.texture&&(t.flipY!==e.texture?.flipY?(t.needsUpdate=!0,t.flipY=e.texture?.flipY??!0):t.wrapS!==k(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=k(e.texture?.wrapS)):t.wrapT!==k(e.texture?.wrapT)&&(t.wrapT=k(e.texture?.wrapT),t.needsUpdate=!0))}else try{await this._getTextureLoader(e.fileKey).loadAsync(this.getUri(e.fileKey)).then(t=>(t.texture3D?t=t.texture3D:(t.wrapS=k(e.texture?.wrapS),t.wrapT=k(e.texture?.wrapT),t.flipY=e.texture?.flipY??!0),this.textureCache.set(e.id,t),this._retrievedTextures.push(t),t))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}const t=this.textureCache.get(e.id);return null!=t&&(t.userData.assetId=e.id),t}async getTextureArray(e){const t=e.texture?.textureArrayFileKey,s=e.texture?.textureArrayLayer;if(!t||null==s)return{texture:null,layerIndex:null};if(!this._arrayTexturesByFileKey.has(t)){const e=this._getTextureLoader(t);let s=await e.loadAsync(this.getUri(t));s instanceof n||(s=s.texture3D),this._arrayTexturesByFileKey.set(t,s),this._retrievedTextures.push(s)}return{texture:this._arrayTexturesByFileKey.get(t),layerIndex:s}}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){"mesh"===e.type?(Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)}),P(e.fileKey)):"texture"===e.type&&(this.textureCache.delete(e.id),P(e.fileKey))}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new s,animations:[]};if(!K.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new s,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new s,animations:[]}}const a=this.cache.get(r).scene,n=this.computeCollisionShapes(e,a);!0===t?.mergeGeomtries&&this.optimizeDrawGroups(a);const o=f(a),l=this.cache.get(r).animations;o.traverse(e=>{e instanceof i&&e.material instanceof Array&&(e.material=e.material.slice())});const h=new AssetMeshInstance;h.add(o),h.collisionShapes=n,h.animations=l;const c=e.receiveShadow??!0,u=e.castShadow??!1;return o.traverse(e=>{e.castShadow=u,e.receiveShadow=c}),!0===t?.rescale&&"number"==typeof e.mesh?.rescale&&h.scale.setScalar(e.mesh?.rescale),{scene:h,animations:l}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const s=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,s),s}async getAnimationClip(e){if(null==e||null==e.fileKey||null==!e.anim?.clip)return console.warn("Asset or animation clip name is not defined",e),null;const t=e.anim.clip,s=e.fileKey+"|"+t;if(this._animationCache.has(s))return this._animationCache.get(s);if(this._animationPromises.has(s))return this._animationPromises.get(s);const r=(async()=>{try{const r=await this.getMesh(e),i=r.animations.find(e=>e.name===t);return null!=i&&this._animationCache.set(s,i),i}catch(e){return this.onError(e),null}finally{setTimeout(()=>this._animationPromises.delete(s),1e3)}})();return this._animationPromises.set(s,r),r}computeCollisionShapes(e,t){const s=e.id+e.mesh?.collisions?.shapeType;return this.collisionShapeCache.has(s)||this.collisionShapeCache.set(s,w(t,e)),this.collisionShapeCache.get(s)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(e=>(e.scene.traverse(e=>{e instanceof i&&e.material,x(e)?e.visible=!1:e instanceof i&&e.geometry instanceof t&&(e.geometry.hasAttribute("normal")||e.geometry.computeVertexNormals())}),this._retrievedMeshes.push(e.scene),e.scene=function(e,t){let s=!1;if(t.traverseVisible(e=>{I.test(e.name)&&(s=!0)}),!s)return t;const r=new M.LOD,i=[t];for(;i.length>0;){const e=i.shift(),t=e.name.match(I);if(null!=t){const s=parseInt(t[1]);0===s?r.addLevel(e,0):console.warn(`Skipping LOD level ${s} for now as LOD is not fully supported`)}else i.push(...e.children)}return r}(0,e.scene),function(e){const t=D;D.length=0,e.traverse(e=>{(e instanceof M.Camera||e instanceof M.Light)&&t.push(e)}),t.forEach(e=>e.removeFromParent())}(e.scene),e))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid),e.updateWorldMatrix(!0,!0);const s=[];e.traverse(e=>{e instanceof i&&!(e instanceof M.SkinnedMesh)&&e.geometry instanceof t&&Array.isArray(e.material)&&!x(e)&&s.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:t,geometry:r,materialArray:a,parent:n}of s){t.removeFromParent();for(let s=0;s<a.length;s++){const o=a[s],l=r.groups.filter(e=>e.materialIndex===s);if(0===l.length)continue;const h=this.extractGeometryGroups(r,l);h.groups.length>1&&A.mergeGroups(h);const c=new i(h,o);c.copy(t,!1),c.geometry=h,c.material=o,n?n.add(c):e.add(c)}r.dispose()}let r=!0,a=0,n=0;if(e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!x(e)){a++;const t=Object.keys(e.geometry.attributes).length;t!==n&&0!==n&&(r=!1),n=t}else(e instanceof M.SkinnedMesh||e instanceof M.Bone)&&(r=!1)}),a>1&&r){const s=new Map;e.traverse(r=>{if(r instanceof i&&r.geometry instanceof t&&!x(r)){if(Array.isArray(r.material))return;r.updateWorldMatrix(!0,!0);const t=r.material?.uuid||"default";s.has(t)||s.set(t,{material:r.material,geometries:[],objects:[]});const i=s.get(t),a=e.matrixWorld.clone().invert().multiply(r.matrixWorld);i.geometries.push(r.geometry.clone().applyMatrix4(a)),i.objects.push(r)}});for(const e of s.values())for(const t of e.objects)t.removeFromParent();for(const t of s.values()){let s;s=1===t.geometries.length?t.geometries[0]:A.mergeGeometries(t.geometries,!0),s.groups.length>1&&A.mergeGroups(s),e.add(new i(s,t.material))}}e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!x(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&A.mergeGroups(t)}})}extractGeometryGroups(e,s){const r=e.index;if(!r){const r=new t;let i=0;for(const e of s)i+=e.count;if(0===i)return r;for(const t in e.attributes){const a=e.attributes[t],n=a.itemSize,o=a.array,l=new(0,o.constructor)(i*n);let h=0;for(const e of s){const t=e.start*n,s=e.count*n;for(let e=0;e<s;e++)l[h+e]=o[t+e];h+=s}const c=new M.BufferAttribute(l,n,a.normalized);r.setAttribute(t,c)}return r.groups=[{start:0,count:i,materialIndex:0}],r}const i=[];for(const e of s)for(let t=0;t<e.count;t++){const s=r.getX(e.start+t);i.push(s)}if(0===i.length)return new t;const a=new Map,n=[];let o=0;for(const e of i)a.has(e)||(a.set(e,o),o++),n.push(a.get(e));if(0===n.length||0===a.size)return new t;const l=new t;for(const t in e.attributes){const s=e.attributes[t],r=s.itemSize,i=s.array,n=new(0,i.constructor)(a.size*r);for(const[e,t]of a)for(let s=0;s<r;s++)n[t*r+s]=i[e*r+s];const o=new M.BufferAttribute(n,r,s.normalized);l.setAttribute(t,o)}const h=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)h[e]=n[e];return l.setIndex(new M.BufferAttribute(h,1)),l.groups=[{start:0,count:n.length,materialIndex:0}],l}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(e=>({scene:e.scene,animations:e.animations}));case"fbx":return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new h;t.materialOptions={normalizeRGB:!1};const s=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(s)}return this.objLoader.loadAsync(t).then(e=>(j(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>C(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}const R=new Map;function P(e){R.set(e,R.get(e)??1)}function j(e){if(e instanceof i)for(const t of L(e.material))t instanceof M.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach(j)}export class AssetMeshInstance extends a{}export function getElectronArg(e){const t=`--${e}=`,s=window.process?.argv.find(e=>e.startsWith(t));return s?.substring(t.length)}function k(e){switch(e){case"clamp":return M.ClampToEdgeWrapping;case"repeat":return M.RepeatWrapping;case"mirror":return M.MirroredRepeatWrapping}return M.RepeatWrapping}new M.Matrix4;const D=[];const I=/_LOD(\d+)$/;/*
1
+ import{AudioLoader as e,BufferGeometry as t,Group as s,LoadingManager as r,Mesh as i,Object3D as a,Texture as n,TextureLoader as o}from"three";import{GLTFLoader as l,MTLLoader as h,OBJLoader as c,DRACOLoader as u,LUTCubeLoader as d}from"three-stdlib";import{FBXLoader as m}from"three-stdlib";import{cloneMesh as f}from"../utils/mesh.js";import{pathJoin as p}from"../utils/files.js";import{Subject as g,firstValueFrom as y}from"rxjs";import{importCollisionShapes as w,isCollisionMesh as x}from"./collision/collision-shape-import.js";import*as M from"three";import{iterateMaterials as L}from"../utils/materials.js";import{applyMaterial as A}from"./materializer.js";import{BufferGeometryUtils as b,EXRLoader as v,KTX2Loader as _,TGALoader as T,UltraHDRLoader as C}from"three/examples/jsm/Addons.js";import{disposeScene as S}from"../utils/three/cleanup.js";const R=new u;R.setDecoderConfig({type:"js"}),R.setDecoderPath("/assets/draco/");const K=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new r,this.glbLoader=new l(this.loadingManager).setDRACOLoader(R),this.fbxLoader=new m(this.loadingManager),this.objLoader=new c(this.loadingManager),this.textureLoader=new o(this.loadingManager),this.tgaLoader=new T(this.loadingManager),this.exrLoader=new v(this.loadingManager),this.cubeLoader=new d(this.loadingManager),this.hdrLoader=new C(this.loadingManager),this.ktx2Loader=new _(this.loadingManager),this._textureLoader=new M.ImageBitmapLoader(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new g,this.ready=y(this.makeReady),this._texturePromises=new Map,this._arrayTexturesByFileKey=new Map,this._animationPromises=new Map,this._animationCache=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}initKtx2(e){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.detectSupport(e)}setDataDir(e){this.basePath=p(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){const t=function(e){return P.get(e)}(e),s=getElectronArg("windowId");return null!=s||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?p(this.basePath,e)+(null!=s?`?windowId=${s}&v=${t}`:""):new URL(p("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if(this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;if(await this.ready,this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);null!=e.texture&&(t.flipY!==e.texture?.flipY?(t.needsUpdate=!0,t.flipY=e.texture?.flipY??!0):t.wrapS!==D(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=D(e.texture?.wrapS)):t.wrapT!==D(e.texture?.wrapT)&&(t.wrapT=D(e.texture?.wrapT),t.needsUpdate=!0))}else try{await this._getTextureLoader(e.fileKey).loadAsync(this.getUri(e.fileKey)).then(t=>(t.texture3D?t=t.texture3D:(t.wrapS=D(e.texture?.wrapS),t.wrapT=D(e.texture?.wrapT),t.flipY=e.texture?.flipY??!0),this.textureCache.set(e.id,t),this._retrievedTextures.push(t),t))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}const t=this.textureCache.get(e.id);return null!=t&&(t.userData.assetId=e.id),t}async getTextureArray(e){const t=e.texture?.textureArrayFileKey,s=e.texture?.textureArrayLayer;if(!t||null==s)return{texture:null,layerIndex:null};if(!this._arrayTexturesByFileKey.has(t)){const e=this._getTextureLoader(t);let s=await e.loadAsync(this.getUri(t));s instanceof n||(s=s.texture3D),this._arrayTexturesByFileKey.set(t,s),this._retrievedTextures.push(s)}return{texture:this._arrayTexturesByFileKey.get(t),layerIndex:s}}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){"mesh"===e.type?(Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)}),j(e.fileKey)):"texture"===e.type&&(this.textureCache.delete(e.id),j(e.fileKey))}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new s,animations:[]};if(!K.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new s,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new s,animations:[]}}const a=this.cache.get(r).scene,n=this.computeCollisionShapes(e,a);!0===t?.mergeGeomtries&&this.optimizeDrawGroups(a);const o=f(a),l=this.cache.get(r).animations;o.traverse(e=>{e instanceof i&&e.material instanceof Array&&(e.material=e.material.slice())});const h=new AssetMeshInstance;h.add(o),h.collisionShapes=n,h.animations=l;const c=e.receiveShadow??!0,u=e.castShadow??!1;if(o.traverse(e=>{e.castShadow=u,e.receiveShadow=c}),!0===t?.rescale&&"number"==typeof e.mesh?.rescale&&h.scale.setScalar(e.mesh?.rescale),!0===t?.applyMaterials){const s=t?.materialResolver??this.materialProvider;if(null!=s)for(const t of e.materialAssignments??[])await A(h,t,s);else console.warn(`applyMaterials was set to true for ${e.name} but no material resolver was provided.`)}return{scene:h,animations:l}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const s=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,s),s}async getAnimationClip(e){if(null==e||null==e.fileKey||null==!e.anim?.clip)return console.warn("Asset or animation clip name is not defined",e),null;const t=e.anim.clip,s=e.fileKey+"|"+t;if(this._animationCache.has(s))return this._animationCache.get(s);if(this._animationPromises.has(s))return this._animationPromises.get(s);const r=(async()=>{try{const r=await this.getMesh(e),i=r.animations.find(e=>e.name===t);return null!=i&&this._animationCache.set(s,i),i}catch(e){return this.onError(e),null}finally{setTimeout(()=>this._animationPromises.delete(s),1e3)}})();return this._animationPromises.set(s,r),r}computeCollisionShapes(e,t){const s=e.id+e.mesh?.collisions?.shapeType;return this.collisionShapeCache.has(s)||this.collisionShapeCache.set(s,w(t,e)),this.collisionShapeCache.get(s)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(e=>(e.scene.traverse(e=>{e instanceof i&&e.material,x(e)?e.visible=!1:e instanceof i&&e.geometry instanceof t&&(e.geometry.hasAttribute("normal")||e.geometry.computeVertexNormals())}),this._retrievedMeshes.push(e.scene),e.scene=function(e,t){let s=!1;if(t.traverseVisible(e=>{U.test(e.name)&&(s=!0)}),!s)return t;const r=new M.LOD,i=[t];for(;i.length>0;){const e=i.shift(),t=e.name.match(U);if(null!=t){const s=parseInt(t[1]);0===s?r.addLevel(e,0):console.warn(`Skipping LOD level ${s} for now as LOD is not fully supported`)}else i.push(...e.children)}return r}(0,e.scene),function(e){const t=I;I.length=0,e.traverse(e=>{(e instanceof M.Camera||e instanceof M.Light)&&t.push(e)}),t.forEach(e=>e.removeFromParent())}(e.scene),e))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid),e.updateWorldMatrix(!0,!0);const s=[];e.traverse(e=>{e instanceof i&&!(e instanceof M.SkinnedMesh)&&e.geometry instanceof t&&Array.isArray(e.material)&&!x(e)&&s.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:t,geometry:r,materialArray:a,parent:n}of s){t.removeFromParent();for(let s=0;s<a.length;s++){const o=a[s],l=r.groups.filter(e=>e.materialIndex===s);if(0===l.length)continue;const h=this.extractGeometryGroups(r,l);h.groups.length>1&&b.mergeGroups(h);const c=new i(h,o);c.copy(t,!1),c.geometry=h,c.material=o,n?n.add(c):e.add(c)}r.dispose()}let r=!0,a=0,n=0;if(e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!x(e)){a++;const t=Object.keys(e.geometry.attributes).length;t!==n&&0!==n&&(r=!1),n=t}else(e instanceof M.SkinnedMesh||e instanceof M.Bone)&&(r=!1)}),a>1&&r){const s=new Map;e.traverse(r=>{if(r instanceof i&&r.geometry instanceof t&&!x(r)){if(Array.isArray(r.material))return;r.updateWorldMatrix(!0,!0);const t=r.material?.uuid||"default";s.has(t)||s.set(t,{material:r.material,geometries:[],objects:[]});const i=s.get(t),a=e.matrixWorld.clone().invert().multiply(r.matrixWorld);i.geometries.push(r.geometry.clone().applyMatrix4(a)),i.objects.push(r)}});for(const e of s.values())for(const t of e.objects)t.removeFromParent();for(const t of s.values()){let s;s=1===t.geometries.length?t.geometries[0]:b.mergeGeometries(t.geometries,!0),s.groups.length>1&&b.mergeGroups(s),e.add(new i(s,t.material))}}e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!x(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&b.mergeGroups(t)}})}extractGeometryGroups(e,s){const r=e.index;if(!r){const r=new t;let i=0;for(const e of s)i+=e.count;if(0===i)return r;for(const t in e.attributes){const a=e.attributes[t],n=a.itemSize,o=a.array,l=new(0,o.constructor)(i*n);let h=0;for(const e of s){const t=e.start*n,s=e.count*n;for(let e=0;e<s;e++)l[h+e]=o[t+e];h+=s}const c=new M.BufferAttribute(l,n,a.normalized);r.setAttribute(t,c)}return r.groups=[{start:0,count:i,materialIndex:0}],r}const i=[];for(const e of s)for(let t=0;t<e.count;t++){const s=r.getX(e.start+t);i.push(s)}if(0===i.length)return new t;const a=new Map,n=[];let o=0;for(const e of i)a.has(e)||(a.set(e,o),o++),n.push(a.get(e));if(0===n.length||0===a.size)return new t;const l=new t;for(const t in e.attributes){const s=e.attributes[t],r=s.itemSize,i=s.array,n=new(0,i.constructor)(a.size*r);for(const[e,t]of a)for(let s=0;s<r;s++)n[t*r+s]=i[e*r+s];const o=new M.BufferAttribute(n,r,s.normalized);l.setAttribute(t,o)}const h=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)h[e]=n[e];return l.setIndex(new M.BufferAttribute(h,1)),l.groups=[{start:0,count:n.length,materialIndex:0}],l}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(e=>({scene:e.scene,animations:e.animations}));case"fbx":return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new h;t.materialOptions={normalizeRGB:!1};const s=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(s)}return this.objLoader.loadAsync(t).then(e=>(k(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>S(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}const P=new Map;function j(e){P.set(e,P.get(e)??1)}function k(e){if(e instanceof i)for(const t of L(e.material))t instanceof M.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach(k)}export class AssetMeshInstance extends a{}export function getElectronArg(e){const t=`--${e}=`,s=window.process?.argv.find(e=>e.startsWith(t));return s?.substring(t.length)}function D(e){switch(e){case"clamp":return M.ClampToEdgeWrapping;case"repeat":return M.RepeatWrapping;case"mirror":return M.MirroredRepeatWrapping}return M.RepeatWrapping}new M.Matrix4;const I=[];const U=/_LOD(\d+)$/;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */