@hology/core 0.0.165 → 0.0.166

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 t,__metadata as e}from"tslib";import o,{ignore as i}from"@plumier/reflect";import{Subject as n,skipWhile as s}from"rxjs";import{Group as r}from"three";import a,{Service as p}from"typedi";import{ActorComponent as c}from"./component.js";import{initComponents as d}from"./internal/component-init.js";import{activeContainerInstance as m,containerRefMap as h}from"./internal/container-map.js";import{randomString as l}from"../../utils/math.js";import{inject as u}from"../inject.js";import{ViewController as f}from"../services/render.js";export function Actor(){const t=p({transient:!0});return function(e){e.__isActor=!0,t(e),o.noop()(e),o.parameterProperties()(e)}}let U=0;export class BaseActor{get position(){return this.object?.position}get quaternion(){return this.object?.quaternion}get rotation(){return this.object?.rotation}onInit(){}onBeginPlay(){}onEndPlay(){}onUpdate(t){}onLateUpdate(t){}constructor(){this.id=++U,this.__isInitialised=!1,this.object=new r,this.disposed=new n,this.onUpdate!==BaseActor.prototype.onUpdate&&u(f).onUpdate(this).pipe(s(()=>!this.__isInitialised)).subscribe(t=>this.onUpdate(t)),this.onLateUpdate!==BaseActor.prototype.onLateUpdate&&u(f).onLateUpdate(this).pipe(s(()=>!this.__isInitialised)).subscribe(t=>this.onLateUpdate(t))}attach(t,e){const o=m.value,i=h.get(this)??m.value??a.of("default");m.value=i;const n=l();i.set({id:n,type:t,transient:!0});const s=i.get(n);if(m.value=o,null!=e)for(const t of Object.keys(e))s[t]=e[t];return this.__isInitialised&&(s.actor=this,s.onInit(),d(s,this)),s}getComponent(t){for(const e of Object.values(this))if(e instanceof t)return e}}t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"position",null),t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"quaternion",null),t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"rotation",null);export function _setupActorUpdateEventHandlers(){this.onUpdate!==c.prototype.onUpdate&&u(f).onUpdate(this.actor).pipe(s(()=>!this.actor?.__isInitialised)).subscribe(t=>this.onUpdate(t)),this.onLateUpdate!==c.prototype.onLateUpdate&&u(f).onLateUpdate(this.actor).pipe(s(()=>!this.actor?.__isInitialised)).subscribe(t=>this.onLateUpdate(t))}/*
1
+ import{__decorate as t,__metadata as e}from"tslib";import o,{ignore as i}from"@plumier/reflect";import{Subject as n,skipWhile as s}from"rxjs";import{Group as r}from"three";import a,{Service as p}from"typedi";import{ActorComponent as c}from"./component.js";import{initComponents as d}from"./internal/component-init.js";import{activeContainerInstance as h,containerRefMap as m}from"./internal/container-map.js";import{randomString as u}from"../../utils/math.js";import{inject as l}from"../inject.js";import{ViewController as f}from"../services/render.js";export function Actor(){const t=p({transient:!0});return function(e){e.__isActor=!0,t(e),o.noop()(e),o.parameterProperties()(e)}}let U=0;export class BaseActor{get position(){return this.object?.position}get quaternion(){return this.object?.quaternion}get rotation(){return this.object?.rotation}onInit(){}onBeginPlay(){}onEndPlay(){}onUpdate(t){}onLateUpdate(t){}constructor(){this.id=++U,this.__isInitialised=!1,this.object=new r,this.disposed=new n,this.attachedComponents=[],this.onUpdate!==BaseActor.prototype.onUpdate&&l(f).onUpdate(this).pipe(s(()=>!this.__isInitialised)).subscribe(t=>this.onUpdate(t)),this.onLateUpdate!==BaseActor.prototype.onLateUpdate&&l(f).onLateUpdate(this).pipe(s(()=>!this.__isInitialised)).subscribe(t=>this.onLateUpdate(t))}attach(t,e){const o=h.value,i=m.get(this)??h.value??a.of("default");h.value=i;const n=u();i.set({id:n,type:t,transient:!0});const s=i.get(n);if(h.value=o,null!=e)for(const t of Object.keys(e))s[t]=e[t];return this.__isInitialised&&(s.actor=this,s.onInit(),d(s,this)),this.attachedComponents.push(s),s}getComponent(t){for(const e of Object.values(this))if(e instanceof t)return e;for(const e of this.attachedComponents)if(e instanceof t)return e}}t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"position",null),t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"quaternion",null),t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"rotation",null);export function _setupActorUpdateEventHandlers(){this.onUpdate!==c.prototype.onUpdate&&l(f).onUpdate(this.actor).pipe(s(()=>!this.actor?.__isInitialised)).subscribe(t=>this.onUpdate(t)),this.onLateUpdate!==c.prototype.onLateUpdate&&l(f).onLateUpdate(this.actor).pipe(s(()=>!this.actor?.__isInitialised)).subscribe(t=>this.onLateUpdate(t))}/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{ActorComponent as o}from"../component.js";const n=new WeakMap;export async function initComponents(t,c,i=!1){const r=[];for(const s of Object.values(t))if(s instanceof o||null!=s?.constructor&&!0===s.constructor.__isActorComponent){if(i&&!s.constructor.__inEditor)continue;if(!i&&s.constructor.__onlyEditor)continue;const o=s;if(o.actor=c,n.has(o))continue;n.set(o,!0),await o.onInit(),r.push(initComponents(s,c,i))}return Promise.all(r)}/*
1
+ import{ActorComponent as o}from"../component.js";const n=new WeakMap;export async function initComponents(t,c,i=!1){const s=[],r=[...Object.values(t)];t===c&&c.attachedComponents.forEach(o=>r.push(o));for(const t of r)if(t instanceof o||null!=t?.constructor&&!0===t.constructor.__isActorComponent){if(i&&!t.constructor.__inEditor)continue;if(!i&&t.constructor.__onlyEditor)continue;const o=t;if(o.actor=c,n.has(o))continue;n.set(o,!0),await o.onInit(),s.push(initComponents(t,c,i))}return Promise.all(s)}/*
2
2
  * Copyright (©) 2025 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},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}},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 };\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\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\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) {\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 float inShadow = texture2DCompare(directionalShadowMap, shadowCoord.xy, shadowCoord.z - bias);\n\n return dirLight.color * phase * inShadow;\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\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, 0.0);\n\n // An alternative method to get stepSize but is less dynamic\n // float stepSize = (t1 - t0) / float(MAX_STEP_COUNT);\n\n float maxStepSize = 0.3; // adjust for visual quality\n float distance = t1 - t0;\n int stepCount = int(ceil(distance / maxStepSize));\n stepCount = min(stepCount, MAX_STEP_COUNT); // optional clamp for performance\n float stepSize = distance / float(stepCount);\n \n // Add a slight random offset to reduce banding \n float jitterAmount = 1.0;\n float rayStartOffset = random * stepSize * jitterAmount;\n t0 += rayStartOffset;\n\n for (int i = 0; i < stepCount; i++) {\n\n float t = t0 + float(i) * stepSize;\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); // simple white light\n #if VOLUMETRIC == 1\n\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 light += calcDirectionalLight(p, rayDir, g, directionalLight);\n\n // Ambient \n light += ambientLight / 12.0;\n\n // Use luminosity to reduce transparency when dark to avoid dark fog\n transmittance *= exp(-density * stepSize * luminosity(light));\n #else\n light = vec3(1.0);\n transmittance *= exp(-density * stepSize);\n #endif\n\n light *= volume.albedo;\n inscatter += transmittance * light * density * stepSize;\n }\n }\n #endif\n\n float alpha = 1.0 - transmittance;\n // inscatter += ambientLight * alpha;\n\n vec3 color = inscatter;\n\n gl_FragColor = vec4(color, alpha);\n }\n "}),this.material.onBeforeCompile=t=>{console.log("compile material",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:2}},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).r;\n\n float centerDepth = unpackRGBAToDepth( texture2D( tDepth, 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 // 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 = unpackRGBAToDepth( texture2D( tDepth, uv ) );\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}},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 varying vec2 vUv;\n void main() {\n vec4 sceneColor = texture2D(tDiffuse, vUv);\n vec4 fogColor = texture2D(tFog, vUv);\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})}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=u,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=f,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)}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},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}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,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[0];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);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)}}const u=new t.Vector2(1,0),f=new t.Vector2(0,1);/*
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},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}},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 };\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\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\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) {\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 float inShadow = texture2DCompare(directionalShadowMap, shadowCoord.xy, shadowCoord.z - bias);\n\n return dirLight.color * phase * inShadow;\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\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, 0.0);\n\n // An alternative method to get stepSize but is less dynamic\n // float stepSize = (t1 - t0) / float(MAX_STEP_COUNT);\n\n float maxStepSize = 0.3; // adjust for visual quality\n float distance = t1 - t0;\n int stepCount = int(ceil(distance / maxStepSize));\n stepCount = min(stepCount, MAX_STEP_COUNT); // optional clamp for performance\n float stepSize = distance / float(stepCount);\n \n // Add a slight random offset to reduce banding \n float jitterAmount = 1.0;\n float rayStartOffset = random * stepSize * jitterAmount;\n t0 += rayStartOffset;\n\n for (int i = 0; i < stepCount; i++) {\n\n float t = t0 + float(i) * stepSize;\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); // simple white light\n #if VOLUMETRIC == 1\n\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 light += calcDirectionalLight(p, rayDir, g, directionalLight);\n\n // Ambient \n light += ambientLight / 12.0;\n\n // Use luminosity to reduce transparency when dark to avoid dark fog\n transmittance *= exp(-density * stepSize * luminosity(light));\n #else\n light = vec3(1.0);\n transmittance *= exp(-density * stepSize);\n #endif\n\n light *= volume.albedo;\n inscatter += transmittance * light * density * stepSize;\n }\n }\n #endif\n\n float alpha = 1.0 - transmittance;\n // inscatter += ambientLight * alpha;\n\n vec3 color = inscatter;\n\n gl_FragColor = vec4(color, 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:2}},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).r;\n\n float centerDepth = unpackRGBAToDepth( texture2D( tDepth, 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 // 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 = unpackRGBAToDepth( texture2D( tDepth, uv ) );\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}},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 varying vec2 vUv;\n void main() {\n vec4 sceneColor = texture2D(tDiffuse, vUv);\n vec4 fogColor = texture2D(tFog, vUv);\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})}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=u,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=f,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)}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},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}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,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[0];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);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)}}const u=new t.Vector2(1,0),f=new t.Vector2(0,1);/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
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 r,Material as a,Matrix4 as n,Mesh as o,PerspectiveCamera as l,ShaderChunk as h,ShaderMaterial as d,WebGLRenderTarget as u,Texture as c,Euler as p,MeshStandardMaterial as m}from"three";import{CopyShader as f,EffectComposer as g,FXAAShader as v,GammaCorrectionShader as M,LUTPass as T,RenderPass as b,ShaderPass as x,VRButton as P}from"three-stdlib";import{CSMShader as y,CSMUtil as w}from"./csm.js";import{bool as S,colorToNormal as R,float as C,NodeShaderMaterial as A,standardMaterial as F,uniformFloat as U,uniformVec3 as E,toonMaterial as O,lambertMaterial as B,normalize as I,rgb as D,rgba as W,textureSampler2d as L,transformed as j,varying as V,varyingAttributes as _,varyingTransformed as G,vec4 as q,BooleanExpression as k,select as N,ifDefApply as H,uniformSampler2d as z,RgbaNode 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 J from"three/examples/jsm/libs/stats.module.js";import{GTAOPass as Z}from"three/examples/jsm/postprocessing/GTAOPass.js";import{Service as ee}from"typedi";import{depthUniformName as te,farUniformName as se,nearUniformName as ie,resolutionUniformName as re,sceneNormalUniformName as ae,screenUV as ne,supportsDepthTextureExtension as oe}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as le}from"./shader-nodes/time.js";import{aoMapUniformName as he,sceneMapUniformName as de}from"./shader-nodes/scene-sample.js";import{DepthPass as ue}from"./utils/three/depth-pass.js";import{GPUStatsPanel as ce}from"./utils/three/gpu-stats-panel.js";import{OutlinePass as pe}from"./utils/three/outline-pass.js";import{findFirstVisibleObject as me,traverseVisibleStop as fe}from"./utils/three/traverse.js";import{clamp as ge}from"./utils/math.js";import{ColorPass as ve}from"./rendering/color-pass.js";import{SSRPass as Me}from"./rendering/ssr/SSRPass.js";import{SSRShader as Te}from"./rendering/ssr/SSRShader.js";import{VolumetricFogPass as be}from"./rendering/fog/volumetric-fog-pass.js";import{OutlineEffect as xe}from"./rendering/outline-effect.js";import{UnrealBloomPass as Pe}from"./rendering/bloom/UnrealBloomPass.js";import{highPrecisionEyeDepth as ye}from"./shader-nodes/depth.js";import{packDepthToRGBA as we}from"three-shader-graph";import{FogVolumeObject as Se}from"./rendering/fog/fog-volume-object";import{ParallaxStandardMaterial as Re}from"./shader/builtin/standard-shader.js";import{parallaxOcclusionMapping as Ce}from"./shader-nodes/pom.js";import{FullScreenQuad as Ae}from"three-stdlib";import{edgeDepthEffect as Fe}from"./shader-nodes/effects";import{decalDiscard as Ue}from"./shader-nodes/decal.js";import{Pass as Ee}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 Be=new i.MeshBasicMaterial({color:"black"}),Ie=new i.MeshDepthMaterial;var De;Ie.depthPacking=i.RGBADepthPacking,Ie.blending=i.NoBlending,Ie.side=i.DoubleSide,function(e){e[e.opaque=0]="opaque",e[e.transparent=1]="transparent"}(De||(De={}));const We=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let Le=e=class{setPaused(e){this.paused=e}resizeRender(){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*this.resolutionScale,t*this.resolutionScale),this.dofPass.setSize(e*this.resolutionScale,t*this.resolutionScale),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.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.aoPass.setSize(e*this.resolutionScale,t*this.resolutionScale),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.fquadCopy=new Ae(new d(f)),this.fquadCopyOpaque=new Ae(new A({outputs:[z("tSceneColor",new c).sample(ne),q(z("tDepthTexture",new i.DepthTexture(1,1)).sample(ne).r)]})),this.fquadBlendAO=(()=>{const e=q(1),t=new A({outputs:[z("tAO",new c).sample(ne),e,e],transparent:!0});t.depthWrite=!1,t.depthTest=!1,t.blending=i.MultiplyBlending;return new Ae(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 J,this._showStats=!0,this.gbufferMaterialCache=new Map,this.tbufferMaterialCache=new Map,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 r,this.hadBloom=!1,this.bloomStoredMaterials={},this.bloomHidden=[],this._customDepthMaterialCache=new WeakMap,null!=s.maxPixelRatio&&(this.maxPixelRatio=s.maxPixelRatio),window.renderer=this.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 a=new xe(this.renderer,{defaultThickness:.005,defaultColor:[0,0,0],defaultAlpha:1,defaultKeepAlive:!0});this.outlineEffect=a,this.createGRenderTarget(),this.composer=new g(this.renderer);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=oe(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 b(this.scene,this.camera),new x(f,"prevtexture"));h.enabled=!0,h.needsSwap=!0,h.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass=h;const u=new Pe(l,1.5,.4,.85);u.threshold=1,u.strength=.9,u.radius=.5,this.bloomPass=u;const p=new Z(this.scene,this.camera,t.clientWidth,t.clientWidth,{});p.normalRenderTarget?.dispose(),p.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),p.output=Z.OUTPUT.Off,p.enabled=!1,this.aoPass=p,this.fquadBlendAO.material.uniforms.tAO.value=p.pdRenderTarget.texture,Te.fragmentShader=Te.fragmentShader.replace("if(metalness==0.) return;","if(metalness<0.1) return;");const m=new Me({renderer:this.renderer,scene:this.scene,camera:this.camera,groundReflector:null,selects:[],normalTexture:this.gRenderTarget.textures[2],depthTexture:this.gRenderTarget.depthTexture});m.output=Me.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 y=new et((e,t,s,i,r)=>{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(y);const S=new et((e,t,s,i,r)=>{this.renderer.setRenderTarget(this.gRenderTarget),this.renderScene(De.transparent),this.renderer.setRenderTarget(null)});this.composer.addPass(S),this.composer.addPass(h),this.composer.addPass(m),this.phasedRenderPass=new Ze(this.scene,this.camera,this.gRenderTarget),this.composer.addPass(this.phasedRenderPass),this.composer.addPass(u),u.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 pe(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 C=new x(v);C.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(C),this.fxaaPass=C,this.fxaaPass.enabled=!1,!0===s.enableOutlines&&this.setEnableOutlines(!0),new x(M).clear=!1,this.fixStatsStyle(),this.lutPass=new T({}),this.lutPass.enabled=!1,this.composer.addPass(this.lutPass);const F=new x(f,"prevtexture");F.enabled=!0,F.needsSwap=!1,F.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[1],F.renderToScreen=!0;const U=new Q;this.composer.addPass(U)}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){this.camera=e,this.composer.passes.forEach(t=>{t instanceof b?t.camera=e:t instanceof pe?t.renderCamera=e:(t instanceof ue||t instanceof Z)&&(t.camera=e)}),this.ssrPass&&(this.ssrPass.camera=e),this.aoPass&&(this.aoPass.camera=e),this.phasedRenderPass&&(this.phasedRenderPass.camera=e),null==this.csm?(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"}),this.csm&&Array.isArray(this.csm.lights),this.csm.fade=!0,h.lights_fragment_begin=y.lights_fragment_begin):(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 r=new i.WebGLRenderTarget(t.clientWidth*s,t.clientHeight*s);return r.texture.minFilter=i.NearestFilter,r.texture.magFilter=i.NearestFilter,r.texture.generateMipmaps=!1,r.stencilBuffer=!1,r.depthTexture=new i.DepthTexture(128,128),r.depthTexture.type=i.UnsignedShortType,r.depthTexture.minFilter=i.NearestFilter,r.depthTexture.magFilter=i.NearestFilter,r}static createAOMaskDepthRenderTarget(e,t){const s=new i.WebGLRenderTarget(t.clientWidth*e.getPixelRatio(),t.clientHeight*e.getPixelRatio(),{type:i.HalfFloatType});return s.texture.minFilter=i.NearestFilter,s.texture.magFilter=i.NearestFilter,s.texture.generateMipmaps=!1,s.stencilBuffer=!1,s.depthTexture=new i.DepthTexture(128,128),s.depthTexture.type=i.UnsignedInt248Type,s.depthTexture.minFilter=i.NearestFilter,s.depthTexture.magFilter=i.NearestFilter,s}createSceneColorRenderTarget(e,t){const s=new i.WebGLRenderTarget(t.clientWidth*this.renderer.getPixelRatio(),t.clientHeight*this.renderer.getPixelRatio(),{count:2,type:i.FloatType,format:i.RGBAFormat,colorSpace:i.SRGBColorSpace,depthBuffer:!1,stencilBuffer:!1});return s.texture.minFilter=i.LinearFilter,s.texture.magFilter=i.LinearFilter,s.texture.generateMipmaps=!1,s}createGRenderTarget(){const e=this.container;null!=this.gRenderTarget&&this.gRenderTarget.dispose(),this.gRenderTarget=new u(e.clientWidth*this.renderer.getPixelRatio(),e.clientHeight*this.renderer.getPixelRatio(),{count:3,minFilter:i.NearestFilter,magFilter:i.NearestFilter,type:i.HalfFloatType,format:i.RGBAFormat}),this.gRenderTarget.depthTexture=new i.DepthTexture(e.clientWidth,e.clientHeight),this.gRenderTarget.depthTexture.type=i.UnsignedIntType,this.gRenderTarget.depthTexture.minFilter=i.NearestFilter,this.gRenderTarget.depthTexture.magFilter=i.NearestFilter,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(){this.running=!1,window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],this.renderer.dispose(),this.gRenderTarget.dispose(),this.aoMaskDepthRenderTarget.dispose(),this.sceneColorRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren(),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 A&&(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:ze(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 A||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)}updateUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e in s){const t=i[e],r=s[e].value;null!=t&&t.value!==r&&(t.value=r)}}updateLightUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e of tt){const t=i[e],r=s[e];null!=r&&null!=t&&(t.value=r.value)}}createGBufferMaterial(e,t){const s=t===De.opaque?this.gbufferMaterialCache:this.tbufferMaterialCache;let r=s.get(e);if(null==r){let n=_.uv;e instanceof Re&&null!=e.heightMap&&(n=Ce(n,L(e.heightMap),C(e.heightScale??1)));let o=G.normal;e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial?null!=e.normalMap&&(o=R(L(e.normalMap).sample(n),e.normalScale.x??1)):e instanceof A&&null!=e.outputNormal&&(o=e.outputNormal),!0!==e.userData.disableAO&&(o=H("DOUBLE_SIDED",o,e=>N(new k("gl_FrontFacing"),e,e.multiplyScalar(-1))));let l=e.userData?.reflective?C(0):C(1);if(e instanceof i.MeshStandardMaterial){const t=U("roughness",e.roughness??1);l=null!=e.roughnessMap?L(e.roughnessMap).sample(n).g.multiply(t):t}else e instanceof A&&null!=e.outputRoughness&&(l=e.outputRoughness);let h=null;(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial)&&null!=e.lightMap&&(h=L(e.lightMap).sample(n).rgb.multiplyScalar(e.lightMapIntensity));let u,c=C(0);if(e instanceof i.MeshStandardMaterial){const t=U("metalness",e.metalness??0);c=null!=e.metalnessMap?L(e.metalnessMap).sample(n).b.multiply(t):t}else e instanceof A&&e.outputRoughness;let p=C(1);e instanceof i.MeshStandardMaterial?null!=e.aoMap&&(u=L(e.aoMap).sample(n).r,p=U("aoMapIntensity",e.aoMapIntensity)):e instanceof A&&e.outputRoughness;const f=U("opacity",e.opacity??1);let g=C(1);e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial?(null!=e.alphaMap&&(g=L(e.alphaMap).sample(n).r),g=g.multiply(f)):e instanceof A&&null!=e.outputOpacity&&(g=e.outputOpacity);let v=W(0,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("color",(new i.Vector3).setFromColor(e.color));null!=e.map?(v=L(e.map).sample(n).multiply(W(t,1)),g=g.multiply(v.w)):v=W(t,1)}const M=!0===e.userData.hasBloom;let T=D(0);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=E("emissive",(new i.Vector3).setFromColor(e.emissive));T=null!=e.emissiveMap?L(e.emissiveMap).sample(n).rgb.multiply(t):t,T=T.multiplyScalar(e.emissiveIntensity)}else e instanceof A&&null!=e.outputEmissive&&(T=e.outputEmissive);const b=e instanceof d&&null!=e.uniforms[te],x=e instanceof d&&null!=e.uniforms[de],P=e instanceof d&&null!=e.uniforms[he],y=e.transparent&&e.alphaTest<=.01||e.blending===i.AdditiveBlending,w=U("alphaTest",e.alphaTest);let j,V=e.alphaTest>0?g.lt(w):y&&t===De.opaque?g.lt(.8):S(!1);!0===e.userData.isDecal&&(V=V.or(Ue)),j=y?q(0,0,0,0):(a=o,I(a).multiplyScalar(.5).addScalar(.5)).rgba(l);const z=e instanceof A?e.outputPosition:void 0,$=e instanceof A?e.outputTransform:void 0;let X,Y=W("black",1);if(e instanceof A&&null!=e.outputColor)Y=e.outputColor;else if(e instanceof i.MeshStandardMaterial)Y=F({color:v,metalness:c,roughness:l,emissive:T.rgb,normal:o,ambientOcclusion:u,ambientOcclusionIntensity:p,bakedLight:h});else if(e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)Y=B({color:v.rgb});else if(e instanceof i.MeshBasicMaterial){let e=v.rgb,t=h??D("white");null!=u&&(t=t.multiplyScalar(u.subtract(1).multiply(p).add(1))),e=e.multiply(t),Y=e.rgba(g)}else e instanceof i.MeshToonMaterial&&(Y=O({color:v,emissive:T.rgb,normal:o,ambientOcclusion:u,ambientOcclusionIntensity:p,bakedLight:h}));(e instanceof A||e instanceof i.MeshStandardMaterial)&&(X=e.envMap);let Q=!0;(e instanceof m||e instanceof i.MeshBasicMaterial||e instanceof i.ShaderMaterial)&&(Q=e.fog);let K=W(Y.rgb,g);Q&&(K=new FogNode(K)),r=new A({transform:$,position:null==$?z:void 0,outputs:[K,T.rgba(t===De.opaque?w:M?1:0),j],opacity:g,outputEncoding:!1,fog:Q,transparent:e.transparent,lights:!0,envMap:X,discard:V}),e instanceof i.MeshStandardMaterial&&null!=e.envMap&&null!=r.uniforms.envMapIntensity&&(r.uniforms.envMapIntensity.value=e.envMapIntensity),(e instanceof A||e instanceof i.MeshStandardMaterial)&&this.applyEnvMap(r),e instanceof A&&Object.assign(r.defines,e.defines),r.userData.mrtOutputs=3,r.forceSinglePass=e.forceSinglePass,r.side=e.side,r.blending=e.blending,y?(r.depthWrite=!e.transparent,r.depthTest=e.depthTest,r.colorWrite=t===De.transparent):(r.depthWrite=e.depthWrite,r.depthTest=e.depthTest),r.visible=e.visible,r.alphaTest=e.alphaTest,r.alphaHash=e.alphaHash,t===De.opaque?(r.visible&&(r.visible=!b&&!x&&!P),r.visible&&(r.visible=!y)):t===De.transparent&&r.visible&&(r.visible=y||b||x||P),Object.assign(r.userData,e.userData),r.visible&&(this.csm.setupMaterial(r),e instanceof d&&Object.assign(r.uniforms,e.uniforms)),s.set(e,r)}var a;return r.visible&&e instanceof d&&this.updateUniformValues(e,r),r}loop(e,t=!1){const s=this.stats,r=s.addPanel(new J.Panel("Calls","#83f","#002")),a=s.addPanel(new J.Panel("Triangles","#c32","#002"));let l;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(l=new ce(this.renderer.getContext()),s.addPanel(l)),this.showStats=t;let h=10,d=1e3;const u=()=>{const e=this.renderer.info.render.calls;e>h&&(h=e,setTimeout(()=>h=10,5e3)),r.update(e,h);const t=this.renderer.info.render.triangles;t>d&&(d=t,setTimeout(()=>d=1e3,5e3)),a.update(t,d)};performance.now();i.Ray.prototype.intersectTriangle;this.resizeRender();const c=[],p=[],m=[];let f=0;const g=new n,v=new n;let M=0;let T=this.paused;const b=t=>{const r=this.renderer.getContext();if(this.paused&&this.running&&r.drawingBufferHeight>1)return setTimeout(()=>b(t),500),void(T=!0);this.renderer.clear(),this.applyPostProcessSettings(),this.renderer.autoClear=!1,this.renderer.clear(),this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),this.camera,s.begin(),this.showStats&&l?.startQuery(),this.ssrPass.gpuPanel=l;let a=(t*=.001)-f;if(f=t,T&&(a=.016,T=!1),g.copy(this.camera.matrixWorld),a>1){let t=a;for(;t>.05;)e(je),t-=je;e(t)}else e(a);this.onLoopCallbacks.forEach(e=>e(a)),this.camera?.updateMatrixWorld(),v.copy(this.camera.matrixWorld),t-M>.08&&!v.equals(g)&&(this.renderer.shadowMap.needsUpdate=!0,M=t),this.csm.update();let n=!1;c.length=0,p.length=0,m.length=0;const h=_e;qe.multiplyMatrices(this.camera.projectionMatrix,this.camera.matrixWorldInverse),h.setFromProjectionMatrix(qe);let d=!1,x=!1,P=!1;this.scene.traverseVisible(e=>{if(this.setupCsm(e),this.outlineEffect.apply(e),e instanceof Se&&(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),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[te])&&isObjectInFrustum(e,h)?(this.initDepthUniform(e.material),x=!0):e instanceof X&&(e.visible=!1,p.push(e)),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[he]&&isObjectInFrustum(e,h)&&e.material instanceof A&&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,P=!0),e instanceof o&&e.material?.uniforms&&null!=e.material?.uniforms[le])e.material.uniforms[le].value=t;else if(e instanceof o&&Array.isArray(e.material))for(const s of e.material)s.uniforms&&null!=s.uniforms[le]&&(s.uniforms[le].value=t)}),this.bloomPass.enabled=n,this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.clear(),this.renderScene(De.opaque),this.aoPass.output=Z.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)),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&&d&&this.volumetricFogPass.update(this.camera,this.gRenderTarget,this.csm,this.scene);try{!this.paused&&this.running&&(this.render(a),this.showStats&&l?.endQuery(),this.showStats&&u(),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(b)},1e3/this.fpsCap):requestAnimationFrame(b))};!0===this.options.enableXR?this.renderer.setAnimationLoop(b):requestAnimationFrame(b)}renderScene(e){Ye.clear(),Qe.length=0;fe(this.scene,t=>{if(Ke(t))return Qe.push(t),t.visible=!1,!1;if(t instanceof o){Ye.set(t,t.material);let s=!1;if(Array.isArray(t.material)){t.material=t.material.slice();for(let i=0;i<t.material.length;i++)t.material[i]=this.createGBufferMaterial(t.material[i],e),s||(s=t.material[i].visible)}else t.material=this.createGBufferMaterial(t.material,e),s||(s=t.material.visible);s?t.visible=!0:null!=t.children&&0!=t.children.length||(Qe.push(t),t.visible=!1)}});const t=this.scene.matrixWorldAutoUpdate,s=this.scene.matrixAutoUpdate,i=this.renderer.shadowMap.autoUpdate;e!==De.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===De.opaque&&Ye.forEach((e,t)=>{!Array.isArray(e)&&!Array.isArray(t.material)&&e instanceof d&&this.updateLightUniformValues(t.material,e)}),Ye.forEach((e,t)=>{t.material=e}),Qe.forEach((e,t)=>{e.visible=!0,e.updateMatrixWorld(!0)}),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,r=!1,a=!1,n=!1,o=!1;if(null==this.camera)return;const h=this.camera.getWorldPosition(ke);let d=[];for(const e of this.postProcessVolumes){if(!Ve(e.object))continue;let l=e.blendWeight??1;const u=e.distanceToPoint(h);u>e.blendRadius||(e.blendRadius>0&&(l*=ge(1-u/e.blendRadius,0,1)),l>1&&(l=1),l>0&&(d.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),a=!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&&(r=!0,t.depthFocus=void 0!==t.depthFocus?i.MathUtils.lerp(t.depthFocus,e.settings.depthFocus,l):e.settings.depthFocus),void 0!==e.settings.depthAperture&&(r=!0,t.depthAperture=void 0!==t.depthAperture?i.MathUtils.lerp(t.depthAperture,e.settings.depthAperture,l):e.settings.depthAperture),void 0!==e.settings.depthMaxBlur&&(r=!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=a,this.colorPass.colorTint=t.colorTint,this.colorPass.colorTintIntensity=t.colorTintIntensity,this.colorPass.enabled=a||o,r&&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(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,_e)&&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!=me(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===Be.id)return;this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=Be:(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 d&&(e.uniforms[te].value=this.sceneColorRenderTarget.textures[1],this.camera instanceof l&&(null!=e.uniforms[ie]&&(e.uniforms[ie].value=this.camera.near),null!=e.uniforms[se]&&(e.uniforms[se].value=this.camera.far)))}initNormalUniform(e){e instanceof d&&null!=e.uniforms[ae]&&(e.uniforms[ae].value=this.gRenderTarget.textures[2])}initShadowUniform(e,t){t instanceof A&&t.uniforms.receiveShadow&&(t.uniforms.receiveShadow.value=e.receiveShadow)}initResolutionUniform(e){if(e instanceof d&&null!=e.uniforms[re]){const t=this.previousClientWith,s=this.previousClientHeight;e.uniforms[re].value.set(t*this.renderer.getPixelRatio(),s*this.renderer.getPixelRatio())}}initAoUniform(e){if(this.aoPass.enabled){e.uniforms[he].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 A&&!t.transparent&&t.depthWrite){let s=this._customDepthMaterialCache.get(t);if(null==s){const e=we(ye);let i;null!=t.alphaTest&&t.alphaTest>0&&null!=t.outputOpacity&&(i=t.outputOpacity.lt(t.alphaTest)),s=new A({color:e,discard:i}),this._customDepthMaterialCache.set(t,s)}e.customDepthMaterial=s}}};Le=e=t([ee(),s("design:paramtypes",[HTMLElement,Object])],Le);export{Le as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const je=.05;function Ve(e){let t=e;for(;t;){if(!1===t.visible)return!1;t=t.parent}return!0}Z.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 _e=new i.Frustum,Ge=new i.Box3,qe=new i.Matrix4;export function isObjectInFrustum(e,t){const s=Ge.setFromObject(e);return t.intersectsBox(s)}const ke=new i.Vector3;const Ne=new n,He=new p;function ze(e,t,s=new i.Matrix3){return He.copy(e),He.x*=-1,He.y*=-1,He.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(He.y*=-1,He.z*=-1),s.setFromMatrix4(Ne.makeRotationFromEuler(He))}const $e=new A({outputs:[q(0,0,0,0),q(0,0,0,0),W(D("white"),Fe(4))],transparent:!0}),Xe=new i.MeshBasicMaterial({color:"blue",transparent:!0,opacity:.5});$e.depthWrite=!1;new o(new i.BoxGeometry(4,4,4),Xe);const Ye=new Map,Qe=[];function Ke(e){return e instanceof i.Sprite||e.isPoints||e.isLine||e.isTransformControls||e.isTransformControlsGizmo||e instanceof o&&Je(e,e.material)}function Je(e,t){return null==t||(Array.isArray(t)?t.some(t=>Je(e,t)):t instanceof i.RawShaderMaterial||t instanceof i.ShaderMaterial&&!(t instanceof A))}class Ze extends Ee{constructor(e,t,s){super(),this.scene=e,this.camera=t,this.gRenderTarget=s,this.needsSwap=!1}render(e,t,s,i,r){const a=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 d=s.depthTexture;s.depthTexture=this.gRenderTarget.depthTexture,e.setRenderTarget(s),Qe.length=0;let u=0;this.scene.traverseVisible(e=>{const t=Ke(e);e instanceof o&&!t?(Qe.push(e),e.visible=!1):t&&u++}),u>0&&e.render(this.scene,this.camera),Qe.forEach((e,t)=>{e.visible=!0}),e.setRenderTarget(null),e.autoClear=a,s.depthTexture=d,this.scene.matrixWorldAutoUpdate=n,this.scene.matrixAutoUpdate=l,e.shadowMap.autoUpdate=h}}class et extends Ee{constructor(e){super(),this.fn=e}render(e,t,s,i,r){this.fn(e,t,s,i,r)}}const tt=["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"],st=E("fogColor");export class FogNode extends ${constructor(e,t=st){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),r=e.get(this.fogColor),a=e.get(U("fogFar")),n=e.get(U("fogNear")),o=e.get(U("fogDensity")),l=e.get(V(j.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}, ${a}, ${l} );\n #endif\n vec4 color_vec4_${t} = vec4(mix(${s}, ${r}, fogFactor_${t}), ${i});\n `,out:`color_vec4_${t}`}}}/*
1
+ var e;import{__decorate as t,__metadata as s}from"tslib";import*as i from"three";import{Color as r,Material as a,Matrix4 as n,Mesh as o,PerspectiveCamera as l,ShaderChunk as h,ShaderMaterial as d,WebGLRenderTarget as u,Texture as c,Euler as p,MeshStandardMaterial as m}from"three";import{CopyShader as f,EffectComposer as g,FXAAShader as v,GammaCorrectionShader as M,LUTPass as T,RenderPass as b,ShaderPass as x,VRButton as P}from"three-stdlib";import{CSMShader as y,CSMUtil as w}from"./csm.js";import{bool as S,colorToNormal as R,float as C,NodeShaderMaterial as A,standardMaterial as F,uniformFloat as U,uniformVec3 as E,toonMaterial as O,lambertMaterial as B,normalize as I,rgb as D,rgba as W,textureSampler2d as L,transformed as j,varying as V,varyingAttributes as _,varyingTransformed as G,vec4 as q,BooleanExpression as k,select as N,ifDefApply as H,uniformSampler2d as z,RgbaNode 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 J from"three/examples/jsm/libs/stats.module.js";import{GTAOPass as Z}from"three/examples/jsm/postprocessing/GTAOPass.js";import{Service as ee}from"typedi";import{depthUniformName as te,farUniformName as se,nearUniformName as ie,resolutionUniformName as re,sceneNormalUniformName as ae,screenUV as ne,supportsDepthTextureExtension as oe}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as le}from"./shader-nodes/time.js";import{aoMapUniformName as he,sceneMapUniformName as de}from"./shader-nodes/scene-sample.js";import{DepthPass as ue}from"./utils/three/depth-pass.js";import{GPUStatsPanel as ce}from"./utils/three/gpu-stats-panel.js";import{OutlinePass as pe}from"./utils/three/outline-pass.js";import{findFirstVisibleObject as me,traverseVisibleStop as fe}from"./utils/three/traverse.js";import{clamp as ge}from"./utils/math.js";import{ColorPass as ve}from"./rendering/color-pass.js";import{SSRPass as Me}from"./rendering/ssr/SSRPass.js";import{SSRShader as Te}from"./rendering/ssr/SSRShader.js";import{VolumetricFogPass as be}from"./rendering/fog/volumetric-fog-pass.js";import{OutlineEffect as xe}from"./rendering/outline-effect.js";import{UnrealBloomPass as Pe}from"./rendering/bloom/UnrealBloomPass.js";import{highPrecisionEyeDepth as ye}from"./shader-nodes/depth.js";import{packDepthToRGBA as we}from"three-shader-graph";import{FogVolumeObject as Se}from"./rendering/fog/fog-volume-object";import{ParallaxStandardMaterial as Re}from"./shader/builtin/standard-shader.js";import{parallaxOcclusionMapping as Ce}from"./shader-nodes/pom.js";import{FullScreenQuad as Ae}from"three-stdlib";import{edgeDepthEffect as Fe}from"./shader-nodes/effects";import{decalDiscard as Ue}from"./shader-nodes/decal.js";import{Pass as Ee}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 Be=new i.MeshBasicMaterial({color:"black"}),Ie=new i.MeshDepthMaterial;var De;Ie.depthPacking=i.RGBADepthPacking,Ie.blending=i.NoBlending,Ie.side=i.DoubleSide,function(e){e[e.opaque=0]="opaque",e[e.transparent=1]="transparent"}(De||(De={}));const We=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let Le=0,je=e=class{setPaused(e){this.paused=e}resizeRender(){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*this.resolutionScale,t*this.resolutionScale),this.dofPass.setSize(e*this.resolutionScale,t*this.resolutionScale),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.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.aoPass.setSize(e*this.resolutionScale,t*this.resolutionScale),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._id=Le++,this.fquadCopy=new Ae(new d(f)),this.fquadCopyOpaque=new Ae(new A({outputs:[z("tSceneColor",new c).sample(ne),q(z("tDepthTexture",new i.DepthTexture(1,1)).sample(ne).r)]})),this.fquadBlendAO=(()=>{const e=q(1),t=new A({outputs:[z("tAO",new c).sample(ne),e,e],transparent:!0});t.depthWrite=!1,t.depthTest=!1,t.blending=i.MultiplyBlending;return new Ae(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 J,this._showStats=!0,this.gbufferMaterialCache=new Map,this.tbufferMaterialCache=new Map,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 r,this.hadBloom=!1,this.bloomStoredMaterials={},this.bloomHidden=[],this._customDepthMaterialCache=new WeakMap,null!=s.maxPixelRatio&&(this.maxPixelRatio=s.maxPixelRatio),window.renderer=this.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 a=new xe(this.renderer,{defaultThickness:.005,defaultColor:[0,0,0],defaultAlpha:1,defaultKeepAlive:!0});this.outlineEffect=a,this.createGRenderTarget(),this.composer=new g(this.renderer);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=oe(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 b(this.scene,this.camera),new x(f,"prevtexture"));h.enabled=!0,h.needsSwap=!0,h.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass=h;const u=new Pe(l,1.5,.4,.85);u.threshold=1,u.strength=.9,u.radius=.5,this.bloomPass=u;const p=new Z(this.scene,this.camera,t.clientWidth,t.clientWidth,{});p.normalRenderTarget?.dispose(),p.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),p.output=Z.OUTPUT.Off,p.enabled=!1,this.aoPass=p,this.fquadBlendAO.material.uniforms.tAO.value=p.pdRenderTarget.texture,Te.fragmentShader=Te.fragmentShader.replace("if(metalness==0.) return;","if(metalness<0.1) return;");const m=new Me({renderer:this.renderer,scene:this.scene,camera:this.camera,groundReflector:null,selects:[],normalTexture:this.gRenderTarget.textures[2],depthTexture:this.gRenderTarget.depthTexture});m.output=Me.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 y=new tt((e,t,s,i,r)=>{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(y);const S=new tt((e,t,s,i,r)=>{this.renderer.setRenderTarget(this.gRenderTarget),this.renderScene(De.transparent),this.renderer.setRenderTarget(null)});this.composer.addPass(S),this.composer.addPass(h),this.composer.addPass(m),this.phasedRenderPass=new et(this.scene,this.camera,this.gRenderTarget),this.composer.addPass(this.phasedRenderPass),this.composer.addPass(u),u.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 pe(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 C=new x(v);C.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(C),this.fxaaPass=C,this.fxaaPass.enabled=!1,!0===s.enableOutlines&&this.setEnableOutlines(!0),new x(M).clear=!1,this.fixStatsStyle(),this.lutPass=new T({}),this.lutPass.enabled=!1,this.composer.addPass(this.lutPass);const F=new x(f,"prevtexture");F.enabled=!0,F.needsSwap=!1,F.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[1],F.renderToScreen=!0;const U=new Q;this.composer.addPass(U)}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){this.camera=e,this.composer.passes.forEach(t=>{t instanceof b?t.camera=e:t instanceof pe?t.renderCamera=e:(t instanceof ue||t instanceof Z)&&(t.camera=e)}),this.ssrPass&&(this.ssrPass.camera=e),this.aoPass&&(this.aoPass.camera=e),this.phasedRenderPass&&(this.phasedRenderPass.camera=e),null==this.csm?(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"}),this.csm&&Array.isArray(this.csm.lights),this.csm.fade=!0,h.lights_fragment_begin=y.lights_fragment_begin):(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 r=new i.WebGLRenderTarget(t.clientWidth*s,t.clientHeight*s);return r.texture.minFilter=i.NearestFilter,r.texture.magFilter=i.NearestFilter,r.texture.generateMipmaps=!1,r.stencilBuffer=!1,r.depthTexture=new i.DepthTexture(128,128),r.depthTexture.type=i.UnsignedShortType,r.depthTexture.minFilter=i.NearestFilter,r.depthTexture.magFilter=i.NearestFilter,r}static createAOMaskDepthRenderTarget(e,t){const s=new i.WebGLRenderTarget(t.clientWidth*e.getPixelRatio(),t.clientHeight*e.getPixelRatio(),{type:i.HalfFloatType});return s.texture.minFilter=i.NearestFilter,s.texture.magFilter=i.NearestFilter,s.texture.generateMipmaps=!1,s.stencilBuffer=!1,s.depthTexture=new i.DepthTexture(128,128),s.depthTexture.type=i.UnsignedInt248Type,s.depthTexture.minFilter=i.NearestFilter,s.depthTexture.magFilter=i.NearestFilter,s}createSceneColorRenderTarget(e,t){const s=new i.WebGLRenderTarget(t.clientWidth*this.renderer.getPixelRatio(),t.clientHeight*this.renderer.getPixelRatio(),{count:2,type:i.FloatType,format:i.RGBAFormat,colorSpace:i.SRGBColorSpace,depthBuffer:!1,stencilBuffer:!1});return s.texture.minFilter=i.LinearFilter,s.texture.magFilter=i.LinearFilter,s.texture.generateMipmaps=!1,s}createGRenderTarget(){const e=this.container;null!=this.gRenderTarget&&this.gRenderTarget.dispose(),this.gRenderTarget=new u(e.clientWidth*this.renderer.getPixelRatio(),e.clientHeight*this.renderer.getPixelRatio(),{count:3,minFilter:i.NearestFilter,magFilter:i.NearestFilter,type:i.HalfFloatType,format:i.RGBAFormat}),this.gRenderTarget.depthTexture=new i.DepthTexture(e.clientWidth,e.clientHeight),this.gRenderTarget.depthTexture.type=i.UnsignedIntType,this.gRenderTarget.depthTexture.minFilter=i.NearestFilter,this.gRenderTarget.depthTexture.magFilter=i.NearestFilter,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(){this.running=!1,window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],this.renderer.dispose(),this.gRenderTarget.dispose(),this.aoMaskDepthRenderTarget.dispose(),this.sceneColorRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren(),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 A&&(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:$e(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 A||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)}updateUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e in s){const t=i[e],r=s[e].value;null!=t&&t.value!==r&&(t.value=r)}}updateLightUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e of st){const t=i[e],r=s[e];null!=r&&null!=t&&(t.value=r.value)}}createGBufferMaterial(e,t){const s=t===De.opaque?this.gbufferMaterialCache:this.tbufferMaterialCache;let r=s.get(e);if(null==r){let n=_.uv;e instanceof Re&&null!=e.heightMap&&(n=Ce(n,L(e.heightMap),C(e.heightScale??1)));let o=G.normal;e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial?null!=e.normalMap&&(o=R(L(e.normalMap).sample(n),e.normalScale.x??1)):e instanceof A&&null!=e.outputNormal&&(o=e.outputNormal),!0!==e.userData.disableAO&&(o=H("DOUBLE_SIDED",o,e=>N(new k("gl_FrontFacing"),e,e.multiplyScalar(-1))));let l=e.userData?.reflective?C(0):C(1);if(e instanceof i.MeshStandardMaterial){const t=U("roughness",e.roughness??1);l=null!=e.roughnessMap?L(e.roughnessMap).sample(n).g.multiply(t):t}else e instanceof A&&null!=e.outputRoughness&&(l=e.outputRoughness);let h=null;(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial)&&null!=e.lightMap&&(h=L(e.lightMap).sample(n).rgb.multiplyScalar(e.lightMapIntensity));let u,c=C(0);if(e instanceof i.MeshStandardMaterial){const t=U("metalness",e.metalness??0);c=null!=e.metalnessMap?L(e.metalnessMap).sample(n).b.multiply(t):t}else e instanceof A&&e.outputRoughness;let p=C(1);e instanceof i.MeshStandardMaterial?null!=e.aoMap&&(u=L(e.aoMap).sample(n).r,p=U("aoMapIntensity",e.aoMapIntensity)):e instanceof A&&e.outputRoughness;const f=U("opacity",e.opacity??1);let g=C(1);e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial?(null!=e.alphaMap&&(g=L(e.alphaMap).sample(n).r),g=g.multiply(f)):e instanceof A&&null!=e.outputOpacity&&(g=e.outputOpacity);let v=W(0,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("color",(new i.Vector3).setFromColor(e.color));null!=e.map?(v=L(e.map).sample(n).multiply(W(t,1)),g=g.multiply(v.w)):v=W(t,1)}const M=!0===e.userData.hasBloom;let T=D(0);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=E("emissive",(new i.Vector3).setFromColor(e.emissive));T=null!=e.emissiveMap?L(e.emissiveMap).sample(n).rgb.multiply(t):t,T=T.multiplyScalar(e.emissiveIntensity)}else e instanceof A&&null!=e.outputEmissive&&(T=e.outputEmissive);const b=e instanceof d&&null!=e.uniforms[te],x=e instanceof d&&null!=e.uniforms[de],P=e instanceof d&&null!=e.uniforms[he],y=e.transparent&&e.alphaTest<=.01||e.blending===i.AdditiveBlending,w=U("alphaTest",e.alphaTest);let j,V=e.alphaTest>0?g.lt(w):y&&t===De.opaque?g.lt(.8):S(!1);!0===e.userData.isDecal&&(V=V.or(Ue)),j=y?q(0,0,0,0):(a=o,I(a).multiplyScalar(.5).addScalar(.5)).rgba(l);const z=e instanceof A?e.outputPosition:void 0,$=e instanceof A?e.outputTransform:void 0;let X,Y=W("black",1);if(e instanceof A&&null!=e.outputColor)Y=e.outputColor;else if(e instanceof i.MeshStandardMaterial)Y=F({color:v,metalness:c,roughness:l,emissive:T.rgb,normal:o,ambientOcclusion:u,ambientOcclusionIntensity:p,bakedLight:h});else if(e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)Y=B({color:v.rgb});else if(e instanceof i.MeshBasicMaterial){let e=v.rgb,t=h??D("white");null!=u&&(t=t.multiplyScalar(u.subtract(1).multiply(p).add(1))),e=e.multiply(t),Y=e.rgba(g)}else e instanceof i.MeshToonMaterial&&(Y=O({color:v,emissive:T.rgb,normal:o,ambientOcclusion:u,ambientOcclusionIntensity:p,bakedLight:h}));(e instanceof A||e instanceof i.MeshStandardMaterial)&&(X=e.envMap);let Q=!0;(e instanceof m||e instanceof i.MeshBasicMaterial||e instanceof i.ShaderMaterial)&&(Q=e.fog);let K=W(Y.rgb,g);Q&&(K=new FogNode(K)),r=new A({transform:$,position:null==$?z:void 0,outputs:[K,T.rgba(t===De.opaque?w:M?1:0),j],opacity:g,outputEncoding:!1,fog:Q,transparent:e.transparent,lights:!0,envMap:X,discard:V}),e instanceof i.MeshStandardMaterial&&null!=e.envMap&&null!=r.uniforms.envMapIntensity&&(r.uniforms.envMapIntensity.value=e.envMapIntensity),(e instanceof A||e instanceof i.MeshStandardMaterial)&&this.applyEnvMap(r),e instanceof A&&Object.assign(r.defines,e.defines),r.userData.mrtOutputs=3,r.forceSinglePass=e.forceSinglePass,r.side=e.side,r.blending=e.blending,y?(r.depthWrite=!e.transparent,r.depthTest=e.depthTest,r.colorWrite=t===De.transparent):(r.depthWrite=e.depthWrite,r.depthTest=e.depthTest),r.visible=e.visible,r.alphaTest=e.alphaTest,r.alphaHash=e.alphaHash,t===De.opaque?(r.visible&&(r.visible=!b&&!x&&!P),r.visible&&(r.visible=!y)):t===De.transparent&&r.visible&&(r.visible=y||b||x||P),Object.assign(r.userData,e.userData),r.visible&&(this.csm.setupMaterial(r),e instanceof d&&Object.assign(r.uniforms,e.uniforms)),s.set(e,r)}var a;return r.visible&&e instanceof d&&this.updateUniformValues(e,r),r}loop(e,t=!1){const s=this.stats,r=s.addPanel(new J.Panel("Calls","#83f","#002")),a=s.addPanel(new J.Panel("Triangles","#c32","#002"));let l;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(l=new ce(this.renderer.getContext()),s.addPanel(l)),this.showStats=t;let h=10,d=1e3;const u=()=>{const e=this.renderer.info.render.calls;e>h&&(h=e,setTimeout(()=>h=10,5e3)),r.update(e,h);const t=this.renderer.info.render.triangles;t>d&&(d=t,setTimeout(()=>d=1e3,5e3)),a.update(t,d)};performance.now();i.Ray.prototype.intersectTriangle;this.resizeRender();const c=[],p=[],m=[];let f=0;const g=new n,v=new n;let M=0;let T=this.paused;const b=t=>{const r=this.renderer.getContext();if(this.paused&&this.running&&r.drawingBufferHeight>1)return setTimeout(()=>b(t),500),void(T=!0);this.renderer.clear(),this.applyPostProcessSettings(),this.renderer.autoClear=!1,this.renderer.clear(),this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),this.camera,s.begin(),this.showStats&&l?.startQuery(),this.ssrPass.gpuPanel=l;let a=(t*=.001)-f;if(f=t,T&&(a=.016,T=!1),g.copy(this.camera.matrixWorld),a>1){let t=a;for(;t>.05;)e(Ve),t-=Ve;e(t)}else e(a);this.onLoopCallbacks.forEach(e=>e(a)),this.camera?.updateMatrixWorld(),v.copy(this.camera.matrixWorld),t-M>.08&&!v.equals(g)&&(this.renderer.shadowMap.needsUpdate=!0,M=t),this.csm.update();let n=!1;c.length=0,p.length=0,m.length=0;const h=Ge;ke.multiplyMatrices(this.camera.projectionMatrix,this.camera.matrixWorldInverse),h.setFromProjectionMatrix(ke);let d=!1,x=!1,P=!1;this.scene.traverseVisible(e=>{if(this.setupCsm(e),this.outlineEffect.apply(e),e instanceof Se&&(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),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[te])&&isObjectInFrustum(e,h)?(this.initDepthUniform(e.material),x=!0):e instanceof X&&(e.visible=!1,p.push(e)),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[he]&&isObjectInFrustum(e,h)&&e.material instanceof A&&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,P=!0),e instanceof o&&e.material?.uniforms&&null!=e.material?.uniforms[le])e.material.uniforms[le].value=t;else if(e instanceof o&&Array.isArray(e.material))for(const s of e.material)s.uniforms&&null!=s.uniforms[le]&&(s.uniforms[le].value=t)}),this.bloomPass.enabled=n,this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.clear(),this.renderScene(De.opaque),this.aoPass.output=Z.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)),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&&d&&this.volumetricFogPass.update(this.camera,this.gRenderTarget,this.csm,this.scene);try{!this.paused&&this.running&&(this.render(a),this.showStats&&l?.endQuery(),this.showStats&&u(),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(b)},1e3/this.fpsCap):requestAnimationFrame(b))};!0===this.options.enableXR?this.renderer.setAnimationLoop(b):requestAnimationFrame(b)}renderScene(e){Qe.clear(),Ke.length=0;fe(this.scene,t=>{if(Je(t))return Ke.push(t),t.visible=!1,!1;if(t instanceof o){Qe.set(t,t.material);let s=!1;if(Array.isArray(t.material)){t.material=t.material.slice();for(let i=0;i<t.material.length;i++)t.material[i]=this.createGBufferMaterial(t.material[i],e),s||(s=t.material[i].visible)}else t.material=this.createGBufferMaterial(t.material,e),s||(s=t.material.visible);s?t.visible=!0:null!=t.children&&0!=t.children.length||(Ke.push(t),t.visible=!1)}});const t=this.scene.matrixWorldAutoUpdate,s=this.scene.matrixAutoUpdate,i=this.renderer.shadowMap.autoUpdate;e!==De.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===De.opaque&&Qe.forEach((e,t)=>{!Array.isArray(e)&&!Array.isArray(t.material)&&e instanceof d&&this.updateLightUniformValues(t.material,e)}),Qe.forEach((e,t)=>{t.material=e}),Ke.forEach((e,t)=>{e.visible=!0,e.updateMatrixWorld(!0)}),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,r=!1,a=!1,n=!1,o=!1;if(null==this.camera)return;const h=this.camera.getWorldPosition(Ne);let d=[];for(const e of this.postProcessVolumes){if(!_e(e.object))continue;let l=e.blendWeight??1;const u=e.distanceToPoint(h);u>e.blendRadius||(e.blendRadius>0&&(l*=ge(1-u/e.blendRadius,0,1)),l>1&&(l=1),l>0&&(d.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),a=!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&&(r=!0,t.depthFocus=void 0!==t.depthFocus?i.MathUtils.lerp(t.depthFocus,e.settings.depthFocus,l):e.settings.depthFocus),void 0!==e.settings.depthAperture&&(r=!0,t.depthAperture=void 0!==t.depthAperture?i.MathUtils.lerp(t.depthAperture,e.settings.depthAperture,l):e.settings.depthAperture),void 0!==e.settings.depthMaxBlur&&(r=!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=a,this.colorPass.colorTint=t.colorTint,this.colorPass.colorTintIntensity=t.colorTintIntensity,this.colorPass.enabled=a||o,r&&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(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,Ge)&&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!=me(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===Be.id)return;this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=Be:(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 d&&(e.uniforms[te].value=this.sceneColorRenderTarget.textures[1],this.camera instanceof l&&(null!=e.uniforms[ie]&&(e.uniforms[ie].value=this.camera.near),null!=e.uniforms[se]&&(e.uniforms[se].value=this.camera.far)))}initNormalUniform(e){e instanceof d&&null!=e.uniforms[ae]&&(e.uniforms[ae].value=this.gRenderTarget.textures[2])}initShadowUniform(e,t){t instanceof A&&t.uniforms.receiveShadow&&(t.uniforms.receiveShadow.value=e.receiveShadow)}initResolutionUniform(e){if(e instanceof d&&null!=e.uniforms[re]){const t=this.previousClientWith,s=this.previousClientHeight;e.uniforms[re].value.set(t*this.renderer.getPixelRatio(),s*this.renderer.getPixelRatio())}}initAoUniform(e){if(this.aoPass.enabled){e.uniforms[he].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 A&&!t.transparent&&t.depthWrite){let s=this._customDepthMaterialCache.get(t);if(null==s){const e=we(ye);let i;null!=t.alphaTest&&t.alphaTest>0&&null!=t.outputOpacity&&(i=t.outputOpacity.lt(t.alphaTest)),s=new A({color:e,discard:i}),this._customDepthMaterialCache.set(t,s)}e.customDepthMaterial=s}}};je=e=t([ee(),s("design:paramtypes",[HTMLElement,Object])],je);export{je as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const Ve=.05;function _e(e){let t=e;for(;t;){if(!1===t.visible)return!1;t=t.parent}return!0}Z.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 Ge=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 Ne=new i.Vector3;const He=new n,ze=new p;function $e(e,t,s=new i.Matrix3){return ze.copy(e),ze.x*=-1,ze.y*=-1,ze.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(ze.y*=-1,ze.z*=-1),s.setFromMatrix4(He.makeRotationFromEuler(ze))}const Xe=new A({outputs:[q(0,0,0,0),q(0,0,0,0),W(D("white"),Fe(4))],transparent:!0}),Ye=new i.MeshBasicMaterial({color:"blue",transparent:!0,opacity:.5});Xe.depthWrite=!1;new o(new i.BoxGeometry(4,4,4),Ye);const Qe=new Map,Ke=[];function Je(e){return e instanceof i.Sprite||e.isPoints||e.isLine||e.isTransformControls||e.isTransformControlsGizmo||e instanceof o&&Ze(e,e.material)}function Ze(e,t){return null==t||(Array.isArray(t)?t.some(t=>Ze(e,t)):t instanceof i.RawShaderMaterial||t instanceof i.ShaderMaterial&&!(t instanceof A))}class et extends Ee{constructor(e,t,s){super(),this.scene=e,this.camera=t,this.gRenderTarget=s,this.needsSwap=!1}render(e,t,s,i,r){const a=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 d=s.depthTexture;s.depthTexture=this.gRenderTarget.depthTexture,e.setRenderTarget(s),Ke.length=0;let u=0;this.scene.traverseVisible(e=>{const t=Je(e);e instanceof o&&!t?(Ke.push(e),e.visible=!1):t&&u++}),u>0&&e.render(this.scene,this.camera),Ke.forEach((e,t)=>{e.visible=!0}),e.setRenderTarget(null),e.autoClear=a,s.depthTexture=d,this.scene.matrixWorldAutoUpdate=n,this.scene.matrixAutoUpdate=l,e.shadowMap.autoUpdate=h}}class tt extends Ee{constructor(e){super(),this.fn=e}render(e,t,s,i,r){this.fn(e,t,s,i,r)}}const st=["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"],it=E("fogColor");export class FogNode extends ${constructor(e,t=it){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),r=e.get(this.fogColor),a=e.get(U("fogFar")),n=e.get(U("fogNear")),o=e.get(U("fogDensity")),l=e.get(V(j.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}, ${a}, ${l} );\n #endif\n vec4 color_vec4_${t} = vec4(mix(${s}, ${r}, fogFactor_${t}), ${i});\n `,out:`color_vec4_${t}`}}}/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -4,10 +4,10 @@ import { Euler, Material, Object3D, Scene, Vector3 } from "three";
4
4
  import { ContainerInstance } from 'typedi';
5
5
  import { GameComponent } from '../game-component/game-component.js';
6
6
  import { BaseActor } from '../gameplay/actors/actor.js';
7
- import { PhysicsBodyType } from '../gameplay/index.js';
7
+ import { ActorComponent, PhysicsBodyType } from '../gameplay/index.js';
8
8
  import { RenderingView } from '../rendering.js';
9
9
  import { ParameterType, PropertyParameter } from '../shader/parameter.js';
10
- import { ActorImpl, ActorType, ShaderImpl, ShaderType } from '../shader/shader.js';
10
+ import { ActorImpl, ActorType, ClassImpl, ShaderImpl, ShaderType } from '../shader/shader.js';
11
11
  import { Type } from '../utils/type.js';
12
12
  import { AssetResourceLoader } from './asset-resource-loader.js';
13
13
  import { AssetsProvider } from './assets-provider.js';
@@ -164,6 +164,14 @@ export type SceneObjectPhysicsSettings = {
164
164
  export type SkySettings = {
165
165
  materialId?: string;
166
166
  };
167
+ export interface AttachedActorComponent {
168
+ type: string;
169
+ params?: Record<string, CustomParamValue>;
170
+ innerParams?: {
171
+ path: string[];
172
+ params: Record<string, CustomParamValue>;
173
+ }[];
174
+ }
167
175
  export interface ActorSettings {
168
176
  type: string;
169
177
  params?: Record<string, CustomParamValue>;
@@ -171,6 +179,7 @@ export interface ActorSettings {
171
179
  path: string[];
172
180
  params: Record<string, CustomParamValue>;
173
181
  }[];
182
+ attachedComponents?: AttachedActorComponent[];
174
183
  }
175
184
  export interface GrassSettings {
176
185
  layers: GrassLayer[];
@@ -260,6 +269,7 @@ export declare class SceneMaterializer {
260
269
  private shaders;
261
270
  private actorTypes;
262
271
  private actorProvider;
272
+ private componentTypes;
263
273
  private objectMap;
264
274
  private sceneObjectMap;
265
275
  private updateSubscription;
@@ -281,7 +291,7 @@ export declare class SceneMaterializer {
281
291
  private originalFog;
282
292
  private assets;
283
293
  detailTier: DetailTier;
284
- constructor(scene: Scene, dataProvider: SceneDataProvider, assetsService: AssetsProvider, assetManagerService: AssetResourceLoader, renderingView: RenderingView, shaders: ShaderImpl[], actorTypes: ActorImpl[], actorProvider: ActorProvider);
294
+ constructor(scene: Scene, dataProvider: SceneDataProvider, assetsService: AssetsProvider, assetManagerService: AssetResourceLoader, renderingView: RenderingView, shaders: ShaderImpl[], actorTypes: ActorImpl[], actorProvider: ActorProvider, componentTypes?: ClassImpl<ActorComponent>[]);
285
295
  private refreshMaterial;
286
296
  private getTopLevelActors;
287
297
  get actorInstances(): BaseActor[];
@@ -309,6 +319,10 @@ export declare class SceneMaterializer {
309
319
  * Initiating top level actors by default as actors nested in prefabs are already initiated
310
320
  */
311
321
  private initActorsPostInit;
322
+ /**
323
+ * Attach components that were added via the editor UI (not via code)
324
+ */
325
+ private attachEditorComponents;
312
326
  private addVfxChildActors;
313
327
  private applyActorComponentParams;
314
328
  private canObjectBeInstanced;
@@ -339,6 +353,7 @@ export declare class SceneMaterializer {
339
353
  private applyMaterial;
340
354
  private unapplyMaterials;
341
355
  updateActors(actors: ActorImpl[]): void;
356
+ updateComponents(components: ClassImpl<ActorComponent>[]): void;
342
357
  updateShaders(shaders: ShaderImpl[]): void;
343
358
  private worldEnvObj;
344
359
  private update;