@hology/core 0.0.182 → 0.0.184
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/project-config.js +1 -1
- package/dist/controllers/base-game-controller.js +1 -1
- package/dist/csm.js +1 -1
- package/dist/effects/particles/examples.js +1 -1
- package/dist/effects/particles/particle-system-config.js +1 -1
- package/dist/effects/vfx/behaviours.js +1 -1
- package/dist/effects/vfx/index.js +1 -1
- package/dist/effects/vfx/initializsers.js +1 -1
- package/dist/effects/vfx/rates.js +1 -1
- package/dist/effects/vfx/stretched-sprite.js +1 -1
- package/dist/effects/vfx/trail-renderer.js +1 -1
- package/dist/effects/vfx/vfx-actor.js +1 -1
- package/dist/effects/vfx/vfx-asset.js +1 -1
- package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
- package/dist/effects/vfx/vfx-defs.js +1 -1
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/effects/vfx/vfx-old-materializer.js +1 -1
- package/dist/effects/vfx/vfx-param.js +1 -1
- package/dist/effects/vfx/vfx-renderers.js +1 -1
- package/dist/effects/vfx/vfx-service.js +1 -1
- package/dist/effects/vfx/zones.js +1 -1
- package/dist/game-component/component-decorators.js +1 -1
- package/dist/game-component/game-component.js +1 -1
- package/dist/gameplay/actors/actor.js +1 -1
- package/dist/gameplay/actors/builtin/camera-actor.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/modes.js +1 -1
- package/dist/gameplay/actors/builtin/components/editor-sprite-component.js +1 -1
- package/dist/gameplay/actors/builtin/components/index.js +1 -1
- package/dist/gameplay/actors/builtin/components/mesh-component.js +1 -1
- package/dist/gameplay/actors/builtin/components/scene-component.js +1 -1
- package/dist/gameplay/actors/builtin/components/tween-component.js +1 -1
- package/dist/gameplay/actors/builtin/components/volume-editor-component.js +1 -1
- package/dist/gameplay/actors/builtin/index.js +1 -1
- package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
- package/dist/gameplay/actors/builtin/positional-audio-actor.js +1 -1
- package/dist/gameplay/actors/builtin/post-process-volume-actor.js +1 -1
- package/dist/gameplay/actors/builtin/spawn-point.js +1 -1
- package/dist/gameplay/actors/builtin/trigger-volume.js +1 -1
- package/dist/gameplay/actors/camera/camera-component.js +1 -1
- package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
- package/dist/gameplay/actors/component.js +1 -1
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/index.js +1 -1
- package/dist/gameplay/actors/internal/component-init.js +1 -1
- package/dist/gameplay/actors/internal/container-map.js +1 -1
- package/dist/gameplay/ai/behavior-tree/bt.js +1 -1
- package/dist/gameplay/ai/behavior-tree/move.js +1 -1
- package/dist/gameplay/ai/build-tile.js +1 -1
- package/dist/gameplay/ai/dynamic-tiled-navmesh.js +1 -1
- package/dist/gameplay/ai/dynamic-tiled-navmesh.worker.js +1 -1
- package/dist/gameplay/ai/index.js +1 -1
- package/dist/gameplay/ai/navigation.js +1 -1
- package/dist/gameplay/animation/anim-sm.js +1 -1
- package/dist/gameplay/animation/root-motion.js +1 -1
- package/dist/gameplay/env.js +1 -1
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.js +2 -2
- package/dist/gameplay/inject.d.ts +3 -1
- package/dist/gameplay/inject.js +1 -1
- package/dist/gameplay/input/index.js +1 -1
- package/dist/gameplay/input/input-service.js +1 -1
- package/dist/gameplay/input/input.js +1 -1
- package/dist/gameplay/input/keybind.js +1 -1
- package/dist/gameplay/polyfill.js +1 -1
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/abstract-physics-system.js +1 -1
- package/dist/gameplay/services/physics/collision-contact.js +1 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/pointer-events.js +1 -1
- package/dist/gameplay/services/render.js +1 -1
- package/dist/gameplay/services/shader-provider.js +1 -1
- package/dist/gameplay/services/world.js +1 -1
- package/dist/index.js +1 -1
- package/dist/rendering/bloom/LuminosityHighPassShader.js +1 -1
- package/dist/rendering/bloom/UnrealBloomPass.js +1 -1
- package/dist/rendering/bloom/types.js +1 -1
- package/dist/rendering/color-pass.js +1 -1
- package/dist/rendering/fog/fog-volume-actor.js +1 -1
- package/dist/rendering/fog/fog-volume-object.js +1 -1
- package/dist/rendering/fog/volumetric-fog-pass.js +1 -1
- package/dist/rendering/outline-effect.js +1 -1
- package/dist/rendering/shader-override.js +1 -1
- package/dist/rendering/ssr/SSRPass.js +1 -1
- package/dist/rendering/ssr/SSRShader.js +1 -1
- package/dist/rendering/tone-mapping.js +1 -1
- package/dist/rendering.d.ts +7 -1
- package/dist/rendering.js +2 -2
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/assets-provider.js +1 -1
- package/dist/scene/batched-mesh-2.js +2 -2
- package/dist/scene/bootstrap.js +1 -1
- package/dist/scene/collision/collision-shape-import.js +1 -1
- package/dist/scene/collision/collision-shape.js +1 -1
- package/dist/scene/landscape/landscape-manager.js +1 -1
- package/dist/scene/landscape/landscape.js +1 -1
- package/dist/scene/landscape/utils.js +1 -1
- package/dist/scene/materializer.d.ts +5 -0
- package/dist/scene/materializer.js +2 -2
- package/dist/scene/materials/grass-foliage.js +1 -1
- package/dist/scene/materials/grass.js +1 -1
- package/dist/scene/materials/utils/material-painting.js +1 -1
- package/dist/scene/materials/utils/noise.glsl.js +1 -1
- package/dist/scene/materials/water.js +1 -1
- package/dist/scene/model.js +1 -1
- package/dist/scene/objects/prefab.js +1 -1
- package/dist/scene/objects/ramp-geometry.js +1 -1
- package/dist/scene/objects/shapes.js +1 -1
- package/dist/scene/objects/stairs-geometry.js +1 -1
- package/dist/scene/runtime-asset-service.js +1 -1
- package/dist/scene/runtime-backend-service.js +1 -1
- package/dist/scene/runtime-bundled-backend-service.js +1 -1
- package/dist/scene/scene-data-service.js +1 -1
- package/dist/scene/sky.js +1 -1
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/decal-standard-shader.js +1 -1
- package/dist/shader/builtin/decal-unlit-shader.js +1 -1
- package/dist/shader/builtin/index.js +1 -1
- package/dist/shader/builtin/lambert-shader.js +1 -1
- package/dist/shader/builtin/landscape-composite-shader.js +1 -1
- package/dist/shader/builtin/landscape-shader.js +1 -1
- package/dist/shader/builtin/layered-shader.js +1 -1
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/builtin/toon-shader.js +1 -1
- package/dist/shader/builtin/unlit-shader.js +1 -1
- package/dist/shader/color-layer.js +1 -1
- package/dist/shader/decal-shader.js +1 -1
- package/dist/shader/index.js +1 -1
- package/dist/shader/parameter.js +1 -1
- package/dist/shader/shader.js +1 -1
- package/dist/shader/sprite-shader.js +1 -1
- package/dist/shader/trail-shader.js +1 -1
- package/dist/shader-nodes/bulge.js +1 -1
- package/dist/shader-nodes/curve-sample.js +1 -1
- package/dist/shader-nodes/decal.js +1 -1
- package/dist/shader-nodes/depth.js +1 -1
- package/dist/shader-nodes/effects.js +1 -1
- package/dist/shader-nodes/glsl-node.js +1 -1
- package/dist/shader-nodes/index.js +1 -1
- package/dist/shader-nodes/landscape.js +1 -1
- package/dist/shader-nodes/layers.js +1 -1
- package/dist/shader-nodes/math.js +1 -1
- package/dist/shader-nodes/particle.js +1 -1
- package/dist/shader-nodes/pom.js +1 -1
- package/dist/shader-nodes/scene-sample.js +1 -1
- package/dist/shader-nodes/shapes.js +1 -1
- package/dist/shader-nodes/texture-sequence.js +1 -1
- package/dist/shader-nodes/time.js +1 -1
- package/dist/shader-nodes/voronoi.js +1 -1
- package/dist/test/injection.test.js +1 -1
- package/dist/utils/async.js +1 -1
- package/dist/utils/buffer.js +1 -1
- package/dist/utils/collections.js +1 -1
- package/dist/utils/curve.js +1 -1
- package/dist/utils/files.js +1 -1
- package/dist/utils/materials.js +1 -1
- package/dist/utils/math.js +1 -1
- package/dist/utils/mesh.js +1 -1
- package/dist/utils/polyfill.js +1 -1
- package/dist/utils/three/cleanup.js +1 -1
- package/dist/utils/three/depth-pass.js +1 -1
- package/dist/utils/three/gpu-stats-panel.js +1 -1
- package/dist/utils/three/line-sphere.js +1 -1
- package/dist/utils/three/outline-pass.js +1 -1
- package/dist/utils/three/positional-audio-helper.js +1 -1
- package/dist/utils/three/stats.js +1 -1
- package/dist/utils/three/transform-controls.js +1 -1
- package/dist/utils/three/traverse.js +1 -1
- package/dist/utils/three/unscaled-sprite.js +1 -1
- package/dist/utils/type.js +1 -1
- package/dist/utils/uuid.js +1 -1
- package/dist/utils/voxel-bitset.js +1 -1
- package/dist/worker/index.js +1 -1
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
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
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{BackSide as e,Color as t,ShaderMaterial as i,UniformsLib as n,UniformsUtils as a,Object3D as l,Mesh as r,InstancedMesh as o,BatchedMesh as s,Vector3 as c}from"three";import{glslFunction as p,NodeShaderMaterial as u,Vec4Node as d,uniforms as m,transformed as v,neg as f,uniformFloat as h,uniformVec3 as _,vec3 as g,rgba as x,vec4 as k,negVec3 as A,ifDefApply as w,BooleanExpression as y,select as b,attributes as D}from"three-shader-graph";export class OutlineEffect{constructor(i,n={}){this.applied=new WeakSet,this.enabled=!0;const a=void 0!==n.defaultThickness?n.defaultThickness:.003,l=((new t).fromArray(void 0!==n.defaultColor?n.defaultColor:[0,0,0]),void 0!==n.defaultAlpha?n.defaultAlpha:1),r=void 0!==n.defaultKeepAlive&&n.defaultKeepAlive,o={},s={};["#include <common>","#include <uv_pars_vertex>","#include <displacementmap_pars_vertex>","#include <fog_pars_vertex>","#include <morphtarget_pars_vertex>","#include <skinning_pars_vertex>","#include <logdepthbuf_pars_vertex>","#include <clipping_planes_pars_vertex>","uniform float outlineThickness;","vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {","\tfloat thickness = outlineThickness;","\tconst float ratio = 1.0;","\tvec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );"," float viewDistance = length((modelViewMatrix * vec4(skinned.xyz, 1.0)).xyz);"," float scale = pow(viewDistance, 0.5); // sqrt, or any exponent","\tvec4 norm = normalize( pos - pos2 );","\treturn pos + norm * thickness * scale * ratio;","}","void main() {","\t#include <uv_vertex>","\t#include <beginnormal_vertex>","\t#include <morphnormal_vertex>","\t#include <skinbase_vertex>","\t#include <skinnormal_vertex>","\t#include <begin_vertex>","\t#include <morphtarget_vertex>","\t#include <skinning_vertex>","\t#include <displacementmap_vertex>","\t#include <project_vertex>","\tvec3 outlineNormal = - objectNormal;","\tgl_Position = calculateOutline( gl_Position, outlineNormal, vec4( transformed, 1.0 ) );","\t#include <logdepthbuf_vertex>","\t#include <clipping_planes_vertex>","\t#include <fog_vertex>","}"].join("\n"),["#include <common>","#include <fog_pars_fragment>","#include <logdepthbuf_pars_fragment>","#include <clipping_planes_pars_fragment>","uniform vec3 outlineColor;","uniform float outlineAlpha;","void main() {","\t#include <clipping_planes_fragment>","\t#include <logdepthbuf_fragment>","\tgl_FragColor = vec4( outlineColor, outlineAlpha );","\t#include <tonemapping_fragment>","\t#include <colorspace_fragment>","\t#include <fog_fragment>","\t#include <premultiplied_alpha_fragment>","}"].join("\n");function f(t){Array.isArray(t)&&(t=t[0]);const i=m.projectionMatrix.multiply(m.modelViewMatrix).multiplyVec(v.position);let n=v.normal;n=w("DOUBLE_SIDED",n,e=>b(new y("gl_FrontFacing"),e,e.multiplyScalar(-1)));const r=h("outlineThickness",a),o=_("outlineColor",new c(0,0,0)),s=h("outlineAlpha",l),f=p(d,{pos:i,normal:n,skinned:v.position,outlineThickness:r},"\n\t\t\t\tfloat thickness = outlineThickness;\n\t\t\t\tvec4 viewPos = modelViewMatrix * vec4(skinned.xyz, 1.0);\n\t\t\t\tfloat viewDistance = length(viewPos.xyz);\n\t\t\t\t// Clamp to safe domain\n\t\t\t\tviewDistance = max(viewDistance, 0.0001);\n\t\t\t\tfloat scale = sqrt(viewDistance) * 0.5;\n\t\t\t\tvec3 displaced = viewPos.xyz + normal * thickness * scale;\n\t\t\t\treturn projectionMatrix * vec4(displaced, 1.0);\n\t\t\t"),g=x(o,s),A=[g,k(0),k(0)],D="number"==typeof t.userData.mrtOutputs&&t.userData.mrtOutputs>1,M=new u({position:f,outputs:D?A:void 0,color:D?void 0:g});return M.side=e,M.depthTest=!0,M.depthWrite=!0,M.transparent=!0,M}this.createMaterial=f,this.getOutlineMaterial=function(e){const t=function(e){let t=o[e.uuid];return void 0===t&&(t={material:f(e),used:!0,keepAlive:r,count:0},o[e.uuid]=t),t.used=!0,t.material}(e);return s[t.uuid]=e,function(e,t){Array.isArray(t)&&(t=t[0]);if("invisible"===e.name)return;const i=t.userData.outlineParameters;e.fog=t.fog,e.toneMapped=t.toneMapped,e.premultipliedAlpha=t.premultipliedAlpha,e.displacementMap=t.displacementMap,void 0!==i?(!1===t.visible?e.visible=!1:e.visible=void 0===i.visible||i.visible,e.transparent=void 0!==i.alpha&&i.alpha<1||t.transparent,void 0!==i.keepAlive&&(o[t.uuid].keepAlive=i.keepAlive)):(e.transparent=t.transparent,e.visible=t.visible);!0!==t.wireframe&&!1!==t.depthTest||(e.visible=!1);t.clippingPlanes&&(e.clipping=!0,e.clippingPlanes=t.clippingPlanes,e.clipIntersection=t.clipIntersection,e.clipShadows=t.clipShadows);e.version=t.version}(t,e),t},this.updateUniforms=function(e,t){const i=t.userData.outlineParameters;e.uniforms.outlineAlpha.value=t.opacity,void 0!==i&&(void 0!==i.thickness&&(e.uniforms.outlineThickness.value=i.thickness),void 0!==i.color&&e.uniforms.outlineColor.value.fromArray(i.color),void 0!==i.alpha&&(e.uniforms.outlineAlpha.value=i.alpha)),t.displacementMap&&(e.uniforms.displacementMap.value=t.displacementMap,e.uniforms.displacementScale.value=t.displacementScale,e.uniforms.displacementBias.value=t.displacementBias)}}apply(e){if(!(e instanceof r)||e instanceof s||e instanceof o)return;if(this.applied.has(e))return;this.applied.add(e);const t=e.onAfterRender;e.onAfterRender=(i,n,a,l,r,o)=>{t(i,n,a,l,r);let s=!1;if(Array.isArray(r)?s=r.some(e=>e&&e.userData&&e.userData.outlineParameters):r&&r.userData&&r.userData.outlineParameters&&(s=!0),!s)return;const c=e.material,p=this.getOutlineMaterial(c);e.material=p,this.updateUniforms(p,r),i.renderBufferDirect(a,n,l,p,e,o),e.material=c}}}/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export const lambertVertexShaderOverride="\nvec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\n#endif\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n float linearDepth = (-mvPosition.z) / (shadowFar - cameraNear);\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n #if ( UNROLLED_LOOP_INDEX < CSM_CASCADES )\n if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) {\n #endif \n getDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n #endif\n #if ( UNROLLED_LOOP_INDEX < CSM_CASCADES )\n }\n #endif \n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n";export const shadowMaskOverride="\nvarying vec3 vViewPosition;\nfloat getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n // TODO this does not work as this varying does not exist in this shader\n float linearDepth = (-vViewPosition.z) / (shadowFar - cameraNear);\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n #if ( UNROLLED_LOOP_INDEX < CSM_CASCADES )\n if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y) {\n #endif \n directionalLight = directionalLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n #if ( UNROLLED_LOOP_INDEX < CSM_CASCADES )\n }\n #endif \n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}\n";/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{AddEquation as e,Color as t,DepthTexture as s,HalfFloatType as r,Mesh as i,MeshBasicMaterial as a,MeshLambertMaterial as l,MeshNormalMaterial as n,MeshStandardMaterial as h,NearestFilter as o,NoBlending as u,NormalBlending as d,OneMinusSrcAlphaFactor as c,ShaderMaterial as m,SrcAlphaFactor as f,Texture as p,UniformsUtils as g,UnsignedShortType as M,WebGLRenderTarget as T}from"three";import{NodeShaderMaterial as b,float as R,rgb as v,vec3 as y}from"three-shader-graph";import{CopyShader as C,FullScreenQuad as S,Pass as x}from"three/examples/jsm/Addons.js";import{oneMinus as _}from"../../shader-nodes/math.js";import{traverseVisibleStop as w}from"../../utils/three/traverse.js";import{elapsedTimeUniformName as D}from"../../shader-nodes/time.js";import{SSRBlurShader as P,SSRDepthShader as A,SSRShader as k}from"./SSRShader.js";const U=new WeakMap,O=new WeakMap;class E extends x{constructor({renderer:i,scene:l,camera:h,width:d=512,height:p=512,selects:b=null,bouncing:R=!1,groundReflector:v=null,normalTexture:y=null,depthTexture:x=null}){super(),this.elapsedTime=0,this.width=d,this.height=p,this.clear=!0,this.renderer=i,this.scene=l,this.camera=h,this.groundReflector=v,this.opacity=k.uniforms.opacity.value,this.output=0,this.maxDistance=k.uniforms.maxDistance.value,this.thickness=k.uniforms.thickness.value,this.tempColor=new t,this._selects=b,this.selective=Array.isArray(this._selects),this.renderNormals=null==y,this.resolutionDownscale=4,Object.defineProperty(this,"selects",{get(){return this._selects},set(e){this._selects!==e&&(this._selects=e,Array.isArray(e)?(this.selective=!0,this.ssrMaterial.defines.SELECTIVE=!0,this.ssrMaterial.needsUpdate=!0):(this.selective=!1,this.ssrMaterial.defines.SELECTIVE=!1,this.ssrMaterial.needsUpdate=!0))}}),this._bouncing=R,Object.defineProperty(this,"bouncing",{get(){return this._bouncing},set(e){this._bouncing!==e&&(this._bouncing=e,this.ssrMaterial.uniforms.tDiffuse.value=e?this.prevRenderTarget.texture:this.beautyRenderTarget.texture)}}),this.blur=!0,this._distanceAttenuation=k.defines.DISTANCE_ATTENUATION,Object.defineProperty(this,"distanceAttenuation",{get(){return this._distanceAttenuation},set(e){this._distanceAttenuation!==e&&(this._distanceAttenuation=e,this.ssrMaterial.defines.DISTANCE_ATTENUATION=e,this.ssrMaterial.needsUpdate=!0)}}),this._fresnel=k.defines.FRESNEL,Object.defineProperty(this,"fresnel",{get(){return this._fresnel},set(e){this._fresnel!==e&&(this._fresnel=e,this.ssrMaterial.defines.FRESNEL=e,this.ssrMaterial.needsUpdate=!0)}}),this._infiniteThick=k.defines.INFINITE_THICK,Object.defineProperty(this,"infiniteThick",{get(){return this._infiniteThick},set(e){this._infiniteThick!==e&&(this._infiniteThick=e,this.ssrMaterial.defines.INFINITE_THICK=e,this.ssrMaterial.needsUpdate=!0)}});const _=null==x;null==x&&((x=new s).type=M,x.minFilter=o,x.magFilter=o),this.beautyRenderTarget=new T(this.width,this.height,{minFilter:o,magFilter:o,type:r,depthTexture:_?x:void 0,depthBuffer:!0}),this.prevRenderTarget=new T(this.width,this.height,{minFilter:o,magFilter:o}),this.renderNormals&&(this.normalRenderTarget=new T(this.width,this.height,{minFilter:o,magFilter:o,type:r}),this.metalnessRenderTarget=new T(this.width,this.height,{minFilter:o,magFilter:o,type:r})),this.ssrRenderTarget=new T(this.width/this.resolutionDownscale,this.height/this.resolutionDownscale,{minFilter:o,magFilter:o}),this.blurRenderTarget=this.ssrRenderTarget.clone(),this.blurRenderTarget2=this.ssrRenderTarget.clone(),this.ssrMaterial=new m({defines:Object.assign({},k.defines,{MAX_STEP:Math.sqrt(this.width*this.width+this.height*this.height)}),uniforms:g.clone(k.uniforms),vertexShader:k.vertexShader,fragmentShader:k.fragmentShader,blending:u}),this.ssrMaterial.uniforms.tNormal.value=this.renderNormals?this.normalRenderTarget.texture:y,this.ssrMaterial.defines.SELECTIVE=this.selective,this.ssrMaterial.needsUpdate=!0,this.renderNormals&&(this.ssrMaterial.uniforms.tMetalness.value=this.metalnessRenderTarget.texture),this.ssrMaterial.uniforms.tDepth.value=null!=x?x:this.beautyRenderTarget.depthTexture,this.ssrMaterial.uniforms.cameraNear.value=this.camera.near,this.ssrMaterial.uniforms.cameraFar.value=this.camera.far,this.ssrMaterial.uniforms.thickness.value=this.thickness,this.ssrMaterial.uniforms.resolution.value.set(this.width/this.resolutionDownscale,this.height/this.resolutionDownscale),this.ssrMaterial.uniforms.cameraProjectionMatrix.value.copy(this.camera.projectionMatrix),this.ssrMaterial.uniforms.cameraInverseProjectionMatrix.value.copy(this.camera.projectionMatrixInverse),this.normalMaterial=new n,this.normalMaterial.blending=u,this.metalnessOnMaterial=new a({color:"white"}),this.metalnessOffMaterial=new a({color:"black"}),this.blurMaterial=new m({defines:Object.assign({},P.defines),uniforms:g.clone(P.uniforms),vertexShader:P.vertexShader,fragmentShader:P.fragmentShader}),this.blurMaterial.uniforms.tDiffuse.value=this.ssrRenderTarget.texture,this.blurMaterial.uniforms.resolution.value.set(this.width,this.height),this.blurMaterial2=new m({defines:Object.assign({},P.defines),uniforms:g.clone(P.uniforms),vertexShader:P.vertexShader,fragmentShader:P.fragmentShader}),this.blurMaterial2.uniforms.tDiffuse.value=this.blurRenderTarget.texture,this.blurMaterial2.uniforms.resolution.value.set(this.width,this.height),_&&(this.depthRenderMaterial=new m({defines:Object.assign({},A.defines),uniforms:g.clone(A.uniforms),vertexShader:A.vertexShader,fragmentShader:A.fragmentShader,blending:u}),this.depthRenderMaterial.uniforms.tDepth.value=this.beautyRenderTarget.depthTexture,this.depthRenderMaterial.uniforms.cameraNear.value=this.camera.near,this.depthRenderMaterial.uniforms.cameraFar.value=this.camera.far),this.copyMaterial=new m({uniforms:g.clone(C.uniforms),vertexShader:C.vertexShader,fragmentShader:C.fragmentShader,transparent:!0,depthTest:!1,depthWrite:!1,blendSrc:f,blendDst:c,blendEquation:e,blendSrcAlpha:f,blendDstAlpha:c,blendEquationAlpha:e}),this.fsQuad=new S(null),this.originalClearColor=new t,this.needsSwap=!1}setGBuffer(e,t){this.beautyRenderTarget.depthTexture=e,this.ssrMaterial.uniforms.tDepth.value=e,this.ssrMaterial.uniforms.tNormal.value=t,this.ssrMaterial.uniformsNeedUpdate=!0}dispose(){this.beautyRenderTarget&&this.beautyRenderTarget.dispose(),this.prevRenderTarget.dispose(),this.normalRenderTarget&&this.normalRenderTarget.dispose(),this.metalnessRenderTarget&&this.metalnessRenderTarget.dispose(),this.ssrRenderTarget.dispose(),this.blurRenderTarget.dispose(),this.blurRenderTarget2.dispose(),this.normalMaterial.dispose(),this.metalnessOnMaterial.dispose(),this.metalnessOffMaterial.dispose(),this.blurMaterial.dispose(),this.blurMaterial2.dispose(),this.copyMaterial.dispose(),this.depthRenderMaterial&&this.depthRenderMaterial.dispose(),this.fsQuad.dispose()}render(e,t,s){const r=this.scene.matrixWorldAutoUpdate;switch(this.scene.matrixWorldAutoUpdate=!1,this.ssrMaterial.uniforms.tDiffuse.value=s.texture,this.groundReflector&&(this.groundReflector.visible=!1,this.groundReflector.visible=!0),this.groundReflector&&(this.groundReflector.visible=!1),this.renderNormals&&this._renderOverride(e,this.normalMaterial,this.normalRenderTarget,0,0),this.selective&&this.renderNormals&&this._renderMetalness(e,this.metalnessOnMaterial,this.metalnessRenderTarget,0,0),this.ssrMaterial.uniforms.opacity.value=this.opacity,this.ssrMaterial.uniforms.maxDistance.value=this.maxDistance,this.ssrMaterial.uniforms.thickness.value=this.thickness,this._renderPass(e,this.ssrMaterial,this.ssrRenderTarget),this.blur&&(this._renderPass(e,this.blurMaterial,this.blurRenderTarget),this._renderPass(e,this.blurMaterial2,this.blurRenderTarget2)),this.output){case E.OUTPUT.Default:this.bouncing?(this.copyMaterial.uniforms.tDiffuse.value=s.texture,this.copyMaterial.blending=u,this._renderPass(e,this.copyMaterial,this.prevRenderTarget),this.blur?this.copyMaterial.uniforms.tDiffuse.value=this.blurRenderTarget2.texture:this.copyMaterial.uniforms.tDiffuse.value=this.ssrRenderTarget.texture,this.copyMaterial.blending=d,this._renderPass(e,this.copyMaterial,this.prevRenderTarget),this.copyMaterial.uniforms.tDiffuse.value=this.prevRenderTarget.texture,this.copyMaterial.blending=u,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:t)):(this.blur?this.copyMaterial.uniforms.tDiffuse.value=this.blurRenderTarget2.texture:this.copyMaterial.uniforms.tDiffuse.value=this.ssrRenderTarget.texture,this.copyMaterial.blending=d,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:s));break;case E.OUTPUT.SSR:this.blur?this.copyMaterial.uniforms.tDiffuse.value=this.blurRenderTarget2.texture:this.copyMaterial.uniforms.tDiffuse.value=this.ssrRenderTarget.texture,this.copyMaterial.blending=u,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:t),this.bouncing&&(this.blur?this.copyMaterial.uniforms.tDiffuse.value=this.blurRenderTarget2.texture:this.copyMaterial.uniforms.tDiffuse.value=this.beautyRenderTarget.texture,this.copyMaterial.blending=u,this._renderPass(e,this.copyMaterial,this.prevRenderTarget),this.copyMaterial.uniforms.tDiffuse.value=this.ssrRenderTarget.texture,this.copyMaterial.blending=d,this._renderPass(e,this.copyMaterial,this.prevRenderTarget));break;case E.OUTPUT.Beauty:this.copyMaterial.uniforms.tDiffuse.value=this.beautyRenderTarget.texture,this.copyMaterial.blending=u,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:t);break;case E.OUTPUT.Depth:this._renderPass(e,this.depthRenderMaterial,this.renderToScreen?null:t);break;case E.OUTPUT.Normal:this.copyMaterial.uniforms.tDiffuse.value=this.normalRenderTarget.texture,this.copyMaterial.blending=u,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:t);break;case E.OUTPUT.Metalness:this.copyMaterial.uniforms.tDiffuse.value=this.metalnessRenderTarget.texture,this.copyMaterial.blending=u,this._renderPass(e,this.copyMaterial,this.renderToScreen?null:t);break;default:console.warn("THREE.SSRPass: Unknown output type.")}this.scene.matrixWorldAutoUpdate=r}setSize(e,t){this.width=e,this.height=t,this.ssrMaterial.defines.MAX_STEP=Math.sqrt(e*e+t*t),this.ssrMaterial.needsUpdate=!0,this.beautyRenderTarget.setSize(e,t),this.prevRenderTarget.setSize(e,t),this.ssrRenderTarget.setSize(e/this.resolutionDownscale,t/this.resolutionDownscale),null!=this.normalRenderTarget&&this.normalRenderTarget.setSize(e,t),null!=this.metalnessRenderTarget&&this.metalnessRenderTarget.setSize(e,t),this.blurRenderTarget.setSize(e,t),this.blurRenderTarget2.setSize(e,t),this.ssrMaterial.uniforms.resolution.value.set(e/this.resolutionDownscale,t/this.resolutionDownscale),this.ssrMaterial.uniforms.cameraProjectionMatrix.value.copy(this.camera.projectionMatrix),this.ssrMaterial.uniforms.cameraInverseProjectionMatrix.value.copy(this.camera.projectionMatrixInverse),this.blurMaterial.uniforms.resolution.value.set(e,t),this.blurMaterial2.uniforms.resolution.value.set(e,t)}_renderPass(e,t,s,r,i){this.originalClearColor.copy(e.getClearColor(this.tempColor));const a=e.getClearAlpha(this.tempColor),l=e.autoClear;e.setRenderTarget(s),e.autoClear=!1,null!=r&&(e.setClearColor(r),e.setClearAlpha(i||0),e.clear()),this.fsQuad.material=t,this.fsQuad.render(e),e.autoClear=l,e.setClearColor(this.originalClearColor),e.setClearAlpha(a)}_renderOverride(e,t,s,r,a){this.originalClearColor.copy(e.getClearColor(this.tempColor));const l=e.getClearAlpha(this.tempColor),o=e.autoClear;e.setRenderTarget(s),e.autoClear=!1,r=t.clearColor||r,a=t.clearAlpha||a,null!=r&&(e.setClearColor(r),e.setClearAlpha(a||0),e.clear()),w(this.scene,e=>{if(e.isTransformControlsGizmo)return!1;if(e instanceof i)if(e._SSRPassBackupMaterial=e.material,e.material instanceof h&&this._selects.includes(e)){let t=U.get(e.material);t||(t=new n({normalMap:e.material.normalMap,normalScale:e.material.normalScale}),U.set(e.material,t)),e.material=t}else e.material=t}),e.render(this.scene,this.camera),this.scene.traverseVisible(e=>{e._SSRPassBackupMaterial&&(e.material=e._SSRPassBackupMaterial)}),e.autoClear=o,e.setClearColor(this.originalClearColor),e.setClearAlpha(l)}_renderMetalness(e,t,s,r,i){this.originalClearColor.copy(e.getClearColor(this.tempColor));const n=e.getClearAlpha(this.tempColor),o=e.autoClear,u=this.scene.background,d=this.scene.fog;e.setRenderTarget(s),e.autoClear=!1,this.scene.background=null,this.scene.fog=null,r=t.clearColor||r,i=t.clearAlpha||i,null!=r&&(e.setClearColor(r),e.setClearAlpha(i||0),e.clear()),this.scene.traverseVisible(e=>{if(e._SSRPassBackupMaterial=e.material,this._selects.includes(e))if((e.material instanceof h||e.material instanceof l)&&null!=e.material.alphaMap){let t=O.get(e.material);t||(t=new a({color:"white",alphaMap:e.material.alphaMap,alphaTest:.5}),O.set(e.material,t)),e.material=t}else if(e.material instanceof b){let t=O.get(e.material);if(!t){const s=e.material,r=s.outputRoughness??R(0),i=s.outputColor.a.multiply(_(r));t=new b({color:v("white").rgba(i),transparent:!0,fog:!1,outputEncoding:!1}),t.lights=!1,O.set(e.material,t)}e.material=t,null!=t.uniforms[D]&&(t.uniforms[D].value=this.elapsedTime)}else e.material=this.metalnessOnMaterial;else e.material=this.metalnessOffMaterial}),e.render(this.scene,this.camera),this.scene.traverseVisible(e=>{e.material=e._SSRPassBackupMaterial}),e.autoClear=o,e.setClearColor(this.originalClearColor),e.setClearAlpha(n),this.scene.background=u,this.scene.fog=d}}E.OUTPUT={Default:0,SSR:1,Beauty:3,Depth:4,Normal:5,Metalness:7};export{E as SSRPass};/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{Matrix4 as t,Vector2 as e}from"three";const n={name:"SSRShader",defines:{MAX_STEP:0,PERSPECTIVE_CAMERA:!0,DISTANCE_ATTENUATION:!0,FRESNEL:!0,INFINITE_THICK:!1,SELECTIVE:!1},uniforms:{tDiffuse:{value:null},tNormal:{value:null},tMetalness:{value:null},tDepth:{value:null},cameraNear:{value:null},cameraFar:{value:null},resolution:{value:new e},cameraProjectionMatrix:{value:new t},cameraInverseProjectionMatrix:{value:new t},opacity:{value:.5},maxDistance:{value:180},cameraRange:{value:0},thickness:{value:.018}},vertexShader:"\n\n\t\tvarying vec2 vUv;\n\n\t\tvoid main() {\n\n\t\t\tvUv = uv;\n\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t}\n\n\t",fragmentShader:'\n\t\t// precision highp float;\n\t\tprecision highp sampler2D;\n\t\tvarying vec2 vUv;\n\t\tuniform sampler2D tDepth;\n\t\tuniform sampler2D tNormal;\n\t\tuniform sampler2D tMetalness;\n\t\tuniform sampler2D tDiffuse;\n\t\tuniform float cameraRange;\n\t\tuniform vec2 resolution;\n\t\tuniform float opacity;\n\t\tuniform float cameraNear;\n\t\tuniform float cameraFar;\n\t\tuniform float maxDistance;\n\t\tuniform float thickness;\n\t\tuniform mat4 cameraProjectionMatrix;\n\t\tuniform mat4 cameraInverseProjectionMatrix;\n\t\t#include <packing>\n\t\tfloat pointToLineDistance(vec3 x0, vec3 x1, vec3 x2) {\n\t\t\t//x0: point, x1: linePointA, x2: linePointB\n\t\t\t//https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html\n\t\t\treturn length(cross(x0-x1,x0-x2))/length(x2-x1);\n\t\t}\n\t\tfloat pointPlaneDistance(vec3 point,vec3 planePoint,vec3 planeNormal){\n\t\t\t// https://mathworld.wolfram.com/Point-PlaneDistance.html\n\t\t\t//// https://en.wikipedia.org/wiki/Plane_(geometry)\n\t\t\t//// http://paulbourke.net/geometry/pointlineplane/\n\t\t\tfloat a=planeNormal.x,b=planeNormal.y,c=planeNormal.z;\n\t\t\tfloat x0=point.x,y0=point.y,z0=point.z;\n\t\t\tfloat x=planePoint.x,y=planePoint.y,z=planePoint.z;\n\t\t\tfloat d=-(a*x+b*y+c*z);\n\t\t\tfloat distance=(a*x0+b*y0+c*z0+d)/sqrt(a*a+b*b+c*c);\n\t\t\treturn distance;\n\t\t}\n\t\tfloat getDepth( const in vec2 uv ) {\n\t\t\treturn texture2D( tDepth, uv ).x;\n\t\t}\n\t\tfloat getViewZ( const in float depth ) {\n\t\t\t#ifdef PERSPECTIVE_CAMERA\n\t\t\t\treturn perspectiveDepthToViewZ( depth, cameraNear, cameraFar );\n\t\t\t#else\n\t\t\t\treturn orthographicDepthToViewZ( depth, cameraNear, cameraFar );\n\t\t\t#endif\n\t\t}\n\t\tvec3 getViewPosition( const in vec2 uv, const in float depth/*clip space*/, const in float clipW ) {\n\t\t\tvec4 clipPosition = vec4( ( vec3( uv, depth ) - 0.5 ) * 2.0, 1.0 );//ndc\n\t\t\tclipPosition *= clipW; //clip\n\t\t\treturn ( cameraInverseProjectionMatrix * clipPosition ).xyz;//view\n\t\t}\n\t\tvec3 getViewNormal( const in vec2 uv ) {\n\t\t\treturn unpackRGBToNormal( texture2D( tNormal, uv ).xyz );\n\t\t}\n\t\tvec2 viewPositionToXY(vec3 viewPosition){\n\t\t\tvec2 xy;\n\t\t\tvec4 clip=cameraProjectionMatrix*vec4(viewPosition,1);\n\t\t\txy=clip.xy;//clip\n\t\t\tfloat clipW=clip.w;\n\t\t\txy/=clipW;//NDC\n\t\t\txy=(xy+1.)/2.;//uv\n\t\t\txy*=resolution;//screen\n\t\t\treturn xy;\n\t\t}\n\t\tvoid main(){\n\t\t\tfloat reflectivity = 1.0;\n\t\t\t// These are only combined if we don\'t render normals in the pass\n\t\t\tvec4 normalRoughness = texture2D(tNormal,vUv);\n\t\t\t// No point in checking if selective as with our current renderer\n\t\t\t// it will always utilize the gbuffer roughness to determine the \n\t\t\t// reflectivity\n\t\t\t//#ifdef SELECTIVE\n\t\t\t\t// float metalness=texture2D(tMetalness,vUv).r;\n\t\t\t\tfloat metalness = 1.0 - normalRoughness.w;\n\t\t\t\treflectivity = metalness;\n\t\t\t\tif(metalness==0.) return;\n\t\t\t//#endif\n\n\t\t\tfloat depth = getDepth( vUv );\n\t\t\tfloat viewZ = getViewZ( depth );\n\t\t\tif(-viewZ>=cameraFar) return;\n\n\t\t\tfloat clipW = cameraProjectionMatrix[2][3] * viewZ+cameraProjectionMatrix[3][3];\n\t\t\tvec3 viewPosition=getViewPosition( vUv, depth, clipW );\n\n\t\t\tvec2 d0=gl_FragCoord.xy;\n\t\t\tvec2 d1;\n\n\t\t\tvec3 viewNormal = unpackRGBToNormal(normalRoughness.xyz); //getViewNormal( vUv );\n\n\t\t\t#ifdef PERSPECTIVE_CAMERA\n\t\t\t\tvec3 viewIncidentDir=normalize(viewPosition);\n\t\t\t\tvec3 viewReflectDir=reflect(viewIncidentDir,viewNormal);\n\t\t\t#else\n\t\t\t\tvec3 viewIncidentDir=vec3(0,0,-1);\n\t\t\t\tvec3 viewReflectDir=reflect(viewIncidentDir,viewNormal);\n\t\t\t#endif\n\n\t\t\tfloat maxReflectRayLen=maxDistance/dot(-viewIncidentDir,viewNormal);\n\t\t\t// dot(a,b)==length(a)*length(b)*cos(theta) // https://www.mathsisfun.com/algebra/vectors-dot-product.html\n\t\t\t// if(a.isNormalized&&b.isNormalized) dot(a,b)==cos(theta)\n\t\t\t// maxDistance/maxReflectRayLen=cos(theta)\n\t\t\t// maxDistance/maxReflectRayLen==dot(a,b)\n\t\t\t// maxReflectRayLen==maxDistance/dot(a,b)\n\n\t\t\tvec3 d1viewPosition=viewPosition+viewReflectDir*maxReflectRayLen;\n\t\t\t#ifdef PERSPECTIVE_CAMERA\n\t\t\t\tif(d1viewPosition.z>-cameraNear){\n\t\t\t\t\t//https://tutorial.math.lamar.edu/Classes/CalcIII/EqnsOfLines.aspx\n\t\t\t\t\tfloat t=(-cameraNear-viewPosition.z)/viewReflectDir.z;\n\t\t\t\t\td1viewPosition=viewPosition+viewReflectDir*t;\n\t\t\t\t}\n\t\t\t#endif\n\t\t\td1=viewPositionToXY(d1viewPosition);\n\n\t\t\tfloat totalLen=length(d1-d0);\n\t\t\tfloat xLen=d1.x-d0.x;\n\t\t\tfloat yLen=d1.y-d0.y;\n\t\t\tfloat totalStep=max(abs(xLen),abs(yLen));\n\t\t\tfloat xSpan=xLen/totalStep;\n\t\t\tfloat ySpan=yLen/totalStep;\n\t\t\tfor(float i=0.;i<float(MAX_STEP);i++){\n\t\t\t\tif(i>=totalStep) break;\n\t\t\t\tvec2 xy=vec2(d0.x+i*xSpan,d0.y+i*ySpan);\n\t\t\t\tif(xy.x<0.||xy.x>resolution.x||xy.y<0.||xy.y>resolution.y) break;\n\t\t\t\tfloat s=length(xy-d0)/totalLen;\n\t\t\t\tvec2 uv=xy/resolution;\n\n\t\t\t\tfloat d = getDepth(uv);\n\t\t\t\tfloat vZ = getViewZ( d );\n\t\t\t\tif(-vZ>=cameraFar) continue;\n\t\t\t\tfloat cW = cameraProjectionMatrix[2][3] * vZ+cameraProjectionMatrix[3][3];\n\t\t\t\tvec3 vP=getViewPosition( uv, d, cW );\n\n\t\t\t\t#ifdef PERSPECTIVE_CAMERA\n\t\t\t\t\t// https://comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf\n\t\t\t\t\tfloat recipVPZ=1./viewPosition.z;\n\t\t\t\t\tfloat viewReflectRayZ=1./(recipVPZ+s*(1./d1viewPosition.z-recipVPZ));\n\t\t\t\t#else\n\t\t\t\t\tfloat viewReflectRayZ=viewPosition.z+s*(d1viewPosition.z-viewPosition.z);\n\t\t\t\t#endif\n\n\t\t\t\t// if(viewReflectRayZ>vZ) continue; // will cause "npm run make-screenshot webgl_postprocessing_ssr" high probability hang.\n\t\t\t\t// https://github.com/mrdoob/three.js/pull/21539#issuecomment-821061164\n\t\t\t\tif(viewReflectRayZ<=vZ){\n\n\t\t\t\t\tbool hit;\n\t\t\t\t\t#ifdef INFINITE_THICK\n\t\t\t\t\t\thit=true;\n\t\t\t\t\t#else\n\t\t\t\t\t\tfloat away=pointToLineDistance(vP,viewPosition,d1viewPosition);\n\n\t\t\t\t\t\tfloat minThickness;\n\t\t\t\t\t\tvec2 xyNeighbor=xy;\n\t\t\t\t\t\txyNeighbor.x+=1.;\n\t\t\t\t\t\tvec2 uvNeighbor=xyNeighbor/resolution;\n\t\t\t\t\t\tvec3 vPNeighbor=getViewPosition(uvNeighbor,d,cW);\n\t\t\t\t\t\tminThickness=vPNeighbor.x-vP.x;\n\t\t\t\t\t\tminThickness*=3.;\n\t\t\t\t\t\tfloat tk=max(minThickness,thickness);\n\n\t\t\t\t\t\thit=away<=tk;\n\t\t\t\t\t#endif\n\n\t\t\t\t\tif(hit){\n\t\t\t\t\t\tvec3 vN=getViewNormal( uv );\n\t\t\t\t\t\tif(dot(viewReflectDir,vN)>=0.) continue;\n\t\t\t\t\t\tfloat distance=pointPlaneDistance(vP,viewPosition,viewNormal);\n\t\t\t\t\t\tif(distance>maxDistance) break;\n\t\t\t\t\t\tfloat op=opacity;\n\t\t\t\t\t\t#ifdef DISTANCE_ATTENUATION\n\t\t\t\t\t\t\tfloat ratio=1.-(distance/maxDistance);\n\t\t\t\t\t\t\tfloat attenuation=ratio*ratio;\n\t\t\t\t\t\t\top=opacity*attenuation;\n\t\t\t\t\t\t#endif\n\t\t\t\t\t\t#ifdef FRESNEL\n\t\t\t\t\t\t\tfloat fresnelCoe=(dot(viewIncidentDir,viewReflectDir)+1.)/2.;\n\t\t\t\t\t\t\top*=fresnelCoe;\n\t\t\t\t\t\t#endif\n\t\t\t\t\t\tvec4 reflectColor=texture2D(tDiffuse,uv);\n\t\t\t\t\t\tgl_FragColor.xyz=reflectColor.xyz;\n\t\t\t\t\t\top *= reflectivity;\n\t\t\t\t\t\tgl_FragColor.a=op;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t'},i={name:"SSRDepthShader",defines:{PERSPECTIVE_CAMERA:1},uniforms:{tDepth:{value:null},cameraNear:{value:null},cameraFar:{value:null}},vertexShader:"\n\n\t\tvarying vec2 vUv;\n\n\t\tvoid main() {\n\n\t\t\tvUv = uv;\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t}\n\n\t",fragmentShader:"\n\n\t\tuniform sampler2D tDepth;\n\n\t\tuniform float cameraNear;\n\t\tuniform float cameraFar;\n\n\t\tvarying vec2 vUv;\n\n\t\t#include <packing>\n\n\t\tfloat getLinearDepth( const in vec2 uv ) {\n\n\t\t\t#if PERSPECTIVE_CAMERA == 1\n\n\t\t\t\tfloat fragCoordZ = texture2D( tDepth, uv ).x;\n\t\t\t\tfloat viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );\n\t\t\t\treturn viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );\n\n\t\t\t#else\n\n\t\t\t\treturn texture2D( tDepth, uv ).x;\n\n\t\t\t#endif\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tfloat depth = getLinearDepth( vUv );\n\t\t\tfloat d = 1.0 - depth;\n\t\t\t// d=(d-.999)*1000.;\n\t\t\tgl_FragColor = vec4( vec3( d ), 1.0 );\n\n\t\t}\n\n\t"},a={name:"SSRBlurShader",uniforms:{tDiffuse:{value:null},resolution:{value:new e},opacity:{value:.5}},vertexShader:"\n\n\t\tvarying vec2 vUv;\n\n\t\tvoid main() {\n\n\t\t\tvUv = uv;\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t}\n\n\t",fragmentShader:"\n\n\t\tuniform sampler2D tDiffuse;\n\t\tuniform vec2 resolution;\n\t\tvarying vec2 vUv;\n\t\tvoid main() {\n\t\t\t//reverse engineering from PhotoShop blur filter, then change coefficient\n\n\t\t\tvec2 texelSize = ( 1.0 / resolution );\n\n\t\t\tvec4 c=texture2D(tDiffuse,vUv);\n\n\t\t\tvec2 offset;\n\n\t\t\toffset=(vec2(-1,0))*texelSize;\n\t\t\tvec4 cl=texture2D(tDiffuse,vUv+offset);\n\n\t\t\toffset=(vec2(1,0))*texelSize;\n\t\t\tvec4 cr=texture2D(tDiffuse,vUv+offset);\n\n\t\t\toffset=(vec2(0,-1))*texelSize;\n\t\t\tvec4 cb=texture2D(tDiffuse,vUv+offset);\n\n\t\t\toffset=(vec2(0,1))*texelSize;\n\t\t\tvec4 ct=texture2D(tDiffuse,vUv+offset);\n\n\t\t\t// float coeCenter=.5;\n\t\t\t// float coeSide=.125;\n\t\t\tfloat coeCenter=.2;\n\t\t\tfloat coeSide=.2;\n\t\t\tfloat a=c.a*coeCenter+cl.a*coeSide+cr.a*coeSide+cb.a*coeSide+ct.a*coeSide;\n\t\t\tvec3 rgb=(c.rgb*c.a*coeCenter+cl.rgb*cl.a*coeSide+cr.rgb*cr.a*coeSide+cb.rgb*cb.a*coeSide+ct.rgb*ct.a*coeSide)/a;\n\t\t\tgl_FragColor=vec4(rgb,a);\n\n\t\t}\n\t"};export{n as SSRShader,i as SSRDepthShader,a as SSRBlurShader};/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{NoToneMapping as e,ACESFilmicToneMapping as a,AgXToneMapping as n,CineonToneMapping as m,LinearToneMapping as l,NeutralToneMapping as u,ReinhardToneMapping as i}from"three";export const tonemapMappings=[{value:e,name:"None"},{value:l,name:"Linear"},{value:i,name:"Reinhard"},{value:m,name:"Cineon"},{value:a,name:"ACES Filmic"},{value:n,name:"AgX"},{value:u,name:"Neutral"}];/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
package/dist/rendering.d.ts
CHANGED
|
@@ -128,8 +128,14 @@ export declare class RenderingView {
|
|
|
128
128
|
private gBufferCachedVisibility;
|
|
129
129
|
private applyGBufferMaterials;
|
|
130
130
|
private unapplyGBufferMaterials;
|
|
131
|
+
initTextures(scene?: THREE.Scene): void;
|
|
132
|
+
private _initiatedMaterialTextures;
|
|
133
|
+
private _initiatedTextures;
|
|
134
|
+
private _initMaterialTextures;
|
|
131
135
|
private compileInProgress;
|
|
132
|
-
compileAsync(): Promise<void>;
|
|
136
|
+
compileAsync(scene?: Object3D): Promise<void>;
|
|
137
|
+
private applyDepthMaterial;
|
|
138
|
+
private unapplyDepthMaterial;
|
|
133
139
|
private renderScene;
|
|
134
140
|
private pmremGenerator?;
|
|
135
141
|
private pmremGeneratorResults;
|
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 c,Texture as u,Euler as p,MeshStandardMaterial as m}from"three";import{CopyShader as f,EffectComposer as g,FXAAShader as M,GammaCorrectionShader as v,LUTPass as T,RenderPass as y,ShaderPass as b,VRButton as w}from"three-stdlib";import{CSMShader as x,CSMUtil as P}from"./csm.js";import{bool as S,colorToNormal as R,float as C,NodeShaderMaterial as A,standardMaterial as U,uniformFloat as F,uniformVec3 as B,toonMaterial as O,lambertMaterial as I,normalize as E,rgb as D,rgba as L,textureSampler2d as W,transformed as j,varying as G,varyingAttributes as V,varyingTransformed as _,vec4 as N,BooleanExpression as k,select as q,ifDefApply as z,uniformSampler2d as H,RgbaNode as $,mix as X,vec3 as Y,Vec3ExpressionNode as Q}from"three-shader-graph";import{Reflector as K}from"three-stdlib";import{BokehPass as J,OutputPass as Z}from"three/examples/jsm/Addons.js";import{CSM as ee}from"three/examples/jsm/csm/CSM.js";import te from"three/examples/jsm/libs/stats.module.js";import{GTAOPass as se}from"three/examples/jsm/postprocessing/GTAOPass.js";import{Service as ie}from"typedi";import{depthUniformName as re,farUniformName as ae,nearUniformName as ne,resolutionUniformName as oe,sceneNormalUniformName as le,screenUV as he,supportsDepthTextureExtension as de}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as ce}from"./shader-nodes/time.js";import{aoMapUniformName as ue,sceneMapUniformName as pe}from"./shader-nodes/scene-sample.js";import{DepthPass as me}from"./utils/three/depth-pass.js";import{GPUStatsPanel as fe}from"./utils/three/gpu-stats-panel.js";import{OutlinePass as ge}from"./utils/three/outline-pass.js";import{findFirstVisibleObject as Me,traverseVisibleStop as ve}from"./utils/three/traverse.js";import{clamp as Te}from"./utils/math.js";import{ColorPass as ye}from"./rendering/color-pass.js";import{SSRPass as be}from"./rendering/ssr/SSRPass.js";import{SSRShader as we}from"./rendering/ssr/SSRShader.js";import{VolumetricFogPass as xe}from"./rendering/fog/volumetric-fog-pass.js";import{OutlineEffect as Pe}from"./rendering/outline-effect.js";import{UnrealBloomPass as Se}from"./rendering/bloom/UnrealBloomPass.js";import{highPrecisionEyeDepth as Re}from"./shader-nodes/depth.js";import{packDepthToRGBA as Ce}from"three-shader-graph";import{FogVolumeObject as Ae}from"./rendering/fog/fog-volume-object";import{ParallaxStandardMaterial as Ue}from"./shader/builtin/standard-shader.js";import{parallaxOcclusionMapping as Fe}from"./shader-nodes/pom.js";import{FullScreenQuad as Be}from"three-stdlib";import{edgeDepthEffect as Oe}from"./shader-nodes/effects";import{decalDiscard as Ie}from"./shader-nodes/decal.js";import{Pass as Ee}from"three/examples/jsm/Addons.js";P.patchSetupMaterial();const De=document.createElement("div");De.style.position="absolute",De.style.left="50%",De.style.top="50%",De.style.color="black",De.style.zIndex="999";(new i.Layers).set(9);const Le=new i.MeshBasicMaterial({color:"black"}),We=new i.MeshDepthMaterial;var je;We.depthPacking=i.RGBADepthPacking,We.blending=i.NoBlending,We.side=i.DoubleSide,function(e){e[e.opaque=0]="opaque",e[e.transparent=1]="transparent"}(je||(je={}));const Ge=(()=>{const e=new Uint8Array([255,255,255,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),Ve=(()=>{const e=new Uint8Array([0,0,0,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),_e=(()=>{const e=new Uint8Array([128,128,255,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),Ne=new A({color:C(0),position:N(C(0))});Ne.visible=!1;const ke=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let qe=0,ze=e=class{setPaused(e){this.paused=e}resizeRender(){if(!this.running)return;const e=this.container.clientWidth,t=this.container.clientHeight;this.previousClientWith===e&&this.previousClientHeight===t||0!==e&&0!==t&&(this.previousClientWith=e,this.previousClientHeight=t,this.camera instanceof l&&(this.camera.aspect=e/t,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(e,t),this.composer.setSize(e,t),this.dofPass.setSize(e*this.renderer.getPixelRatio(),t*this.renderer.getPixelRatio()),this.fxaaPass.setSize(e*this.renderer.getPixelRatio(),t*this.renderer.getPixelRatio()),this.fxaaPass.uniforms.resolution.value.set(1/(e*this.renderer.getPixelRatio()),1/(t*this.renderer.getPixelRatio())),this.createGRenderTarget(),this.phasedRenderPass.gRenderTarget=this.gRenderTarget,this.bloomPass.emissiveTexture=this.gRenderTarget.textures[1],this.ssrPass.setSize(this.gRenderTarget.width,this.gRenderTarget.height),this.ssrPass.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.aoPass.setSize(this.gRenderTarget.width,this.gRenderTarget.height),this.aoPass.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.sceneColorRenderTarget.dispose(),this.sceneColorRenderTarget=this.createSceneColorRenderTarget(this.renderer,this.container),this.copyPass.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass.material.uniformsNeedUpdate=!0)}addPostProcessVolume(e){if(0===this.postProcessVolumes.length)this.postProcessVolumes.push(e);else{let t=!1;for(let s=0;s<this.postProcessVolumes.length;s++)if(e.priority<this.postProcessVolumes[s].priority){this.postProcessVolumes.splice(s,0,e),t=!0;break}t||this.postProcessVolumes.push(e)}}removePostProcessVolume(e){const t=this.postProcessVolumes.indexOf(e);t>-1&&this.postProcessVolumes.splice(t,1)}constructor(t,s={}){this.container=t,this.options=s,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.postProcessVolumes=[],this.postProcessSettings={},this.csmUpdateInvervals=this.options.shadows?.cascadeUpdateIntervals,this._id=qe++,this.fquadCopy=new Be(new d(f)),this.fquadCopyOpaque=new Be(new A({outputs:[H("tSceneColor",new u).sample(V.uv),N(H("tDepthTexture",new i.DepthTexture(1,1)).sample(V.uv).r)]})),this.fquadBlendAO=(()=>{const e=N(1),t=new A({outputs:[H("tAO",new u).sample(he),e,e],transparent:!0});t.depthWrite=!1,t.depthTest=!1,t.blending=i.MultiplyBlending;return new Be(t)})(),this.resolutionScale=1,this.maxPixelRatio=ke?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 te,this._showStats=!0,this.gbufferMaterialCache=new Map,this.tbufferMaterialCache=new Map,this.gBufferCachedMaterials=new Map,this.gBufferCachedVisibility=[],this.compileInProgress=!1,this.pmremGeneratorResults=new WeakMap,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new r,this.hadBloom=!1,this.bloomStoredMaterials={},this.bloomHidden=[],this._customDepthMaterialCache=new WeakMap,null!=s.maxPixelRatio&&(this.maxPixelRatio=s.maxPixelRatio),this.resolutionScale=s.resolutionScale??1,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(w.createButton(this.renderer));const a=new Pe(this.renderer,{defaultThickness:.005,defaultColor:[0,0,0],defaultAlpha:1,defaultKeepAlive:!0});this.outlineEffect=a,this.createGRenderTarget(),this.composer=new g(this.renderer),this.composer.setSize(t.clientWidth,t.clientHeight);var n=(t.clientWidth||1)/(t.clientHeight||1);const o=new i.PerspectiveCamera(45,n,.5,800);o.layers.enable(19),this.setCamera(o),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=i.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=s.shadows?.autoUpdate??!1,this.renderer.outputColorSpace=i.SRGBColorSpace,this.renderer.toneMapping=i.NoToneMapping,this.renderer.toneMappingExposure=1,this.renderer.gammaFactor=1.4,P.renderingView=this,this.isDepthTextureExtensionSupported=de(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.aoMaskDepthRenderTarget=e.createAOMaskDepthRenderTarget(this.renderer,this.container),this.sceneColorRenderTarget=this.createSceneColorRenderTarget(this.renderer,this.container);const l=new i.Vector2(t.clientWidth,t.clientHeight),h=(new y(this.scene,this.camera),new b(f,"prevtexture"));h.enabled=!0,h.needsSwap=!0,h.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass=h;const c=new Se(l,1.5,.4,.85);c.threshold=1,c.strength=.9,c.radius=.5,this.bloomPass=c;const p=new se(this.scene,this.camera,this.gRenderTarget.width,this.gRenderTarget.height,{});p.normalRenderTarget?.dispose(),p.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),p.output=se.OUTPUT.Off,p.enabled=!1,this.aoPass=p,this.fquadBlendAO.material.uniforms.tAO.value=p.pdRenderTarget.texture,we.fragmentShader=we.fragmentShader.replace("if(metalness==0.) return;","if(metalness<0.1) return;");const m=new be({renderer:this.renderer,scene:this.scene,camera:this.camera,width:this.gRenderTarget.width,height:this.gRenderTarget.height,groundReflector:null,selects:[],normalTexture:this.gRenderTarget.textures[2],depthTexture:this.gRenderTarget.depthTexture});m.output=be.OUTPUT.Default,m.blur=!0,m.fresnel=!1,m.distanceAttenuation=!0,m.maxDistance=50,m.selective=!0,m.bouncing=!1,m.opacity=.4,m.enabled=!1!==this.options?.reflection?.enabled,this.ssrPass=m,!1!==this.options.ao?.enabled&&this.composer.addPass(p);const x=new nt((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(x);const S=new nt((e,t,s,i,r)=>{this.renderer.setRenderTarget(this.gRenderTarget),this.renderScene(je.transparent),this.renderer.setRenderTarget(null)});this.composer.addPass(S),this.composer.addPass(h),this.composer.addPass(m),this.phasedRenderPass=new at(this.scene,this.camera,this.gRenderTarget),this.composer.addPass(this.phasedRenderPass),this.composer.addPass(c),c.emissiveTexture=this.gRenderTarget.textures[1],this.renderer.info.autoReset=!1,this.volumetricFogPass=new xe(l),this.composer.addPass(this.volumetricFogPass),this.volumetricFogPass.enabled=!0,this.dofPass=new J(this.scene,this.camera,{focus:1,aperture:.025,maxblur:.01}),this.dofPass.enabled=!1,this.composer.addPass(this.dofPass);const R=new ye;this.composer.addPass(R),this.colorPass=R,R.vignetteEnabled=!1,this.outlinePass=new ge(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 b(M);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 b(v).clear=!1,this.fixStatsStyle(),this.lutPass=new T({}),this.lutPass.enabled=!1,this.composer.addPass(this.lutPass);const U=new b(f,"prevtexture");U.enabled=!0,U.needsSwap=!1,U.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[1],U.renderToScreen=!0;const F=new Z;this.composer.addPass(F)}fixStatsStyle(){const e=this.stats.dom;e.style.position="absolute";const t=e.getElementsByTagName("canvas");for(let e=0;e<t.length;e++)t.item(e).style.display="inline-block"}setEnableOutlines(e){this.outlinePass.enabled=e,this.fxaaPass.enabled=e}setCamera(e){if(this.camera=e,this.composer.passes.forEach(t=>{t instanceof y?t.camera=e:t instanceof ge?t.renderCamera=e:(t instanceof me||t instanceof se)&&(t.camera=e)}),this.ssrPass&&(this.ssrPass.camera=e),this.aoPass&&(this.aoPass.camera=e),this.phasedRenderPass&&(this.phasedRenderPass.camera=e),null==this.csm){if(this.csm=new ee({maxFar:100,lightFar:250,lightMargin:20,cascades:ke?2:4,shadowMapSize:2048*(ke?.5:1),lightDirection:new i.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5*Math.PI,camera:this.camera,parent:this.scene,mode:"practical"}),null!=this.csmUpdateInvervals){this.csmCascadeLastUpdate=new Array(this.csm.lights.length).fill(0);for(const e of this.csm.lights)e.shadow.autoUpdate=!1}this.csm&&Array.isArray(this.csm.lights),this.csm.fade=!0,h.lights_fragment_begin=x.lights_fragment_begin}else this.csm.camera=this.camera,this.camera;this.csm.updateFrustums()}setSelectedObjects(e){if(null==this.outlinePass)return;const t=new Map;for(const s of e)t.set(s.uuid,s);for(const s of e)s.traverse(e=>{e.uuid!==s.uuid&&t.has(e.uuid)&&t.delete(e.uuid)});this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(e,t,s){const r=Math.max(1,Math.floor(t.clientWidth*s)),a=Math.max(1,Math.floor(t.clientHeight*s)),n=new i.WebGLRenderTarget(r,a);return n.texture.minFilter=i.NearestFilter,n.texture.magFilter=i.NearestFilter,n.texture.generateMipmaps=!1,n.stencilBuffer=!1,n.depthTexture=new i.DepthTexture(r,a),n.depthTexture.type=i.UnsignedShortType,n.depthTexture.minFilter=i.NearestFilter,n.depthTexture.magFilter=i.NearestFilter,n}static createAOMaskDepthRenderTarget(e,t){const s=Math.max(1,t.clientWidth*e.getPixelRatio()),r=Math.max(1,t.clientHeight*e.getPixelRatio()),a=new i.DepthTexture(s,r);a.type=i.UnsignedInt248Type,a.minFilter=i.NearestFilter,a.magFilter=i.NearestFilter;const n=new i.WebGLRenderTarget(s,r,{type:i.HalfFloatType,depthTexture:a});return n.texture.minFilter=i.NearestFilter,n.texture.magFilter=i.NearestFilter,n.texture.generateMipmaps=!1,n.stencilBuffer=!1,n}createSceneColorRenderTarget(e,t){const s=this.gRenderTarget.width,r=this.gRenderTarget.height,a=new i.WebGLRenderTarget(s,r,{count:2,type:i.FloatType,format:i.RGBAFormat,colorSpace:i.SRGBColorSpace,depthBuffer:!1,stencilBuffer:!1});return a.texture.minFilter=i.LinearFilter,a.texture.magFilter=i.LinearFilter,a.texture.generateMipmaps=!1,a.textures[1].minFilter=i.NearestFilter,a.textures[1].magFilter=i.NearestFilter,a}createGRenderTarget(){const e=this.container;null!=this.gRenderTarget&&this.gRenderTarget.dispose();const t=Math.max(1,e.clientWidth*this.renderer.getPixelRatio()),s=Math.max(1,e.clientHeight*this.renderer.getPixelRatio()),r=new i.DepthTexture(t,s);r.type=i.UnsignedIntType,r.minFilter=i.NearestFilter,r.magFilter=i.NearestFilter,this.gRenderTarget=new c(t,s,{count:3,minFilter:i.NearestFilter,magFilter:i.NearestFilter,type:i.HalfFloatType,format:i.RGBAFormat,depthTexture:r}),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(),P.clearSceneCache(this.scene)}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);t>=0&&this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}applyEnvMap(e){if(null!=this.scene.environment&&(e instanceof 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:et(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&&"receiveShadow"!==e&&!1===ot.includes(e)&&(t.value=r)}}updateLightUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e of ot){const t=i[e],r=s[e];null!=r&&null!=t&&(t.value=r.value)}}createGBufferMaterial(e,t){const s=t===je.opaque?this.gbufferMaterialCache:this.tbufferMaterialCache;let r=s.get(e);if(!0===e.userData.isGBufferMaterial)return e;if(null==r){let n=V.uv;if(e instanceof Ue&&null!=e.heightMap){const t=F("heightScale",e.heightScale??1);n=Fe(n,W(e.heightMap),t)}let o=_.normal;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=e.normalMap??_e,s=F("useNormalMap",null!=e.normalMap?1:0),i=F("normalScale",e.normalScale?.x??1),r=R(W(t).sample(n),i);o=X(_.normal,r,s)}else e instanceof A&&null!=e.outputNormal&&(o=e.outputNormal);!0!==e.userData.disableAO&&(o=z("DOUBLE_SIDED",o,e=>q(new k("gl_FrontFacing"),e,e.multiplyScalar(-1))));let l=e.userData?.reflective?C(0):C(1);if(e instanceof i.MeshStandardMaterial){const t=F("roughness",e.roughness??1),s=e.roughnessMap??Ge,i=F("useRoughnessMap",null!=e.roughnessMap?1:0),r=W(s).sample(n).g.multiply(t);l=X(t,r,i)}else e instanceof A&&null!=e.outputRoughness&&(l=e.outputRoughness);let h=null;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial){const t=e.lightMap??Ve,s=F("useLightMap",null!=e.lightMap?1:0),i=F("lightMapIntensity",e.lightMapIntensity??1),r=W(t).sample(n).rgb.multiplyScalar(i);h=X(D(0),r,s)}let c=C(0);if(e instanceof i.MeshStandardMaterial){const t=F("metalness",e.metalness??0),s=e.metalnessMap??Ve,i=F("useMetalnessMap",null!=e.metalnessMap?1:0),r=W(s).sample(n).b.multiply(t);c=X(t,r,i)}else e instanceof A&&e.outputRoughness;let u=null,p=C(1);if(e instanceof i.MeshStandardMaterial){const t=e.aoMap??Ge,s=F("useAoMap",null!=e.aoMap?1:0);p=F("aoMapIntensity",e.aoMapIntensity??1);const i=W(t).sample(n).r;u=X(C(1),i,s)}else e instanceof A&&e.outputRoughness;const f=F("opacity",e.opacity??1);let g=C(1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=e.alphaMap??Ge,s=F("useAlphaMap",null!=e.alphaMap?1:0),i=W(t).sample(n).r;g=X(C(1),i,s),g=g.multiply(f)}else e instanceof A&&null!=e.outputOpacity&&(g=e.outputOpacity);let M=L(0,1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial){let t=B("color",(new i.Vector3).setFromColor(e.color));if(e.vertexColors){const e=G(z("USE_COLOR",Y(1,1,1),e=>new Q("color")));t=t.multiply(e)}const s=e.map??Ge,r=F("useAlbedoMap",null!=e.map?1:0),a=W(s).sample(n),o=a.multiply(L(t,1)),l=L(t,1);M=X(l,o,r);const h=X(C(1),a.w,r);g=g.multiply(h)}const v=!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=B("emissive",(new i.Vector3).setFromColor(e.emissive)),s=F("emissiveIntensity",e.emissiveIntensity),r=e.emissiveMap??Ve,a=F("useEmissiveMap",null!=e.emissiveMap?1:0),o=W(r).sample(n).rgb.multiply(t);T=X(t,o,a),T=T.multiplyScalar(s)}else e instanceof A&&null!=e.outputEmissive&&(T=e.outputEmissive);const y=e instanceof d&&null!=e.uniforms[re],b=e instanceof d&&null!=e.uniforms[pe],w=e instanceof d&&null!=e.uniforms[ue],x=e.transparent&&e.alphaTest<=.01||e.blending===i.AdditiveBlending,P=F("alphaTest",e.alphaTest);let j,H=e.alphaTest>0?g.lt(P):x&&t===je.opaque?g.lt(.8):S(!1);!0===e.userData.isDecal&&(H=H.or(Ie)),j=x?N(0,0,0,0):(a=o,E(a).multiplyScalar(.5).addScalar(.5)).rgba(e.userData?.reflective?l:1);const $=e instanceof A?e.outputPosition:void 0,K=e instanceof A?e.outputTransform:void 0;let J,Z=L("black",1);if(e instanceof A&&null!=e.outputColor)Z=e.outputColor;else if(e instanceof i.MeshStandardMaterial)Z=U({color:M,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)Z=I({color:M.rgb});else if(e instanceof i.MeshBasicMaterial){let e=M.rgb,t=h??D("white");null!=u&&(t=t.multiplyScalar(u.subtract(1).multiply(p).add(1))),e=e.add(t),Z=e.rgba(g)}else e instanceof i.MeshToonMaterial&&(Z=O({color:M,emissive:T.rgb,normal:o,ambientOcclusion:u,ambientOcclusionIntensity:p,bakedLight:h}));(e instanceof A||e instanceof i.MeshStandardMaterial)&&(J=e.envMap);let ee=!0;(e instanceof m||e instanceof i.MeshBasicMaterial||e instanceof i.ShaderMaterial)&&(ee=e.fog);let te=L(Z.rgb,g);ee&&(te=new FogNode(te));let se=!0;if(t===je.opaque?(se&&(se=!y&&!b&&!w),se&&(se=!x)):t===je.transparent&&se&&(se=x||y||b||w),!se)return r=Ne,s.set(e,r),r;r=new A({transform:K,position:null==K?$:void 0,outputs:[te,T.rgba(t===je.opaque?P:v?1:0),j],opacity:g,outputEncoding:!1,fog:ee,transparent:e.transparent,lights:!0,envMap:J,discard:H}),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,x?(r.depthWrite=!e.transparent,r.depthTest=e.depthTest,r.colorWrite=t===je.transparent):(r.depthWrite=e.depthWrite,r.depthTest=e.depthTest),r.visible=e.visible,r.alphaTest=e.alphaTest,r.alphaHash=e.alphaHash,r.vertexColors=e.vertexColors,r.premultipliedAlpha=e.premultipliedAlpha,r.toneMapped=e.toneMapped,r.blendAlpha=e.blendAlpha,r.blendColor=e.blendColor,r.polygonOffset=e.polygonOffset,r.polygonOffsetFactor=e.polygonOffsetFactor,r.polygonOffsetUnits=e.polygonOffsetUnits,r.blending=e.blending,r.userData.isGBufferMaterial=!0,r.visible=se,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}updateCsm(){const e=this.csmUpdateInvervals;if(this.renderer.shadowMap.autoUpdate&&null!=this.csmCascadeLastUpdate&&Array.isArray(e)){const t=performance.now();for(let s=0;s<this.csm.lights.length;++s){const i=e[s]??e[e.length-1]??16;if(t-this.csmCascadeLastUpdate[s]>=i&&this.csm.lights[s].shadow){this.csm.lights[s].shadow.needsUpdate=!0,this.csmCascadeLastUpdate[s]=t;break}}}this.csm.update()}loop(e,t=!1){const s=this.stats,r=s.addPanel(new te.Panel("Calls","#83f","#002")),a=s.addPanel(new te.Panel("Triangles","#c32","#002"));let l;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(l=new fe(this.renderer.getContext()),s.addPanel(l)),this.showStats=t;let h=10,d=1e3;const c=()=>{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 u=[],p=[],m=[];let f=0;const g=new n,M=new n;let v=0;let T=this.paused;const y=t=>{const r=this.renderer.getContext();if(this.paused&&this.running&&r.drawingBufferHeight>1)return setTimeout(()=>y(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(He),t-=He;e(t)}else e(a);this.onLoopCallbacks.forEach(e=>e(a)),this.camera?.updateMatrixWorld(),M.copy(this.camera.matrixWorld),t-v>.08&&!M.equals(g)&&(this.renderer.shadowMap.needsUpdate=!0,v=t),this.updateCsm();let n=!1;u.length=0,p.length=0,m.length=0;const h=Xe;Qe.multiplyMatrices(this.camera.projectionMatrix,this.camera.matrixWorldInverse),h.setFromProjectionMatrix(Qe);let d=!1,b=!1,w=!1;this.scene.traverseVisible(e=>{if(this.setupCsm(e),this.outlineEffect.apply(e),e instanceof Ae&&(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[re])&&isObjectInFrustum(e,h)?(this.initDepthUniform(e.material),b=!0):e instanceof K&&(e.visible=!1,p.push(e)),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[ue]&&isObjectInFrustum(e,h)&&e.material instanceof A&&this.initAoUniform(e.material),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[pe]&&isObjectInFrustum(e,h)&&(m.push(e),e.material.uniforms[pe].value=this.sceneColorRenderTarget.texture,w=!0),e instanceof o&&e.material?.uniforms&&null!=e.material?.uniforms[ce])e.material.uniforms[ce].value=t;else if(e instanceof o&&Array.isArray(e.material))for(const s of e.material)s.uniforms&&null!=s.uniforms[ce]&&(s.uniforms[ce].value=t)}),this.bloomPass.enabled=n,this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.clear(),this.renderScene(je.opaque),this.aoPass.output=se.OUTPUT.Off,(b||w)&&(this.fquadCopyOpaque.material.uniforms.tSceneColor.value=this.gRenderTarget.textures[0],this.fquadCopyOpaque.material.uniforms.tDepthTexture.value=this.gRenderTarget.depthTexture,this.initResolutionUniform(this.fquadCopyOpaque.material),this.renderer.setRenderTarget(this.sceneColorRenderTarget),this.renderer.clear(),this.fquadCopyOpaque.render(this.renderer),this.renderer.setRenderTarget(this.gRenderTarget)),m.length,u.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&&c(),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(y)},1e3/this.fpsCap):requestAnimationFrame(y))};!0===this.options.enableXR?this.renderer.setAnimationLoop(y):requestAnimationFrame(y)}applyGBufferMaterials(e){const t=this.gBufferCachedMaterials,s=this.gBufferCachedVisibility;t.clear(),s.length=0;ve(this.scene,i=>{if(it(i))return s.push(i),i.visible=!1,!1;if(i instanceof o){t.set(i,i.material);let r=!1;if(Array.isArray(i.material)){i.material=i.material.slice();for(let t=0;t<i.material.length;t++)i.material[t]=this.createGBufferMaterial(i.material[t],e),r||(r=i.material[t].visible),this.initShadowUniform(i,i.material[t])}else i.material=this.createGBufferMaterial(i.material,e),r||(r=i.material.visible),this.initShadowUniform(i,i.material);r?i.visible=!0:null!=i.children&&0!=i.children.length||(s.push(i),i.visible=!1)}})}unapplyGBufferMaterials(){this.gBufferCachedMaterials.forEach((e,t)=>{t.material=e}),this.gBufferCachedVisibility.forEach((e,t)=>{e.visible=!0,e.updateMatrixWorld(!0)})}async compileAsync(){this.compileInProgress||(this.renderer.setRenderTarget(this.gRenderTarget),this.compileInProgress=!0,this.applyGBufferMaterials(je.opaque),await this.renderer.compileAsync(this.scene,this.camera),this.unapplyGBufferMaterials(),this.applyGBufferMaterials(je.transparent),await this.renderer.compileAsync(this.scene,this.camera),this.unapplyGBufferMaterials(),this.compileInProgress=!1,this.renderer.setRenderTarget(null))}renderScene(e){if(!this.running||this.paused)return;if(this.compileInProgress)return void console.error("Compile in progress, skipping render");this.applyGBufferMaterials(e);const t=this.scene.matrixWorldAutoUpdate,s=this.scene.matrixAutoUpdate,i=this.renderer.shadowMap.autoUpdate;e!==je.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===je.opaque&&this.gBufferCachedMaterials.forEach((e,t)=>{!Array.isArray(e)&&!Array.isArray(t.material)&&e instanceof d&&this.updateLightUniformValues(t.material,e)}),this.unapplyGBufferMaterials(),this.renderer.shadowMap.autoUpdate=i,this.scene.matrixWorldAutoUpdate=t,this.scene.matrixAutoUpdate=s}getEnvTexture(e){null==this.pmremGenerator&&(this.pmremGenerator=new i.PMREMGenerator(this.renderer),this.pmremGenerator.compileEquirectangularShader());let t=this.pmremGeneratorResults.get(e);return null==t&&(t=this.pmremGenerator.fromEquirectangular(e).texture,this.pmremGeneratorResults.set(e,t)),t.colorSpace=i.SRGBColorSpace,t}applyPostProcessSettings(){if(0==this.postProcessVolumes.length)return this.lutPass.enabled=!1,void(this.colorPass.enabled=!1);var e;(e=this.postProcessSettings).tonemapMapping=void 0,e.tonemapExposure=1,e.envIntensity=1,e.envTexture=void 0,e.vignetteIntensity=0,e.colorTint=new i.Color("white"),e.colorTintIntensity=0,e.depthFocus=void 0,e.depthAperture=void 0,e.depthMaxBlur=void 0,e.temperature=6500,e.temperatureTint=0,e.lut=void 0,e.lutIntensity=0;const t=this.postProcessSettings;let s,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(!$e(e.object))continue;let l=e.blendWeight??1;const c=e.distanceToPoint(h);c>e.blendRadius||(e.blendRadius>0&&(l*=Te(1-c/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(!this.running)return;if(0===this.overlayCameras.size)return;const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.previousClientWith/2,s=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let i=0;i<e.length;i++)this.renderer.clearDepth(),this.renderer.setViewport(t-s/2+this.insetWidth*i+this.insetMargin*i,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[i])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){if(!this.running)return;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,Xe)&&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===Le.id)return;this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=Le:(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[re].value=this.sceneColorRenderTarget.textures[1],this.camera instanceof l&&(null!=e.uniforms[ne]&&(e.uniforms[ne].value=this.camera.near),null!=e.uniforms[ae]&&(e.uniforms[ae].value=this.camera.far)))}initNormalUniform(e){e instanceof d&&null!=e.uniforms[le]&&(e.uniforms[le].value=this.gRenderTarget.textures[2])}initShadowUniform(e,t){var s;t instanceof A&&(t.uniforms.receiveShadow?(s=t.uniforms.receiveShadow).value||(s.value=e.receiveShadow):t.uniforms.receiveShadow={value:e.receiveShadow})}initResolutionUniform(e){e instanceof d&&null!=e.uniforms[oe]&&e.uniforms[oe].value.set(this.gRenderTarget.width,this.gRenderTarget.height)}initAoUniform(e){if(this.aoPass.enabled){e.uniforms[ue].value=this.aoPass.pdRenderTarget.texture,null==e.defines.USE_SSAO_MAP&&(e.defines.USE_SSAO_MAP="",e.needsUpdate=!0),e.defines.USE_SSAO_MAP="";const t=this.tbufferMaterialCache.get(e);null!=t&&this.initAoUniform(t)}else if(null!=e.defines.USE_SSAO_MAP){delete e.defines.USE_SSAO_MAP,e.needsUpdate=!0;const t=this.tbufferMaterialCache.get(e);null!=t&&this.initAoUniform(t)}}initCustomDepthMaterial(e){if(null!=e.customDepthMaterial||!e.castShadow)return;const t=e.material;if(t instanceof A&&!t.transparent&&t.depthWrite){let s=this._customDepthMaterialCache.get(t);if(null==s){const e=Ce(Re);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}}};ze=e=t([ie(),s("design:paramtypes",[HTMLElement,Object])],ze);export{ze as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const He=.05;function $e(e){let t=e;for(;t;){if(!1===t.visible)return!1;t=t.parent}return!0}se.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 Xe=new i.Frustum,Ye=new i.Box3,Qe=new i.Matrix4;export function isObjectInFrustum(e,t){const s=Ye.setFromObject(e);return t.intersectsBox(s)}const Ke=new i.Vector3;const Je=new n,Ze=new p;function et(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(Je.makeRotationFromEuler(Ze))}const tt=new A({outputs:[N(0,0,0,0),N(0,0,0,0),L(D("white"),Oe(4))],transparent:!0}),st=new i.MeshBasicMaterial({color:"blue",transparent:!0,opacity:.5});tt.depthWrite=!1;new o(new i.BoxGeometry(4,4,4),st);function it(e){return e instanceof i.Sprite||e.isPoints||e.isLine||e.isLineSegments2||e.isTransformControls||e.isTransformControlsGizmo||e instanceof o&&rt(e,e.material)}function rt(e,t){return null==t||(Array.isArray(t)?t.some(t=>rt(e,t)):t instanceof i.RawShaderMaterial||t instanceof i.ShaderMaterial&&!(t instanceof A))}class at extends Ee{constructor(e,t,s){super(),this.scene=e,this.camera=t,this.gRenderTarget=s,this.cachedVisibility=[],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),this.cachedVisibility.length=0;let c=0;this.scene.traverseVisible(e=>{const t=it(e);e instanceof o&&!t?(this.cachedVisibility.push(e),e.visible=!1):t&&c++}),c>0&&e.render(this.scene,this.camera),this.cachedVisibility.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 nt extends Ee{constructor(e){super(),this.fn=e}render(e,t,s,i,r){this.fn(e,t,s,i,r)}}const ot=["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"],lt=B("fogColor");export class FogNode extends ${constructor(e,t=lt){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(F("fogFar")),n=e.get(F("fogNear")),o=e.get(F("fogDensity")),l=e.get(G(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
|
-
* Copyright (©)
|
|
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 M,GammaCorrectionShader as v,LUTPass as T,RenderPass as y,ShaderPass as x,VRButton as b}from"three-stdlib";import{CSMShader as w,CSMUtil as P}from"./csm.js";import{bool as S,colorToNormal as R,float as C,NodeShaderMaterial as A,standardMaterial as U,uniformFloat as F,uniformVec3 as B,toonMaterial as O,lambertMaterial as D,normalize as I,rgb as E,rgba as L,textureSampler2d as _,transformed as j,varying as G,varyingAttributes as W,varyingTransformed as V,vec4 as q,BooleanExpression as k,select as N,ifDefApply as z,uniformSampler2d as H,RgbaNode as $,mix as X,vec3 as Y,Vec3ExpressionNode as Q}from"three-shader-graph";import{Reflector as K}from"three-stdlib";import{BokehPass as J,OutputPass as Z}from"three/examples/jsm/Addons.js";import{CSM as ee}from"three/examples/jsm/csm/CSM.js";import te from"three/examples/jsm/libs/stats.module.js";import{GTAOPass as se}from"three/examples/jsm/postprocessing/GTAOPass.js";import{Service as ie}from"typedi";import{depthUniformName as re,farUniformName as ae,nearUniformName as ne,resolutionUniformName as oe,sceneNormalUniformName as le,screenUV as he,supportsDepthTextureExtension as de}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as ue}from"./shader-nodes/time.js";import{aoMapUniformName as ce,sceneMapUniformName as pe}from"./shader-nodes/scene-sample.js";import{DepthPass as me}from"./utils/three/depth-pass.js";import{GPUStatsPanel as fe}from"./utils/three/gpu-stats-panel.js";import{OutlinePass as ge}from"./utils/three/outline-pass.js";import{findFirstVisibleObject as Me,traverseVisibleStop as ve}from"./utils/three/traverse.js";import{clamp as Te}from"./utils/math.js";import{ColorPass as ye}from"./rendering/color-pass.js";import{SSRPass as xe}from"./rendering/ssr/SSRPass.js";import{SSRShader as be}from"./rendering/ssr/SSRShader.js";import{VolumetricFogPass as we}from"./rendering/fog/volumetric-fog-pass.js";import{OutlineEffect as Pe}from"./rendering/outline-effect.js";import{UnrealBloomPass as Se}from"./rendering/bloom/UnrealBloomPass.js";import{highPrecisionEyeDepth as Re}from"./shader-nodes/depth.js";import{packDepthToRGBA as Ce}from"three-shader-graph";import{FogVolumeObject as Ae}from"./rendering/fog/fog-volume-object";import{ParallaxStandardMaterial as Ue}from"./shader/builtin/standard-shader.js";import{parallaxOcclusionMapping as Fe}from"./shader-nodes/pom.js";import{FullScreenQuad as Be}from"three-stdlib";import{edgeDepthEffect as Oe}from"./shader-nodes/effects";import{decalDiscard as De}from"./shader-nodes/decal.js";import{Pass as Ie}from"three/examples/jsm/Addons.js";P.patchSetupMaterial();const Ee=document.createElement("div");Ee.style.position="absolute",Ee.style.left="50%",Ee.style.top="50%",Ee.style.color="black",Ee.style.zIndex="999";(new i.Layers).set(9);const Le=new i.MeshBasicMaterial({color:"black"}),_e=new i.MeshDepthMaterial;var je;_e.depthPacking=i.RGBADepthPacking,_e.blending=i.NoBlending,_e.side=i.DoubleSide,function(e){e[e.opaque=0]="opaque",e[e.transparent=1]="transparent"}(je||(je={}));const Ge=(()=>{const e=new Uint8Array([255,255,255,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),We=(()=>{const e=new Uint8Array([0,0,0,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),Ve=(()=>{const e=new Uint8Array([128,128,255,255]),t=new i.DataTexture(e,1,1,i.RGBAFormat);return t.needsUpdate=!0,t})(),qe=new A({color:C(0),position:q(C(0))});qe.visible=!1;const ke=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let Ne=0,ze=e=class{setPaused(e){this.paused=e}resizeRender(){if(!this.running)return;const e=this.container.clientWidth,t=this.container.clientHeight;this.previousClientWith===e&&this.previousClientHeight===t||0!==e&&0!==t&&(this.previousClientWith=e,this.previousClientHeight=t,this.camera instanceof l&&(this.camera.aspect=e/t,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(e,t),this.composer.setSize(e,t),this.dofPass.setSize(e*this.renderer.getPixelRatio(),t*this.renderer.getPixelRatio()),this.fxaaPass.setSize(e*this.renderer.getPixelRatio(),t*this.renderer.getPixelRatio()),this.fxaaPass.uniforms.resolution.value.set(1/(e*this.renderer.getPixelRatio()),1/(t*this.renderer.getPixelRatio())),this.createGRenderTarget(),this.phasedRenderPass.gRenderTarget=this.gRenderTarget,this.bloomPass.emissiveTexture=this.gRenderTarget.textures[1],this.ssrPass.setSize(this.gRenderTarget.width,this.gRenderTarget.height),this.ssrPass.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.aoPass.setSize(this.gRenderTarget.width,this.gRenderTarget.height),this.aoPass.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),this.sceneColorRenderTarget.dispose(),this.sceneColorRenderTarget=this.createSceneColorRenderTarget(this.renderer,this.container),this.copyPass.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass.material.uniformsNeedUpdate=!0)}addPostProcessVolume(e){if(0===this.postProcessVolumes.length)this.postProcessVolumes.push(e);else{let t=!1;for(let s=0;s<this.postProcessVolumes.length;s++)if(e.priority<this.postProcessVolumes[s].priority){this.postProcessVolumes.splice(s,0,e),t=!0;break}t||this.postProcessVolumes.push(e)}}removePostProcessVolume(e){const t=this.postProcessVolumes.indexOf(e);t>-1&&this.postProcessVolumes.splice(t,1)}constructor(t,s={}){this.container=t,this.options=s,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.postProcessVolumes=[],this.postProcessSettings={},this.csmUpdateInvervals=this.options.shadows?.cascadeUpdateIntervals,this._id=Ne++,this.fquadCopy=new Be(new d(f)),this.fquadCopyOpaque=new Be(new A({outputs:[H("tSceneColor",new c).sample(W.uv),q(H("tDepthTexture",new i.DepthTexture(1,1)).sample(W.uv).r)]})),this.fquadBlendAO=(()=>{const e=q(1),t=new A({outputs:[H("tAO",new c).sample(he),e,e],transparent:!0});t.depthWrite=!1,t.depthTest=!1,t.blending=i.MultiplyBlending;return new Be(t)})(),this.resolutionScale=1,this.maxPixelRatio=ke?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 te,this._showStats=!0,this.gbufferMaterialCache=new Map,this.tbufferMaterialCache=new Map,this.gBufferCachedMaterials=new Map,this.gBufferCachedVisibility=[],this._initiatedMaterialTextures=new Set,this._initiatedTextures=new Set,this.compileInProgress=!1,this.pmremGeneratorResults=new WeakMap,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new r,this.hadBloom=!1,this.bloomStoredMaterials={},this.bloomHidden=[],this._customDepthMaterialCache=new WeakMap,null!=s.maxPixelRatio&&(this.maxPixelRatio=s.maxPixelRatio),this.resolutionScale=s.resolutionScale??1,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(b.createButton(this.renderer));const a=new Pe(this.renderer,{defaultThickness:.005,defaultColor:[0,0,0],defaultAlpha:1,defaultKeepAlive:!0});this.outlineEffect=a,this.createGRenderTarget(),this.composer=new g(this.renderer),this.composer.setSize(t.clientWidth,t.clientHeight);var n=(t.clientWidth||1)/(t.clientHeight||1);const o=new i.PerspectiveCamera(45,n,.5,800);o.layers.enable(19),this.setCamera(o),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=i.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=s.shadows?.autoUpdate??!1,this.renderer.outputColorSpace=i.SRGBColorSpace,this.renderer.toneMapping=i.NoToneMapping,this.renderer.toneMappingExposure=1,this.renderer.gammaFactor=1.4,P.renderingView=this,this.isDepthTextureExtensionSupported=de(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.aoMaskDepthRenderTarget=e.createAOMaskDepthRenderTarget(this.renderer,this.container),this.sceneColorRenderTarget=this.createSceneColorRenderTarget(this.renderer,this.container);const l=new i.Vector2(t.clientWidth,t.clientHeight),h=(new y(this.scene,this.camera),new x(f,"prevtexture"));h.enabled=!0,h.needsSwap=!0,h.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[0],this.copyPass=h;const u=new Se(l,1.5,.4,.85);u.threshold=1,u.strength=.9,u.radius=.5,this.bloomPass=u;const p=new se(this.scene,this.camera,this.gRenderTarget.width,this.gRenderTarget.height,{});p.normalRenderTarget?.dispose(),p.setGBuffer(this.gRenderTarget.depthTexture,this.gRenderTarget.textures[2]),p.output=se.OUTPUT.Off,p.enabled=!1,this.aoPass=p,this.fquadBlendAO.material.uniforms.tAO.value=p.pdRenderTarget.texture,be.fragmentShader=be.fragmentShader.replace("if(metalness==0.) return;","if(metalness<0.1) return;");const m=new xe({renderer:this.renderer,scene:this.scene,camera:this.camera,width:this.gRenderTarget.width,height:this.gRenderTarget.height,groundReflector:null,selects:[],normalTexture:this.gRenderTarget.textures[2],depthTexture:this.gRenderTarget.depthTexture});m.output=xe.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 w=new nt((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(w);const S=new nt((e,t,s,i,r)=>{this.renderer.setRenderTarget(this.gRenderTarget),this.renderScene(je.transparent),this.renderer.setRenderTarget(null)});this.composer.addPass(S),this.composer.addPass(h),this.composer.addPass(m),this.phasedRenderPass=new at(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 we(l),this.composer.addPass(this.volumetricFogPass),this.volumetricFogPass.enabled=!0,this.dofPass=new J(this.scene,this.camera,{focus:1,aperture:.025,maxblur:.01}),this.dofPass.enabled=!1,this.composer.addPass(this.dofPass);const R=new ye;this.composer.addPass(R),this.colorPass=R,R.vignetteEnabled=!1,this.outlinePass=new ge(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(M);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(v).clear=!1,this.fixStatsStyle(),this.lutPass=new T({}),this.lutPass.enabled=!1,this.composer.addPass(this.lutPass);const U=new x(f,"prevtexture");U.enabled=!0,U.needsSwap=!1,U.material.uniforms.tDiffuse.value=this.gRenderTarget.textures[1],U.renderToScreen=!0;const F=new Z;this.composer.addPass(F)}fixStatsStyle(){const e=this.stats.dom;e.style.position="absolute";const t=e.getElementsByTagName("canvas");for(let e=0;e<t.length;e++)t.item(e).style.display="inline-block"}setEnableOutlines(e){this.outlinePass.enabled=e,this.fxaaPass.enabled=e}setCamera(e){if(this.camera=e,this.composer.passes.forEach(t=>{t instanceof y?t.camera=e:t instanceof ge?t.renderCamera=e:(t instanceof me||t instanceof se)&&(t.camera=e)}),this.ssrPass&&(this.ssrPass.camera=e),this.aoPass&&(this.aoPass.camera=e),this.phasedRenderPass&&(this.phasedRenderPass.camera=e),null==this.csm){if(this.csm=new ee({maxFar:100,lightFar:250,lightMargin:20,cascades:ke?2:4,shadowMapSize:2048*(ke?.5:1),lightDirection:new i.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5*Math.PI,camera:this.camera,parent:this.scene,mode:"practical"}),null!=this.csmUpdateInvervals){this.csmCascadeLastUpdate=new Array(this.csm.lights.length).fill(0);for(const e of this.csm.lights)e.shadow.autoUpdate=!1}this.csm&&Array.isArray(this.csm.lights),this.csm.fade=!0,h.lights_fragment_begin=w.lights_fragment_begin}else this.csm.camera=this.camera,this.camera;this.csm.updateFrustums()}setSelectedObjects(e){if(null==this.outlinePass)return;const t=new Map;for(const s of e)t.set(s.uuid,s);for(const s of e)s.traverse(e=>{e.uuid!==s.uuid&&t.has(e.uuid)&&t.delete(e.uuid)});this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(e,t,s){const r=Math.max(1,Math.floor(t.clientWidth*s)),a=Math.max(1,Math.floor(t.clientHeight*s)),n=new i.WebGLRenderTarget(r,a);return n.texture.minFilter=i.NearestFilter,n.texture.magFilter=i.NearestFilter,n.texture.generateMipmaps=!1,n.stencilBuffer=!1,n.depthTexture=new i.DepthTexture(r,a),n.depthTexture.type=i.UnsignedShortType,n.depthTexture.minFilter=i.NearestFilter,n.depthTexture.magFilter=i.NearestFilter,n}static createAOMaskDepthRenderTarget(e,t){const s=Math.max(1,t.clientWidth*e.getPixelRatio()),r=Math.max(1,t.clientHeight*e.getPixelRatio()),a=new i.DepthTexture(s,r);a.type=i.UnsignedInt248Type,a.minFilter=i.NearestFilter,a.magFilter=i.NearestFilter;const n=new i.WebGLRenderTarget(s,r,{type:i.HalfFloatType,depthTexture:a});return n.texture.minFilter=i.NearestFilter,n.texture.magFilter=i.NearestFilter,n.texture.generateMipmaps=!1,n.stencilBuffer=!1,n}createSceneColorRenderTarget(e,t){const s=this.gRenderTarget.width,r=this.gRenderTarget.height,a=new i.WebGLRenderTarget(s,r,{count:2,type:i.FloatType,format:i.RGBAFormat,colorSpace:i.SRGBColorSpace,depthBuffer:!1,stencilBuffer:!1});return a.texture.minFilter=i.LinearFilter,a.texture.magFilter=i.LinearFilter,a.texture.generateMipmaps=!1,a.textures[1].minFilter=i.NearestFilter,a.textures[1].magFilter=i.NearestFilter,a}createGRenderTarget(){const e=this.container;null!=this.gRenderTarget&&this.gRenderTarget.dispose();const t=Math.max(1,e.clientWidth*this.renderer.getPixelRatio()),s=Math.max(1,e.clientHeight*this.renderer.getPixelRatio()),r=new i.DepthTexture(t,s);r.type=i.UnsignedIntType,r.minFilter=i.NearestFilter,r.magFilter=i.NearestFilter,this.gRenderTarget=new u(t,s,{count:3,minFilter:i.NearestFilter,magFilter:i.NearestFilter,type:i.HalfFloatType,format:i.RGBAFormat,depthTexture:r}),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(),P.clearSceneCache(this.scene)}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);t>=0&&this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}applyEnvMap(e){if(null!=this.scene.environment&&(e instanceof 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:et(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&&"receiveShadow"!==e&&!1===ot.includes(e)&&(t.value=r)}}updateLightUniformValues(e,t){const s=e.uniforms,i=t.uniforms;for(const e of ot){const t=i[e],r=s[e];null!=r&&null!=t&&(t.value=r.value)}}createGBufferMaterial(e,t){const s=t===je.opaque?this.gbufferMaterialCache:this.tbufferMaterialCache;let r=s.get(e);if(!0===e.userData.isGBufferMaterial)return e;if(null==r){let n=W.uv;if(e instanceof Ue&&null!=e.heightMap){const t=F("heightScale",e.heightScale??1);n=Fe(n,_(e.heightMap),t)}let o=V.normal;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=e.normalMap??Ve,s=F("useNormalMap",null!=e.normalMap?1:0),i=F("normalScale",e.normalScale?.x??1),r=R(_(t).sample(n),i);o=X(V.normal,r,s)}else e instanceof A&&null!=e.outputNormal&&(o=e.outputNormal);!0!==e.userData.disableAO&&(o=z("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=F("roughness",e.roughness??1),s=e.roughnessMap??Ge,i=F("useRoughnessMap",null!=e.roughnessMap?1:0),r=_(s).sample(n).g.multiply(t);l=X(t,r,i)}else e instanceof A&&null!=e.outputRoughness&&(l=e.outputRoughness);let h=null;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial){const t=e.lightMap??We,s=F("useLightMap",null!=e.lightMap?1:0),i=F("lightMapIntensity",e.lightMapIntensity??1),r=_(t).sample(n).rgb.multiplyScalar(i);h=X(E(0),r,s)}let u=C(0);if(e instanceof i.MeshStandardMaterial){const t=F("metalness",e.metalness??0),s=e.metalnessMap??We,i=F("useMetalnessMap",null!=e.metalnessMap?1:0),r=_(s).sample(n).b.multiply(t);u=X(t,r,i)}else e instanceof A&&e.outputRoughness;let c=null,p=C(1);if(e instanceof i.MeshStandardMaterial){const t=e.aoMap??Ge,s=F("useAoMap",null!=e.aoMap?1:0);p=F("aoMapIntensity",e.aoMapIntensity??1);const i=_(t).sample(n).r;c=X(C(1),i,s)}else e instanceof A&&e.outputRoughness;const f=F("opacity",e.opacity??1);let g=C(1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=e.alphaMap??Ge,s=F("useAlphaMap",null!=e.alphaMap?1:0),i=_(t).sample(n).r;g=X(C(1),i,s),g=g.multiply(f)}else e instanceof A&&null!=e.outputOpacity&&(g=e.outputOpacity);let M=L(0,1);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial||e instanceof i.MeshBasicMaterial){let t=B("color",(new i.Vector3).setFromColor(e.color));if(e.vertexColors){const e=G(z("USE_COLOR",Y(1,1,1),e=>new Q("color")));t=t.multiply(e)}const s=e.map??Ge,r=F("useAlbedoMap",null!=e.map?1:0),a=_(s).sample(n),o=a.multiply(L(t,1)),l=L(t,1);M=X(l,o,r);const h=X(C(1),a.w,r);g=g.multiply(h)}const v=!0===e.userData.hasBloom;let T=E(0);if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshToonMaterial||e instanceof i.MeshPhongMaterial){const t=B("emissive",(new i.Vector3).setFromColor(e.emissive)),s=F("emissiveIntensity",e.emissiveIntensity),r=e.emissiveMap??We,a=F("useEmissiveMap",null!=e.emissiveMap?1:0),o=_(r).sample(n).rgb.multiply(t);T=X(t,o,a),T=T.multiplyScalar(s)}else e instanceof A&&null!=e.outputEmissive&&(T=e.outputEmissive);const y=e instanceof d&&null!=e.uniforms[re],x=e instanceof d&&null!=e.uniforms[pe],b=e instanceof d&&null!=e.uniforms[ce],w=e.transparent&&e.alphaTest<=.01||e.blending===i.AdditiveBlending,P=F("alphaTest",e.alphaTest);let j,H=e.alphaTest>0?g.lt(P):w&&t===je.opaque?g.lt(.8):S(!1);!0===e.userData.isDecal&&(H=H.or(De)),j=w?q(0,0,0,0):(a=o,I(a).multiplyScalar(.5).addScalar(.5)).rgba(e.userData?.reflective?l:1);const $=e instanceof A?e.outputPosition:void 0,K=e instanceof A?e.outputTransform:void 0;let J,Z=L("black",1);if(e instanceof A&&null!=e.outputColor)Z=e.outputColor;else if(e instanceof i.MeshStandardMaterial)Z=U({color:M,metalness:u,roughness:l,emissive:T.rgb,normal:o,ambientOcclusion:c,ambientOcclusionIntensity:p,bakedLight:h});else if(e instanceof i.MeshLambertMaterial||e instanceof i.MeshPhongMaterial)Z=D({color:M.rgb});else if(e instanceof i.MeshBasicMaterial){let e=M.rgb,t=h??E("white");null!=c&&(t=t.multiplyScalar(c.subtract(1).multiply(p).add(1))),e=e.add(t),Z=e.rgba(g)}else e instanceof i.MeshToonMaterial&&(Z=O({color:M,emissive:T.rgb,normal:o,ambientOcclusion:c,ambientOcclusionIntensity:p,bakedLight:h}));(e instanceof A||e instanceof i.MeshStandardMaterial)&&(J=e.envMap);let ee=!0;(e instanceof m||e instanceof i.MeshBasicMaterial||e instanceof i.ShaderMaterial)&&(ee=e.fog);let te=L(Z.rgb,g);ee&&(te=new FogNode(te));let se=!0;if(t===je.opaque?(se&&(se=!y&&!x&&!b),se&&(se=!w)):t===je.transparent&&se&&(se=w||y||x||b),!se)return r=qe,s.set(e,r),r;r=new A({transform:K,position:null==K?$:void 0,outputs:[te,T.rgba(t===je.opaque?P:v?1:0),j],opacity:g,outputEncoding:!1,fog:ee,transparent:e.transparent,lights:!0,envMap:J,discard:H}),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),null!=r.uniforms[ce]&&(r.uniforms[ce].value=this.aoPass.pdRenderTarget.texture,r.defines.USE_SSAO_MAP="")),r.userData.mrtOutputs=3,r.forceSinglePass=e.forceSinglePass,r.side=e.side,r.blending=e.blending,w?(r.depthWrite=!e.transparent,r.depthTest=e.depthTest,r.colorWrite=t===je.transparent):(r.depthWrite=e.depthWrite,r.depthTest=e.depthTest),r.visible=e.visible,r.alphaTest=e.alphaTest,r.alphaHash=e.alphaHash,r.vertexColors=e.vertexColors,r.premultipliedAlpha=e.premultipliedAlpha,r.toneMapped=e.toneMapped,r.blendAlpha=e.blendAlpha,r.blendColor=e.blendColor,r.polygonOffset=e.polygonOffset,r.polygonOffsetFactor=e.polygonOffsetFactor,r.polygonOffsetUnits=e.polygonOffsetUnits,r.blending=e.blending,r.userData.isGBufferMaterial=!0,r.visible=se,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}updateCsm(){const e=this.csmUpdateInvervals;if(this.renderer.shadowMap.autoUpdate&&null!=this.csmCascadeLastUpdate&&Array.isArray(e)){const t=performance.now();for(let s=0;s<this.csm.lights.length;++s){const i=e[s]??e[e.length-1]??16;if(t-this.csmCascadeLastUpdate[s]>=i&&this.csm.lights[s].shadow){this.csm.lights[s].shadow.needsUpdate=!0,this.csmCascadeLastUpdate[s]=t;break}}}this.csm.update()}loop(e,t=!1){const s=this.stats,r=s.addPanel(new te.Panel("Calls","#83f","#002")),a=s.addPanel(new te.Panel("Triangles","#c32","#002"));let l;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(l=new fe(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,M=new n;let v=0;let T=this.paused;const y=t=>{const r=this.renderer.getContext();if(this.paused&&this.running&&r.drawingBufferHeight>1)return setTimeout(()=>y(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(He),t-=He;e(t)}else e(a);this.onLoopCallbacks.forEach(e=>e(a)),this.camera?.updateMatrixWorld(),M.copy(this.camera.matrixWorld),t-v>.08&&!M.equals(g)&&(this.renderer.shadowMap.needsUpdate=!0,v=t),this.updateCsm();let n=!1;c.length=0,p.length=0,m.length=0;const h=Xe;Qe.multiplyMatrices(this.camera.projectionMatrix,this.camera.matrixWorldInverse),h.setFromProjectionMatrix(Qe);let d=!1,x=!1,b=!1;this.scene.traverseVisible(e=>{if(this.setupCsm(e),this.outlineEffect.apply(e),e instanceof Ae&&(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[re])&&isObjectInFrustum(e,h)?(this.initDepthUniform(e.material),x=!0):e instanceof K&&(e.visible=!1,p.push(e)),(e instanceof o||e instanceof i.Sprite)&&e.material?.uniforms&&null!=e.material?.uniforms[ce]&&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[pe]&&isObjectInFrustum(e,h)&&(m.push(e),e.material.uniforms[pe].value=this.sceneColorRenderTarget.texture,b=!0),e instanceof o&&e.material?.uniforms&&null!=e.material?.uniforms[ue])e.material.uniforms[ue].value=t;else if(e instanceof o&&Array.isArray(e.material))for(const s of e.material)s.uniforms&&null!=s.uniforms[ue]&&(s.uniforms[ue].value=t)}),this.bloomPass.enabled=n,this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.clear(),this.renderScene(je.opaque),this.aoPass.output=se.OUTPUT.Off,(x||b)&&(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(y)},1e3/this.fpsCap):requestAnimationFrame(y))};!0===this.options.enableXR?this.renderer.setAnimationLoop(y):requestAnimationFrame(y)}applyGBufferMaterials(e){const t=this.gBufferCachedMaterials,s=this.gBufferCachedVisibility;t.clear(),s.length=0;ve(this.scene,i=>{if(it(i))return s.push(i),i.visible=!1,!1;if(i instanceof o){t.set(i,i.material);let r=!1;if(Array.isArray(i.material)){i.material=i.material.slice();for(let t=0;t<i.material.length;t++)i.material[t]=this.createGBufferMaterial(i.material[t],e),r||(r=i.material[t].visible),this.initShadowUniform(i,i.material[t])}else i.material=this.createGBufferMaterial(i.material,e),r||(r=i.material.visible),this.initShadowUniform(i,i.material);r?i.visible=!0:null!=i.children&&0!=i.children.length||(s.push(i),i.visible=!1)}})}unapplyGBufferMaterials(){this.gBufferCachedMaterials.forEach((e,t)=>{t.material=e}),this.gBufferCachedVisibility.forEach((e,t)=>{e.visible=!0,e.updateMatrixWorld(!0)})}initTextures(e=this.scene){e.traverse(e=>{if(e instanceof o)if(Array.isArray(e.material))for(let t=0;t<e.material.length;t++)this._initMaterialTextures(e.material[t]);else this._initMaterialTextures(e.material)})}_initMaterialTextures(e){if(!this._initiatedMaterialTextures.has(e))if(this._initiatedMaterialTextures.add(e),e instanceof d){for(const[t,s]of Object.entries(e.uniforms))if(s.value instanceof c){if(this._initiatedTextures.has(s.value))continue;this.renderer.initTexture(s.value),this._initiatedTextures.add(s.value)}}else for(const[t,s]of Object.entries(e))if(s instanceof c){if(this._initiatedTextures.has(s))continue;this.renderer.initTexture(s),this._initiatedTextures.add(s)}}async compileAsync(e=this.scene){if(this.compileInProgress)return;this.renderer.setRenderTarget(this.gRenderTarget),this.compileInProgress=!0,this.applyGBufferMaterials(je.opaque),await this.renderer.compileAsync(e,this.camera),this.unapplyGBufferMaterials(),this.applyGBufferMaterials(je.transparent),await this.renderer.compileAsync(e,this.camera),this.unapplyGBufferMaterials(),e===this.scene&&(this.renderer.setRenderTarget(this.gRenderTarget),this.renderer.compileAsync(this.fquadBlendAO.mesh,this.fquadBlendAO.camera),this.renderer.setRenderTarget(this.sceneColorRenderTarget),this.renderer.compileAsync(this.fquadCopyOpaque.mesh,this.fquadCopyOpaque.camera));const t=this.csm.lights[0]?.shadow.camera;null!=t&&(this.applyDepthMaterial(),await this.renderer.compileAsync(e,t),this.unapplyDepthMaterial()),this.compileInProgress=!1,this.renderer.setRenderTarget(null)}applyDepthMaterial(){const e=this.gBufferCachedMaterials;e.clear(),this.scene.traverse(t=>{(t.isMesh||t.isPoints||t.isLine||t.isSprite)&&(this.initCustomDepthMaterial(t),e.set(t,t.material),t.castShadow?null!=t.customDepthMaterial?t.material=t.customDepthMaterial:t.material=ht:t.material=null)})}unapplyDepthMaterial(){this.gBufferCachedMaterials.forEach((e,t)=>{t.material=e})}renderScene(e){if(!this.running||this.paused)return;if(this.compileInProgress)return void console.error("Compile in progress, skipping render");this.applyGBufferMaterials(e);const t=this.scene.matrixWorldAutoUpdate,s=this.scene.matrixAutoUpdate,i=this.renderer.shadowMap.autoUpdate;e!==je.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===je.opaque&&this.gBufferCachedMaterials.forEach((e,t)=>{!Array.isArray(e)&&!Array.isArray(t.material)&&e instanceof d&&this.updateLightUniformValues(t.material,e)}),this.unapplyGBufferMaterials(),this.renderer.shadowMap.autoUpdate=i,this.scene.matrixWorldAutoUpdate=t,this.scene.matrixAutoUpdate=s}getEnvTexture(e){null==this.pmremGenerator&&(this.pmremGenerator=new i.PMREMGenerator(this.renderer),this.pmremGenerator.compileEquirectangularShader());let t=this.pmremGeneratorResults.get(e);return null==t&&(t=this.pmremGenerator.fromEquirectangular(e).texture,this.pmremGeneratorResults.set(e,t)),t.colorSpace=i.SRGBColorSpace,t}applyPostProcessSettings(){if(0==this.postProcessVolumes.length)return this.lutPass.enabled=!1,void(this.colorPass.enabled=!1);var e;(e=this.postProcessSettings).tonemapMapping=void 0,e.tonemapExposure=1,e.envIntensity=1,e.envTexture=void 0,e.vignetteIntensity=0,e.colorTint=new i.Color("white"),e.colorTintIntensity=0,e.depthFocus=void 0,e.depthAperture=void 0,e.depthMaxBlur=void 0,e.temperature=6500,e.temperatureTint=0,e.lut=void 0,e.lutIntensity=0;const t=this.postProcessSettings;let s,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(!$e(e.object))continue;let l=e.blendWeight??1;const u=e.distanceToPoint(h);u>e.blendRadius||(e.blendRadius>0&&(l*=Te(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(!this.running)return;if(0===this.overlayCameras.size)return;const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.previousClientWith/2,s=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let i=0;i<e.length;i++)this.renderer.clearDepth(),this.renderer.setViewport(t-s/2+this.insetWidth*i+this.insetMargin*i,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[i])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){if(!this.running)return;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,Xe)&&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===Le.id)return;this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=Le:(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&&this.camera instanceof l&&(null!=e.uniforms[ne]&&(e.uniforms[ne].value=this.camera.near),null!=e.uniforms[ae]&&(e.uniforms[ae].value=this.camera.far))}initNormalUniform(e){e instanceof d&&null!=e.uniforms[le]&&(e.uniforms[le].value=this.gRenderTarget.textures[2])}initShadowUniform(e,t){var s;t instanceof A&&(t.uniforms.receiveShadow?(s=t.uniforms.receiveShadow).value||(s.value=e.receiveShadow):t.uniforms.receiveShadow={value:e.receiveShadow})}initResolutionUniform(e){e instanceof d&&null!=e.uniforms[oe]&&e.uniforms[oe].value.set(this.gRenderTarget.width,this.gRenderTarget.height)}initAoUniform(e){if(this.aoPass.enabled){e.uniforms[ce].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=Ce(Re);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}}};ze=e=t([ie(),s("design:paramtypes",[HTMLElement,Object])],ze);export{ze as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const He=.05;function $e(e){let t=e;for(;t;){if(!1===t.visible)return!1;t=t.parent}return!0}se.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 Xe=new i.Frustum,Ye=new i.Box3,Qe=new i.Matrix4;export function isObjectInFrustum(e,t){const s=Ye.setFromObject(e);return t.intersectsBox(s)}const Ke=new i.Vector3;const Je=new n,Ze=new p;function et(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(Je.makeRotationFromEuler(Ze))}const tt=new A({outputs:[q(0,0,0,0),q(0,0,0,0),L(E("white"),Oe(4))],transparent:!0}),st=new i.MeshBasicMaterial({color:"blue",transparent:!0,opacity:.5});tt.depthWrite=!1;new o(new i.BoxGeometry(4,4,4),st);function it(e){return e instanceof i.Sprite||e.isPoints||e.isLine||e.isLineSegments2||e.isTransformControls||e.isTransformControlsGizmo||e instanceof o&&rt(e,e.material)}function rt(e,t){return null==t||(Array.isArray(t)?t.some(t=>rt(e,t)):t instanceof i.RawShaderMaterial||t instanceof i.ShaderMaterial&&!(t instanceof A))}class at extends Ie{constructor(e,t,s){super(),this.scene=e,this.camera=t,this.gRenderTarget=s,this.cachedVisibility=[],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),this.cachedVisibility.length=0;let u=0;this.scene.traverseVisible(e=>{const t=it(e);e instanceof o&&!t?(this.cachedVisibility.push(e),e.visible=!1):t&&u++}),u>0&&e.render(this.scene,this.camera),this.cachedVisibility.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 nt extends Ie{constructor(e){super(),this.fn=e}render(e,t,s,i,r){this.fn(e,t,s,i,r)}}const ot=["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"],lt=B("fogColor");export class FogNode extends ${constructor(e,t=lt){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(F("fogFar")),n=e.get(F("fogNear")),o=e.get(F("fogDensity")),l=e.get(G(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}`}}}const ht=new i.MeshDepthMaterial({depthPacking:i.RGBADepthPacking});/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{AudioLoader as e,BufferGeometry as t,Group as s,LoadingManager as r,Mesh as i,Object3D as a,TextureLoader as n}from"three";import{GLTFLoader as o,MTLLoader as h,OBJLoader as l,DRACOLoader as c,LUTCubeLoader as u}from"three-stdlib";import{FBXLoader as d}from"three-stdlib";import{cloneMesh as m}from"../utils/mesh.js";import{pathJoin as f}from"../utils/files.js";import{Subject as p,firstValueFrom as g}from"rxjs";import{importCollisionShapes as w,isCollisionMesh as y}from"./collision/collision-shape-import.js";import*as x from"three";import{iterateMaterials as M}from"../utils/materials.js";import{BufferGeometryUtils as L,EXRLoader as b,KTX2Loader as A,TGALoader as v,UltraHDRLoader as _}from"three/examples/jsm/Addons.js";import{disposeScene as C}from"../utils/three/cleanup.js";const S=new c;S.setDecoderConfig({type:"js"}),S.setDecoderPath("/assets/draco/");const R=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new r,this.glbLoader=new o(this.loadingManager).setDRACOLoader(S),this.fbxLoader=new d(this.loadingManager),this.objLoader=new l(this.loadingManager),this.textureLoader=new n(this.loadingManager),this.tgaLoader=new v(this.loadingManager),this.exrLoader=new b(this.loadingManager),this.cubeLoader=new u(this.loadingManager),this.hdrLoader=new _(this.loadingManager),this.ktx2Loader=new A(this.loadingManager),this._textureLoader=new x.ImageBitmapLoader(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new p,this.ready=g(this.makeReady),this._texturePromises=new Map,this._animationPromises=new Map,this._animationCache=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}initKtx2(e){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.detectSupport(e)}setDataDir(e){this.basePath=f(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){const t=getElectronArg("windowId");return null!=t||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?f(this.basePath,e)+(null!=t?`?windowId=${t}`:""):new URL(f("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if(this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;if(await this.ready,this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);t.dispose(),null!=e.texture&&(t.flipY!==e.texture?.flipY?(t.needsUpdate=!0,t.flipY=e.texture?.flipY??!0):t.wrapS!==P(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=P(e.texture?.wrapS)):t.wrapT!==P(e.texture?.wrapT)&&(t.wrapT=P(e.texture?.wrapT),t.needsUpdate=!0))}else try{await this._getTextureLoader(e.fileKey).loadAsync(this.getUri(e.fileKey)).then(t=>(t.texture3D?t=t.texture3D:(t.wrapS=P(e.texture?.wrapS),t.wrapT=P(e.texture?.wrapT),t.flipY=e.texture?.flipY??!0),this.textureCache.set(e.id,t),this._retrievedTextures.push(t),t))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}return this.textureCache.get(e.id)}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){"mesh"===e.type&&Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)})}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new s,animations:[]};if(!R.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new s,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new s,animations:[]}}const a=this.cache.get(r).scene,n=this.computeCollisionShapes(e,a);!0===t?.mergeGeomtries&&this.optimizeDrawGroups(a);const o=m(a),h=this.cache.get(r).animations;o.traverse(e=>{e instanceof i&&e.material instanceof Array&&(e.material=e.material.slice())});const l=new AssetMeshInstance;l.add(o),l.collisionShapes=n,l.animations=h;const c=e.receiveShadow??!0,u=e.castShadow??!1;return o.traverse(e=>{e.castShadow=u,e.receiveShadow=c}),{scene:l,animations:h}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const s=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,s),s}async getAnimationClip(e){if(null==e||null==e.fileKey||null==!e.anim?.clip)return console.warn("Asset or animation clip name is not defined",e),null;const t=e.anim.clip,s=e.fileKey+"|"+t;if(this._animationCache.has(s))return this._animationCache.get(s);if(this._animationPromises.has(s))return this._animationPromises.get(s);const r=(async()=>{try{const r=await this.getMesh(e),i=r.animations.find(e=>e.name===t);return null!=i&&this._animationCache.set(s,i),i}catch(e){return this.onError(e),null}finally{setTimeout(()=>this._animationPromises.delete(s),1e3)}})();return this._animationPromises.set(s,r),r}computeCollisionShapes(e,t){const s=e.id+e.mesh?.collisions?.shapeType;return this.collisionShapeCache.has(s)||this.collisionShapeCache.set(s,w(t,e)),this.collisionShapeCache.get(s)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(e=>(e.scene.traverse(e=>{e instanceof i&&e.material,y(e)?e.visible=!1:e instanceof i&&e.geometry instanceof t&&(e.geometry.hasAttribute("normal")||e.geometry.computeVertexNormals())}),this._retrievedMeshes.push(e.scene),e.scene=function(e,t){let s=!1;if(t.traverseVisible(e=>{j.test(e.name)&&(s=!0)}),!s)return t;const r=new x.LOD,i=[t];for(;i.length>0;){const e=i.shift(),t=e.name.match(j);if(null!=t){const s=parseInt(t[1]);0===s?r.addLevel(e,0):console.warn(`Skipping LOD level ${s} for now as LOD is not fully supported`)}else i.push(...e.children)}return r}(0,e.scene),e))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid);let s=!0,r=0,a=0;if(e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){r++;const t=Object.keys(e.geometry.attributes).length;t!==a&&0!==a&&(s=!1),a=t}else(e instanceof x.SkinnedMesh||e instanceof x.Bone)&&(s=!1)}),r>1&&s){const s=new Map;e.updateWorldMatrix(!0,!0),e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){if(Array.isArray(e.material))return;e.updateWorldMatrix(!0,!0);const t=e.material?.uuid||"default";s.has(t)||s.set(t,{material:e.material,geometries:[],objects:[]});const r=s.get(t);r.geometries.push(e.geometry.clone().applyMatrix4(e.matrixWorld)),r.objects.push(e)}});for(const e of s.values())for(const t of e.objects)t.removeFromParent();for(const t of s.values()){let s;s=1===t.geometries.length?t.geometries[0]:L.mergeGeometries(t.geometries,!0),s.groups.length>1&&L.mergeGroups(s),e.add(new i(s,t.material))}}const n=[];e.traverse(e=>{e instanceof i&&e.geometry instanceof t&&Array.isArray(e.material)&&!y(e)&&n.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:t,geometry:s,materialArray:r,parent:a}of n){t.removeFromParent();for(let t=0;t<r.length;t++){const n=r[t],o=s.groups.filter(e=>e.materialIndex===t);if(0===o.length)continue;const h=this.extractGeometryGroups(s,o);h.groups.length>1&&L.mergeGroups(h);const l=new i(h,n);a?a.add(l):e.add(l)}s.dispose()}e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&L.mergeGroups(t)}})}extractGeometryGroups(e,s){const r=e.index;if(!r){const r=new t;let i=0;for(const e of s)i+=e.count;if(0===i)return r;for(const t in e.attributes){const a=e.attributes[t],n=a.itemSize,o=a.array,h=new(0,o.constructor)(i*n);let l=0;for(const e of s){const t=e.start*n,s=e.count*n;for(let e=0;e<s;e++)h[l+e]=o[t+e];l+=s}const c=new x.BufferAttribute(h,n,a.normalized);r.setAttribute(t,c)}return r.groups=[{start:0,count:i,materialIndex:0}],r}const i=[];for(const e of s)for(let t=0;t<e.count;t++){const s=r.getX(e.start+t);i.push(s)}if(0===i.length)return new t;const a=new Map,n=[];let o=0;for(const e of i)a.has(e)||(a.set(e,o),o++),n.push(a.get(e));if(0===n.length||0===a.size)return new t;const h=new t;for(const t in e.attributes){const s=e.attributes[t],r=s.itemSize,i=s.array,n=new(0,i.constructor)(a.size*r);for(const[e,t]of a)for(let s=0;s<r;s++)n[t*r+s]=i[e*r+s];const o=new x.BufferAttribute(n,r,s.normalized);h.setAttribute(t,o)}const l=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)l[e]=n[e];return h.setIndex(new x.BufferAttribute(l,1)),h.groups=[{start:0,count:n.length,materialIndex:0}],h}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(e=>({scene:e.scene,animations:e.animations}));case"fbx":return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new h;t.materialOptions={normalizeRGB:!1};const s=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(s)}return this.objLoader.loadAsync(t).then(e=>(T(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>C(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}function T(e){if(e instanceof i)for(const t of M(e.material))t instanceof x.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach(T)}export class AssetMeshInstance extends a{}export function getElectronArg(e){const t=`--${e}=`,s=window.process?.argv.find(e=>e.startsWith(t));return s?.substring(t.length)}function P(e){switch(e){case"clamp":return x.ClampToEdgeWrapping;case"repeat":return x.RepeatWrapping;case"mirror":return x.MirroredRepeatWrapping}return x.RepeatWrapping}new x.Matrix4;const j=/_LOD(\d+)$/;/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import*as t from"three";function e(t,e){return e.z-t.z}export class BatchedMesh2 extends t.BatchedMesh{constructor(){super(...arguments),this.uniformTextures={},this.uniformSize={},this.customSort=(t,
|
|
2
|
-
* Copyright (©)
|
|
1
|
+
import*as t from"three";function e(t,e){return t.z-e.z}function r(t,e){return e.z-t.z}export class BatchedMesh2 extends t.BatchedMesh{constructor(){super(...arguments),this.uniformTextures={},this.uniformSize={},this.customSort=(t,i)=>{this.material.transparent?t.sort(r):t.sort(e)}}initUniform(e,r,i=0){if(r<1||r>4||3===r)throw"Element size must be between 1,2, or 4";let s=Math.sqrt(this.maxInstanceCount);s=Math.ceil(s);let o=t.RedFormat;2===r?o=t.RGFormat:4===r&&(o=t.RGBAFormat);const n=new Float32Array(s*s*r).fill(i),a=new t.DataTexture(n,s,s,o,t.FloatType);this.uniformTextures[e]=a,this.uniformSize[e]=r;const u=this.material;if(!(u instanceof t.ShaderMaterial))throw"Can not use custom uniforms with other materials than ShaderMaterial";for(const[t,e]of Object.entries(this.uniformTextures))u.uniforms[t]={value:e};u.uniformsNeedUpdate=!0}setUniformAt(e,r,i){const s=this.uniformTextures[e],o=s.image.data,n=this._drawInfo;if(r>=n.length||!1===n[r].active)return this;"number"==typeof i?o[r*this.uniformSize[e]]=i:i.toArray(o,r*this.uniformSize[e]),s.needsUpdate=!0;const a=this.material;a instanceof t.ShaderMaterial&&(a.uniformsNeedUpdate=!0)}getUniformAt(e,r,i){const s=this.uniformTextures[e].image.data,o=this._drawInfo;return r>=o.length||!1===o[r].active?null:1===this.uniformSize[e]?s[r]:void((i instanceof t.Vector2||i instanceof t.Vector2||i instanceof t.Vector3||i instanceof t.Vector4||i instanceof t.Color)&&i.fromArray(s,r*this.uniformSize[e]))}dispose(){super.dispose();for(const t of Object.values(this.uniformTextures))t.dispose();return this.uniformTextures=null,this}}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
package/dist/scene/bootstrap.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{polyfill as e}from"../utils/polyfill.js";import{SceneDataService as t}from"./scene-data-service.js";import{SceneMaterializer as i}from"./materializer.js";import{basicSceneSetup as n}from"./sky.js";export async function loadScene(a,r,s,o,c,m,l,p,d,f,w){e();const{scene:j,renderer:u,camera:y}=a;n(j);const S=await p.getScene(r);if(null==S)throw Error(`Could not find scene with name ${r}`);const b=await p.getSceneData(S.id),g=new t;g.initiate(b);const h=Object.entries(o).map(([e,t])=>({name:e,type:t})),v=Object.entries(c).map(([e,t])=>({name:e,type:t})),O=Object.entries(m).map(([e,t])=>({name:e,type:t})),z=new i(j,g,d,f,a,h,v,l,O);return z.inEditor=!1,z.detailTier=w.detailTier,await z.initWithInstancing(),{scene:j,view:a,materializer:z,assetResourceLoader:f,assetsService:d,actors:z.actorInstances}}/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{Box3 as e,Mesh as t,Quaternion as n,Vector3 as s}from"three";import{BoxCollisionShape as i,CollisionShapeSource as o,ConvexPolyhedronCollisionShape as r,SphereCollisionShape as a,TrimeshCollisionShape as m}from"./collision-shape.js";new n;export function importCollisionShapes(n,l){let c=l.mesh?.collisions?.shapeType;if(null==c){let e=!1;n.traverse(n=>{(n instanceof t||n.isMesh)&&isCollisionMesh(n)&&(e=!0)}),c=e?"imported":"convex"}const u=[];return n.traverse(n=>{if(n instanceof t||n.isMesh){let t;"imported"===c?t=function(t){if(t.name.startsWith(h.convex))return new r(t);if(t.name.startsWith(h.box)){const n=t.clone();n.quaternion.set(0,0,0,1),n.updateMatrixWorld();const o=(new e).setFromObject(n);return isFinite(o.min.lengthSq())?new i(new s(o.max.x-o.min.x,o.max.y-o.min.y,o.max.z-o.min.z)):null}if(t.name.startsWith(h.sphere)){t.geometry.computeBoundingSphere();const e=t.geometry.boundingSphere.radius*Math.max(t.scale.x,t.scale.y,t.scale.z);return new a(e)}if(t.name.startsWith(h.trimesh))return new m(t.geometry)}(n):"convex"===c?t=new r(n):"mesh"===c&&(t=new m(n.geometry)),null!=t&&(t.source="imported"!==c?o.rendered:o.custom,t.offset=n.getWorldPosition(new s),u.push(t),isCollisionMesh(n)&&(n.visible=!1))}}),u}export function isCollisionMesh(e){return e.name.startsWith(h.convex)||e.name.startsWith(h.box)||e.name.startsWith(h.sphere)||e.name.startsWith(h.trimesh)}var h;!function(e){e.convex="UCX_",e.box="UBX_",e.sphere="USP_",e.trimesh="UTM_"}(h||(h={}));new e;/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{Euler as s,Mesh as e,Vector3 as t}from"three";export var CollisionShapeSource;!function(s){s[s.custom=0]="custom",s[s.rendered=1]="rendered"}(CollisionShapeSource||(CollisionShapeSource={}));export class CollisionShape{constructor(){this.offset=new t,this.rotation=new s}withCollisionGroup(s){return this.collisionGroup=s,this}withRestitution(s){return this.restitution=s,this}withOffset(s){return this.offset.copy(s),this}withRotation(s){return this.rotation.copy(s),this}withDensity(s){return this.density=s,this}withMass(s){return this.mass=s,this}withFriction(s){return this.friction=s,this}static box(s){return new BoxCollisionShape(s)}static plane(s,e){return new PlaneCollisionShape(s,e)}static sphere(s){return new SphereCollisionShape(s)}static cylinder(s,e,t,i,o){return new CylinderCollisionShape(s,e,t,i,o)}static cone(s,e){return new ConeCollisionShape(s,e)}static convexPolyhedron(s){return new ConvexPolyhedronCollisionShape(s)}static trimesh(s){return new TrimeshCollisionShape(s)}static mesh(s){return new MeshCollisionShape(s)}static capsule(s,e){return new CapsuleCollisionShape(s,e)}}export class BoxCollisionShape extends CollisionShape{constructor(s){super(),this.dimensions=s}}export class PlaneCollisionShape extends CollisionShape{constructor(s,e){super(),this.width=s,this.height=e}}export class SphereCollisionShape extends CollisionShape{constructor(s){super(),this.radius=s}}export class CylinderCollisionShape extends CollisionShape{constructor(s,e,t,i,o){super(),this.radiusTop=s,this.radiusBottom=e,this.height=t,this.segments=i,this.orentation=o}}export class ConeCollisionShape extends CollisionShape{constructor(s,e){super(),this.radiusBottom=s,this.height=e}}export class ConvexPolyhedronCollisionShape extends CollisionShape{constructor(s){super(),this.mesh=s}}export class TrimeshCollisionShape extends CollisionShape{constructor(s){super(),this.geometry=s}}export class MeshCollisionShape extends CollisionShape{constructor(s){super(),this.geometry=s}}export class CapsuleCollisionShape extends CollisionShape{constructor(s,e){super(),this.length=s,this.radius=e}}export class PhysicalShapeMesh extends e{constructor(s,e,t,i){super(s,e),this.collisionShape=t,this.physics=i,this.isPhysicalShapeMesh=!0}}/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{Subject as e,debounceTime as t}from"rxjs";import{Box3 as s,BufferAttribute as n,InstancedMesh as o,MathUtils as a,Matrix4 as i,Mesh as r,MeshStandardMaterial as c,PerspectiveCamera as l,PlaneGeometry as h,ShaderMaterial as u,Triangle as f,Vector2 as m,Vector3 as p}from"three";import{materialFromAsset as d}from"../../scene/materializer.js";import{getMaterialAttribute as w}from"../../scene/materials/utils/material-painting";import{whenIdle as g}from"../../utils/async.js";import{indexBy as y}from"../../utils/collections.js";import{meanVectors3withWeight as M}from"../../utils/math.js";import{LandscapeMesh as b,defaultLandscapeMaterial as x}from"./landscape.js";import{smoothNormalsCrossMeshes as S}from"./utils.js";export const grassGeometryTriangleLimit=400;new p,new p;const A=new p,v=new p,z=new p;export class LandscapeManager{constructor(s,n,o,a,r,c,l){this.view=n,this.landscape=o,this.assetManagerService=a,this.assetService=r,this.shaders=c,this.applyMaterial=l,this.scatterMeshes=new Map,this.loadedScatterSquares=new Set,this.refreshRequests=new e,this.defaultLandscapeMaterial=x.clone(),this.scatterMeshPool=[],this.onLoopHandler=()=>this.update(),this.sectionCache=new Map,this._matrix=new i,this.scatterGeometryCache=new Map,this._lastUpdatePosition=new p,this._cameraPosition=new p,this.source=JSON.parse(JSON.stringify(s)),this.view.onLoop(this.onLoopHandler),this.defaultLandscapeMaterial.name=x.name,this.defaultLandscapeMaterial.color=x.color,this.refreshRequests.pipe(t(500)).subscribe(e=>this.refreshScatter(e.origin,e.force,e.predicate))}updateSource(e){this.source=JSON.parse(JSON.stringify(e))}updateShaders(e){this.shaders=e}async loadGrass(){const e=await this.assetService.getAsset("6ij937n72g");await this.assetManagerService.getMesh(e);this.grassGeometry=new h(2,2,3,3);const t=this.grassGeometry.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0,this.grassMaterial=new c({color:3765785})}refreshGeometry(){const e=this.source.landscape.options,t=(new p,new p);this.view.camera.getWorldPosition(t);const s=[];z.fromArray(this.source.position);const n=this.view.camera instanceof l?Math.min(this.view.camera.far,1e3):1e3,o=1.1*n,a=e.sections.y*e.sectionSize/-2,i=e.sections.x*e.sectionSize/-2;for(let r=0;r<e.sections.x;r++)if(A.x=i+r*e.sectionSize,!(Math.abs(t.x-A.x)>o))for(let c=0;c<e.sections.y;c++){A.z=a+c*e.sectionSize,v.copy(z).add(A);const l=v.distanceTo(t),h=`${r},${c}`,u=this.landscape.sections.find(e=>e.x===r&&e.y===c);if(l<=n){if(null==u){this.sectionCache.has(h)||this.sectionCache.set(h,this.createLandscapeMesh(this.source,e,i,a,r,c));const t=this.sectionCache.get(h);this.applyMaterial(t),this.landscape.add(t),s.push(t)}}else l>o&&this.landscape.remove(u)}S(s)}applyHeightMap(e,t,s,n=1){const o=Math.pow(s+1,2),a=e.getAttribute("position");if(1===n)for(const e of t.points)a.setY(e.i,e.y);else{const e=y(t.points??[],e=>e.i);for(let t=0;t<a.count;t++){const s=P(t,a.count,o);let n=0;n=s%1==0?e.get(s)?.y??0:Math.floor(e.get(s)?.y),a.setY(t,n)}}a.needsUpdate=!0,e.computeVertexNormals()}deleteOldScatterMeshes(){const e=new Set;for(const[t,s]of this.source.grass?.layers.entries()??[])for(const[n,o]of s.meshes.entries()){const s=`${t}-${n}`;e.add(s)}for(const t of this.scatterMeshes.keys())if(!e.has(t)){this.scatterMeshes.get(t).forEach(e=>{e.parent?.remove(e),e.dispose()}),this.scatterMeshes.delete(t)}}queueRefreshScatter(e,t=!1,s=()=>!0){this.refreshRequests.next({origin:e,force:t,predicate:s})}async refreshScatter(e,t=!1,s=()=>!0){t&&this.scatterGeometryCache.clear(),this.deleteOldScatterMeshes();for(const[n,i]of this.source.grass?.layers.entries()??[])for(const[c,l]of i.meshes.entries()){const i=`${n}-${c}`;this.scatterMeshes.has(i)||this.scatterMeshes.set(i,new Map);const h=this.scatterMeshes.get(i),u=await this.assetService.getAsset(l.assetId);if(null==u){console.error(`Can not find asset with id ${l.assetId}`);continue}let m;try{m=await this.assetManagerService.getMesh(u)}catch(e){console.error(`Failed to load mesh in landscape manager for asset with name ${u.name}`,e);continue}const w=[];if(m.scene.traverse(e=>{e instanceof r&&w.push(e)}),1!==w.length){console.log(m),console.warn("Dynamic grass only works for meshes with a single geometry.");continue}if(!(w[0]instanceof r)){console.warn("Only meshes can be used for dynamic grass. Found:",m.scene);continue}const b=w[0];let x=b.geometry;if(this.scatterGeometryCache.has(b.geometry.uuid))x=this.scatterGeometryCache.get(b.geometry.uuid);else if(x=b.geometry.clone(),!0===l.normalsUp&&F(x),this.scatterGeometryCache.set(b.geometry.uuid,x),null==x.userData.updatedMatrix){m.scene.updateMatrixWorld(),x.applyMatrix4(b.matrixWorld),x.userData.updatedMatrix=!0;const e=u.mesh?.rescale??1;1!==e&&x.scale(e,e,e)}const S=x.getIndex()??x.getAttribute("position"),A=null!=S?S.count/3:0;if(A>400){console.warn(`The triangle count of ${u.name} is too big ${A}. Keep it below 400`);continue}const v=null!=u.materialAssignments&&u.materialAssignments.length>0?u.materialAssignments[0].materialId:null,z=null!=v&&"null"!==v?await d(await this.assetService.getAsset(v),null,this.assetService,this.assetManagerService,this.shaders,!1):null;let P=null!=z?z:b.material;if(Array.isArray(P))for(const e of P)e.userData.disableAO=!0;else P.userData.disableAO=!0;const L=a.degToRad(l.maxSlope??90),T=Math.cos(L),_=this.landscape.sections,D=_.filter($(e,l.viewDistance)),q=D.filter(e=>!h.has(e.uuid)||t).filter(e=>s(e));_.filter(O(e,2*l.viewDistance)).forEach(e=>{const t=h.get(e.uuid);null!=t&&(t.visible=!1)});for(const e of D){const t=h.get(e.uuid);null!=t&&(t.visible=!0)}performance.now();const I=this.source.landscape.options,U=I.sectionSize,k=l.density??1??1,H=I.density,X=U/H,Y=k,E=X/Math.sqrt(Y),J=Math.pow(H,2),Z=E/X,K=Math.floor(J*Y),V=[0,0,0];for(const e of q)await g(async()=>{e.updateWorldMatrix(!0,!1);const s=this._matrix,a=new p,i=e.geometry.getAttribute("position"),r=e.geometry.getAttribute("normal"),c=(this.source.vertexMaterials??[]).filter(t=>t.m===e.name),u=y(c,e=>e.i);let m=h.get(e.uuid);if(null==m||m.count==K&&!t||(m.parent?.remove(m),this.scatterMeshPool.push(m),h.delete(e.uuid),m=null),null==m){const e=this.scatterMeshPool.findIndex(e=>e.count>=K);e>-1?(m=this.scatterMeshPool[e],m.geometry=x,m.material=P,this.scatterMeshPool.splice(e,1)):m=new o(x,P,K),m.raycast=()=>{},m.receiveShadow=!0}m.visible=!0;const d=new f(new p,new p,new p);let[w,g,b,S]=[new p,new p,new p,new p],[A,v,z]=[[],[],[]],[L,O,$]=[new p,new p,new p,new p];const _=new p,D=new p,q=new p,I=new p,U=new f(new p,new p,new p),k=new f(new p,new p,new p),F=new f(new p,new p,new p),X=new f(new p,new p,new p);let E=0;e:for(let t=0;t<J;t++){const o=Math.floor(t/H);w.fromBufferAttribute(i,t+o),I.copy(w).applyMatrix4(e.matrixWorld),U.a.copy(w),U.b.fromBufferAttribute(i,t+1+o),U.c.fromBufferAttribute(i,t+H+1+o),k.a.copy(U.b),k.b.copy(U.c),k.c.fromBufferAttribute(i,t+H+2+o),F.a.fromBufferAttribute(r,t+o),F.b.fromBufferAttribute(r,t+1+o),F.c.fromBufferAttribute(r,t+H+1+o),X.a.copy(F.b),X.b.copy(F.c),X.c.fromBufferAttribute(r,t+H+2+o);const c=[];c[0]=u.get(t+o)?.w,c[1]=u.get(t+1+o)?.w,c[2]=u.get(t+H+1+o)?.w,c[3]=u.get(t+H+2+o)?.w;let h=0;for(let e=0;e<=1+Z;e+=Z)for(let t=0;t<=1+Z;t+=Z){if(E>K)break e;if(h++,h>Y)continue e;1-e>t?(g=U.a,b=U.b,S=U.c,L=F.a,O=F.b,$=F.c,A=c[0],v=c[1],z=c[2]):(g=k.a,b=k.b,S=k.c,L=X.a,O=X.b,$=X.c,A=c[1],v=c[2],z=c[3]),d.a.copy(g),d.b.copy(b),d.c.copy(S),C(d),_.set(w.x,0,w.z),R(d,_),d.getBarycoord(_,a).toArray(V),G[0]=A,G[1]=v,G[2]=z;if(j(G,V,.2)!==n-1)continue;if(M([g,b,S],V,D),M([L,O,$],V,q),null!=l.maxSlope&&l.maxSlope<90&&q.y<T)continue;const o=D;o.y+=B(l.offsetMin,l.offsetMax);const i=B(l.scaleMin??1,l.scaleMax??1);s.makeScale(i,i,i);const r=s.elements;r[12]=o.x,r[13]=o.y,r[14]=o.z,!1!==l.randomRotation&&N(s,i),l.alignToNormal&&W(s,o,m.matrixWorld,q);const u=m.instanceMatrix.array,f=16*E;u[f]=r[0],u[f+1]=r[1],u[f+2]=r[2],u[f+3]=r[3],u[f+4]=r[4],u[f+5]=r[5],u[f+6]=r[6],u[f+7]=r[7],u[f+8]=r[8],u[f+9]=r[9],u[f+10]=r[10],u[f+11]=r[11],u[f+12]=r[12],u[f+13]=r[13],u[f+14]=r[14],u[f+15]=r[15],E++}}m.count=E,m.instanceMatrix.needsUpdate=!0,m.position.copy(e.position),m.updateMatrix(),h.has(e.uuid)||this.landscape?.add(m),h.set(e.uuid,m),m.userData.meshConfig=l});performance.now()}}stop(){this.view.removeOnLoop(this.onLoopHandler)}update(){this.view.camera&&(this.view.camera.getWorldPosition(this._cameraPosition),this._cameraPosition.distanceTo(this._lastUpdatePosition)>10&&(this._lastUpdatePosition.copy(this._cameraPosition),this.refreshGeometry(),this.refreshScatter(this._cameraPosition)))}clear(){this.scatterMeshes.forEach(e=>e.forEach(e=>e.parent?.remove(e)))}createLandscapeMesh(e,t,s,n,o,a){const i=new h(t.sectionSize,t.sectionSize,t.density,t.density);i.rotateX(Math.PI/-2);const r=this.defaultLandscapeMaterial,c=new b(i,r);c.position.x=s+o*t.sectionSize,c.position.z=n+a*t.sectionSize,c.receiveShadow=!0,c.castShadow=!1,c.userData.landscape={x:o,y:a},c.x=o,c.y=a,c.name=`${o},${a}`,w(c,0,!0),w(c,4,!0);const l=e.landscape.heightMaps.find(e=>e.x===o&&e.y===a);if(null!=l&&this.applyHeightMap(i,l,t.density,1),i.computeTangents(),i.computeBoundsTree(),null!=e.landscape.holes&&e.landscape.holes.length>0){const t=getHoleAttribute(c,!0);for(const s of e.landscape.holes)s.m===c.name&&t.setX(s.i,s.w[0])}return c}}export function getHoleAttribute(e,t=!1){if(!e.geometry.hasAttribute("hole")||t){const t=new Float32Array(e.geometry.getAttribute("position").array.length);e.geometry.setAttribute("hole",new n(t,1))}return e.geometry.getAttribute("hole")}function P(e,t,s){const n=Math.sqrt(t),o=Math.floor(e/n)/(n-1),a=e%n/(n-1),i=Math.sqrt(s);return(s-1)*o-(i-1)*o+(i-1)*a}new Map,new m(0,0),new m(1,0),new m(0,1),new m(1,0),new m(0,1),new m(1,1),new p;const L=new s;function O(e,t){return function(s){return L.setFromObject(s).distanceToPoint(e)>t}}function $(e,t){return function(s){return L.setFromObject(s).distanceToPoint(e)<t}}function C(e){e.a.y=0,e.b.y=0,e.c.y=0}const G=[];function j(e,t,s=.5){const n=G;let o=-1,a=-1;for(let e=0;e<n.length;e++)if(null!=n[e])for(let i=0;i<n[e].length;i++){const r=n[e][i]*t[e];r>s&&r>a&&(a=r,o=i)}return o}function B(e,t){let s=t-e,n=D();return n*=s,n+=e,n}const T=[];let _=1e3;for(;_--;)T.push(Math.random());function D(){return++_>=T.length?T[_=0]:T[_]}const q=[];let I=20;for(;I--;)q.push((new i).makeRotationY(D()*Math.PI/2));function R(e,t){let s=D(),n=D();s+n>1&&(s=1-s,n=1-n);const o=e.a,a=e.b,i=e.c;t.x=o.x+s*(a.x-o.x)+n*(i.x-o.x),t.z=o.z+s*(a.z-o.z)+n*(i.z-o.z)}new p;new p;const U=new p,k=new p(0,1,0),H=(new i).makeRotationX(Math.PI/-2);function W(e,t,s,n){e.lookAt(U,n,k).multiply(H)}new i;function N(e,t=1){const s=(++I>=q.length?q[I=0]:q[I]).elements,n=e.elements;n[0]=s[0]*t,n[4]=s[4]*t,n[8]=s[8]*t,n[1]=s[1]*t,n[5]=s[5]*t,n[9]=s[9]*t,n[2]=s[2]*t,n[6]=s[6]*t,n[10]=s[10]*t}function F(e){const t=e.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.normalized=!0,t.needsUpdate=!0}/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{Group as e,Mesh as a}from"three";import{Color as r}from"three";import{varyingAttributes as t,float as n,mod as o,dot as s,vec2 as c,step as i,fract as l,mix as p,rgb as d,NodeShaderMaterial as f,rgba as u,standardMaterial as m,attributeFloat as h,RgbNode as L,varying as x}from"three-shader-graph";import{mixColorsByLayer as S,select as w}from"../../shader-nodes/index.js";export function initLandscape(e){e.sections.y,e.sectionSize,e.sections.x,e.sectionSize;return new LandscapeGroup}export function createLandscapeDefaultMaterial(e=!0){const a=t.uv,L=n(10),w=n(7),v=o(s(c(1,1),i(c(.5,.5),l(a.multiplyScalar(L)))),n(2)),y=o(s(c(1,1),i(c(.5,.5),l(a.multiplyScalar(w.multiply(L))))),n(2)),D=p(d(new r(4473924).convertLinearToSRGB()),d(new r(5592405).convertLinearToSRGB()),v),G=p(D,D.addScalar(n(.1)),y),M=S({layerColors:[u(G).rgb,...["#f3cc91","#e9a135","#f4a4a6","#ef767a","#e6373d","#55DDE0","#33658A","#2F4858"].map(e=>new r(e).convertLinearToSRGB()).map(e=>d(e)).reverse()],enableNoise:!1}),g=h("hole"),B=new f({color:m({color:e?M:G}),discard:x(g).gt(.5)});return B.color=new r("#aaaaaa"),B.name="Default",B}export const defaultLandscapeMaterial=createLandscapeDefaultMaterial();export class LandscapeMesh extends a{}export class LandscapeGroup extends e{get sections(){return this.children.filter(e=>e instanceof LandscapeMesh)}}/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{Vector3 as e}from"three";export function smoothNormalsCrossMeshes(t){const r=new SectionGrid(t);performance.now();const n=new e,o=new e,i=new e,s=new e;for(const e of t){const t=e.geometry.getAttribute("position"),c=e.geometry.getAttribute("normal");for(const d of u(t.count)){const{otherMesh:u,j:a}=f(d,t.count,e,r);if(null==u)continue;n.fromBufferAttribute(t,d),n.applyMatrix4(e.matrixWorld);const x=u.geometry.getAttribute("position"),h=u.geometry.getAttribute("normal");u.updateMatrixWorld(),o.fromBufferAttribute(x,a),o.applyMatrix4(u.matrixWorld),i.fromBufferAttribute(c,d),s.fromBufferAttribute(h,a);const m=i.add(s).divideScalar(2);c.setXYZ(d,m.x,m.y,m.z),h.setXYZ(a,m.x,m.y,m.z),c.needsUpdate=!0,h.needsUpdate=!0;const l=(t.getY(d)+x.getY(a))/2;t.setY(d,l),x.setY(a,l)}}performance.now()}export class SectionGrid{constructor(e){this.grid=new Map;for(const t of e){const{x:e,y:r}=t;this.grid.has(e)||this.grid.set(e,new Map),this.grid.get(e).set(r,t)}}find(e,t){return this.grid.get(e)?.get(t)}}const t={meshPredicate:(e,t)=>e.find(t.x,t.y-1),vertexFunc:(e,t)=>e+t*(t-1)},r={meshPredicate:(e,t)=>e.find(t.x-1,t.y-1),vertexFunc:(e,t)=>t*t-1},n={meshPredicate:(e,t)=>e.find(t.x+1,t.y-1),vertexFunc:(e,t)=>t*t-t},o={meshPredicate:(e,t)=>e.find(t.x,t.y+1),vertexFunc:(e,t)=>e-t*(t-1)},i={meshPredicate:(e,t)=>e.find(t.x-1,t.y+1),vertexFunc:(e,t)=>t-1},s={meshPredicate:(e,t)=>e.find(t.x+1,t.y+1),vertexFunc:(e,t)=>0},c={meshPredicate:(e,t)=>e.find(t.x-1,t.y),vertexFunc:(e,t)=>e+t-1},d={meshPredicate:(e,t)=>e.find(t.x+1,t.y),vertexFunc:(e,t)=>e-t+1};function f(e,f,u,a){const x=Math.sqrt(f),h=(e+1)%x===0,m=e%x===0;let l;if(e<x?(l=t,m&&(l=r),h&&(l=n)):e>=f-x?(l=o,m?l=i:h&&(l=s)):m?l=c:h&&(l=d),null==l)return{otherMesh:null,j:null};return{otherMesh:l.meshPredicate(a,u),j:l.vertexFunc(e,x)}}function*u(e){const t=Math.sqrt(e);for(let r=0;r<t;r++)yield r,yield r+e-t;for(let e=1,r=t-1;e<r;e++)yield e*t,yield e*t+t-1}export function onEdge(e,t){const r=Math.sqrt(t);return e<r||e%r===0||e>=t-r||(e+1)%r===0}/*
|
|
2
|
-
* Copyright (©)
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -310,6 +310,11 @@ export declare class SceneMaterializer {
|
|
|
310
310
|
private initTextures;
|
|
311
311
|
private prefetchAssets;
|
|
312
312
|
init(): Promise<void>;
|
|
313
|
+
/**
|
|
314
|
+
* Materialize visual effects to upload textures
|
|
315
|
+
* and compile shaders before they are first used.
|
|
316
|
+
*/
|
|
317
|
+
private initVfx;
|
|
313
318
|
/**
|
|
314
319
|
* Actors are initialized after first created during materialization because
|
|
315
320
|
* they need to exist to be able to refer to each other.
|