{"version":3,"file":"index.mjs","sources":["../src/plugins/buffer/shaders/VelocityBufferPlugin.unpack.glsl","../src/utils/shaders.ts","../src/utils/shaders/computeScreenSpaceVelocity.glsl","../src/utils/shaders/getWorldPositionFromViewZ.glsl","../src/utils/shaders/temporalaa.glsl","../src/utils/shaders/ssreflection.glsl","../src/utils/shaders/ssrtao.glsl","../src/plugins/postprocessing/TemporalAAPlugin.ts","../src/plugins/buffer/VelocityBufferPlugin.ts","../src/plugins/buffer/shaders/VelocityBufferPlugin.mat.vert.glsl","../src/plugins/buffer/shaders/VelocityBufferPlugin.mat.frag.glsl","../src/plugins/postprocessing/BloomPlugin.ts","../src/plugins/postprocessing/shaders/hdrBloom.glsl","../src/plugins/postprocessing/DepthOfFieldPlugin.ts","../src/plugins/postprocessing/shaders/dofCombine.glsl","../src/plugins/postprocessing/shaders/dofComputeCoC.glsl","../src/plugins/postprocessing/shaders/dofExpandCoC.glsl","../src/plugins/postprocessing/shaders/ssrt.glsl","../src/plugins/postprocessing/SSContactShadowsPlugin.ts","../src/plugins/postprocessing/shaders/samplePointHelpers.glsl","../src/plugins/postprocessing/SSReflectionPlugin.ts","../src/plugins/postprocessing/OutlinePlugin.ts","../src/plugins/postprocessing/shaders/outline.glsl","../src/plugins/postprocessing/shaders/outlineDepthVert.glsl","../src/plugins/postprocessing/shaders/outlineDepthFrag.glsl","../src/passes/BilateralFilterPass.ts","../src/plugins/postprocessing/SSGIPlugin.ts","../src/plugins/extras/AnisotropyPlugin.ts","../src/plugins/extras/shaders/anisotropyTBN.glsl","../src/utils/Reflector2.ts","../node_modules/rand-seed/dist/es/index.js","../src/utils/RandomizedDirectionalLight.ts","../src/utils/FSShadowMaterial.ts","../src/utils/ShadowMapBaker.ts","../src/utils/shaders/seperableShadowBlur.glsl","../src/plugins/extras/AdvancedGroundPlugin.ts","../src/plugins/extras/WatchHandsPlugin.ts","../src/plugins/index.ts"],"sourcesContent":["#if defined(HAS_VELOCITY_BUFFER)\nuniform sampler2D tVelocity;\nvec2 getVelocity(const in vec2 uv) {\n    vec2 screenSpaceVelocity = texture2D(tVelocity, uv).xy * 2.0 - 1.0;\n    return sign(screenSpaceVelocity) * pow(abs(screenSpaceVelocity), vec2(4.));\n}\n#endif\n\n","import computeScreenSpaceVelocity from './shaders/computeScreenSpaceVelocity.glsl'\nimport getWorldPositionFromViewZ from './shaders/getWorldPositionFromViewZ.glsl'\nimport temporalaa from './shaders/temporalaa.glsl'\nimport ssreflection from './shaders/ssreflection.glsl'\nimport ssrtao from './shaders/ssrtao.glsl'\nimport {RenderManager} from \"threepipe\";\n\nconst shadersUtils2 = {\n    computeScreenSpaceVelocity: computeScreenSpaceVelocity,\n    getWorldPositionFromViewZ: getWorldPositionFromViewZ,\n    temporalAA: temporalaa,\n    ssReflection: ssreflection,\n    calculateGI: ssrtao,\n\n    ['__inited']: false,\n}\n\nexport function getShaders(){\n    if(!shadersUtils2.__inited){\n        shadersUtils2.__inited = true\n        Object.assign(RenderManager.ShaderChunk, shadersUtils2)\n    }\n    return shadersUtils2\n}\n","\nuniform mat4 lastProjectionViewMatrix;\nuniform mat4 currentProjectionViewMatrix;\n\nvec2 computeScreenSpaceVelocity(const in vec3 worldPosition) {\n    vec4 currentPositionClip = currentProjectionViewMatrix * vec4(worldPosition, 1.0);\n    vec4 prevPositionClip = lastProjectionViewMatrix * vec4(worldPosition, 1.0);\n\n    vec2 currentPositionNDC = currentPositionClip.xy / currentPositionClip.w;\n    vec2 prevPositionNDC = prevPositionClip.xy / prevPositionClip.w;\n\n    if(prevPositionNDC.x >= 1.0 || prevPositionNDC.x <= -1.0 || prevPositionNDC.x >= 1.0 || prevPositionNDC.y <= -1.0) {\n        return vec2(0.0);\n    }\n    return 0.5 * (currentPositionNDC - prevPositionNDC);\n}\n","\nuniform mat4 inverseViewMatrix;\n\nvec3 getWorldPositionFromViewZ(const in vec2 uv, const in float viewDepth) {\n    vec2 uv_ = 2. * uv - 1.;\n    float xe = -(uv_.x + projection[2][0]) * viewDepth/projection[0][0];\n    float ye = -(uv_.y + projection[2][1]) * viewDepth/projection[1][1];\n    return (inverseViewMatrix * vec4(xe, ye, viewDepth, 1.)).xyz;\n}\n","#include <common>\n#include <gbuffer_unpack>\n\n#ifdef HAS_VELOCITY_BUFFER\n#pragma <velocity_unpack>\n#else\n#define HAS_VELOCITY_BUFFER 0\n#endif\n\n#include <cameraHelpers>\n\nvarying vec2 vUv;\nuniform vec2 previousRTSize;\nuniform vec2 jitterSample;\nuniform vec2 feedBack;\nuniform bool firstFrame;\n\n//float getViewZ( const in float depth ) {\n//\t#if PERSPECTIVE_CAMERA == 1\n//\treturn perspectiveDepthToViewZ( depth, cameraNearFar.x, cameraNearFar.y );\n//\t#else\n//\treturn orthoDepthToViewZ( depth, cameraNearFar.x, cameraNearFar.y );\n//\t#endif\n//}\n\nvec3 find_closest_fragment_3x3(const in vec2 uv) {\n    const vec3 offset = vec3(-1.0, 1.0, 0.0);\n    vec2 texelSize = 1.0/previousRTSize;\n\n    vec3 dtr = vec3( 1, 1, getDepth( uv + offset.yy * texelSize) );\n    vec3 dtc = vec3( 0, 1, getDepth( uv + offset.zy * texelSize) );\n    vec3 dtl = vec3( -1, 1, getDepth( uv + offset.xy * texelSize) );\n\n    vec3 dml = vec3(-1, 0, getDepth( uv + offset.xz * texelSize) );\n    vec3 dmc = vec3( 0, 0, getDepth( uv ) );\n    vec3 dmr = vec3( 1, 0, getDepth( uv + offset.yz * texelSize) );\n\n    vec3 dbl = vec3(-1, -1, getDepth( uv + offset.xx * texelSize) );\n    vec3 dbc = vec3( 0, -1, getDepth( uv + offset.zx * texelSize) );\n    vec3 dbr = vec3( 1, -1, getDepth( uv + offset.yx * texelSize) );\n\n    vec3 dmin = dtl;\n    if ( dmin.z > dtc.z ) dmin = dtc;\n    if ( dmin.z > dtr.z ) dmin = dtr;\n\n    if ( dmin.z > dml.z ) dmin = dml;\n    if ( dmin.z > dmc.z ) dmin = dmc;\n    if ( dmin.z > dmr.z ) dmin = dmr;\n\n    if ( dmin.z > dbl.z ) dmin = dbl;\n    if ( dmin.z > dbc.z ) dmin = dbc;\n    if ( dmin.z > dbr.z ) dmin = dbr;\n\n    return vec3(uv + texelSize.xy * dmin.xy, dmin.z);\n}\n\nvec3 find_closest_fragment_5tap(const in vec2 uv)\n{\n    vec2 texelSize = 1.0/previousRTSize;\n    vec2 offset = vec2(1.0, -1.0);\n\n    vec3 dtl = vec3(-1, 1, getDepth( uv + offset.yx * texelSize) );\n    vec3 dtr = vec3( 1, 1, getDepth( uv + offset.xx * texelSize) );\n\n    vec3 dmc = vec3( 0, 0, getDepth( uv) );\n\n    vec3 dbl = vec3(-1, -1, getDepth( uv + offset.yy * texelSize) );\n    vec3 dbr = vec3( 1, -1, getDepth( uv + offset.xy * texelSize) );\n\n    vec3 dmin = dtl;\n    if ( dmin.z > dtr.z ) dmin = dtr;\n    if ( dmin.z > dmc.z ) dmin = dmc;\n\n    if ( dmin.z > dbl.z ) dmin = dbl;\n    if ( dmin.z > dbr.z ) dmin = dbr;\n\n    return vec3(uv + dmin.xy * texelSize, dmin.z);\n}\n\nvec4 clip_aabb(const in vec4 aabb_min, const in vec4 aabb_max, vec4 p )\n{\n    const float FLT_EPS = 1e-8;\n    vec4 p_clip = 0.5 * (aabb_max + aabb_min);\n    vec4 e_clip = 0.5 * (aabb_max - aabb_min) + FLT_EPS;\n\n    vec4 v_clip = p - p_clip;\n    vec4 v_unit = abs(v_clip / e_clip);\n    float ma_unit = max(v_unit.x, max(v_unit.y, v_unit.z));\n\n    if (ma_unit > 1.0)\n    return p_clip + v_clip / ma_unit;\n    else return p;\n}\n\n#if HAS_VELOCITY_BUFFER == 0 || defined(DEBUG_VELOCITY)\n#include <computeScreenSpaceVelocity>\n#include <getWorldPositionFromViewZ>\n#endif\n\nvec4 currentRTTexelToLinear1(vec4 a){\n    if(isinf(a.x) || isinf(a.y) || isinf(a.z) || isinf(a.w)){\n        return vec4(1.);\n    }\n    return currentRTTexelToLinear(a);\n}\nvec4 computeTAA(const in vec2 uv, const in vec2 screenSpaceVelocity, const in float feedbackScale) {\n//    vec2 jitterOffset = jitterSample/previousRTSize; // todo\n    vec2 uvUnJitter = uv;\n\n    vec4 currentColor = currentRTTexelToLinear(texture2D(currentRT, uvUnJitter));\n    vec4 previousColor = previousRTTexelToLinear(texture2D(previousRT, uv - screenSpaceVelocity));\n    const vec3 offset = vec3(1., -1., 0.);\n    vec2 texelSize = 1./previousRTSize;\n\n    float texelSpeed = length( screenSpaceVelocity );\n\n    // todo pick only the neighbors which are not background?\n    vec4 tl = currentRTTexelToLinear1(texture2D(currentRT, uvUnJitter + offset.yx * texelSize));\n    vec4 tc = currentRTTexelToLinear1(texture2D(currentRT, uvUnJitter + offset.zx * texelSize));\n    vec4 tr = currentRTTexelToLinear1(texture2D(currentRT, uvUnJitter + offset.xx * texelSize));\n    vec4 ml = currentRTTexelToLinear1(texture2D(currentRT, uvUnJitter + offset.yz * texelSize));\n    vec4 mc = currentColor;\n    vec4 mr = currentRTTexelToLinear1(texture2D(currentRT, uvUnJitter + offset.xz * texelSize));\n    vec4 bl = currentRTTexelToLinear1(texture2D(currentRT, uvUnJitter + offset.yy * texelSize));\n    vec4 bc = currentRTTexelToLinear1(texture2D(currentRT, uvUnJitter + offset.zy * texelSize));\n    vec4 br = currentRTTexelToLinear1(texture2D(currentRT, uvUnJitter + offset.xy * texelSize));\n\n    vec4 corners = 2.0 * (tr + bl + br + tl) - 2.0 * mc;\n    mc += (mc - (corners * 0.166667)) * 2.718282 * 0.3;\n    mc = max(vec4(0.0), mc);\n\n    vec4 min5 = min(tc, min(ml, min(mc, min(mr, bc))));\n    vec4 max5 = max(tc, max(ml, max(mc, max(mr, bc))));\n\n    vec4 cmin = min(min5, min(tl, min(tr, min(bl, br))));\n    vec4 cmax = max(min5, max(tl, max(tr, max(bl, br))));;\n\n    cmin = 0.5 * (cmin + min5);\n    cmax = 0.5 * (cmax + max5);\n    previousColor = clip_aabb(cmin, cmax, previousColor);\n\n    float lum0 = luminance(currentColor.rgb);\n    float lum1 = luminance(previousColor.rgb);\n    float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2));\n    float unbiased_weight = 1.0 - unbiased_diff;\n    float unbiased_weight_sqr = unbiased_weight * unbiased_weight;\n    float k_feedback = mix(feedBack.x, feedBack.y, unbiased_weight_sqr);\n\n    return mix(currentColor, previousColor, clamp(k_feedback * feedbackScale, 0., 1.));\n\n}\n\nvoid main() {\n\n    //    gl_FragColor.rgb = vec3(getDepth( vUv ));\n    //    gl_FragColor.a = 1.;\n    //    return;\n    // vec2 jitterOffset = jitterSample/previousRTSize;\n\n    #if HAS_VELOCITY_BUFFER == 0 // todo why not using closest fragment in velocity buffer?\n    #if QUALITY == 1\n    vec3 c_frag = find_closest_fragment_3x3(vUv);\n    #else\n    vec3 c_frag = find_closest_fragment_5tap(vUv);\n    #endif\n    #else\n    vec3 c_frag = vec3(vUv, 0.);\n    #endif\n\n    bool bg = firstFrame;\n\n    #if BACKGROUND_TAA // this is required for edge artifacts in msaa\n\n//    float d = getDepth(vUv);\n    float d = c_frag.z;\n    float edgef = min(1., max(0., 1.- (d*100. - 99.)));\n\n    #else\n\n    bg = bg || c_frag.z > 0.999;\n\n    #endif\n\n    if( bg ) {\n\n        gl_FragColor = currentRTTexelToLinear1(texture2D(currentRT, vUv));\n\n    } else {\n        #if HAS_VELOCITY_BUFFER == 0\n        //        #if LINEAR_DEPTH == 0\n        //            float sampleViewZ = getViewZ( c_frag.z );\n        //        #else\n        float sampleViewZ = mix(-cameraNearFar.x, -cameraNearFar.y, c_frag.z);\n        //        #endif\n        vec3 worldPosition = getWorldPositionFromViewZ(c_frag.xy, sampleViewZ);\n        vec2 screenSpaceVelocity = computeScreenSpaceVelocity(worldPosition);\n        #else\n        vec2 screenSpaceVelocity = getVelocity(c_frag.xy);\n        #endif\n\n//        float previousDepth = getDepth(vUv - screenSpaceVelocity);\n\n//        screenSpaceVelocity *= min(1., edgef);\n//        screenSpaceVelocity *= (d >= 0.99) ? 0. : 1.;\n//        screenSpaceVelocity *= abs(d-previousDepth) > 0.01 ? 0. : 1.;\n//        screenSpaceVelocity *= 0.;\n\n        // todo add velocity scale also\n        #if BACKGROUND_TAA\n        gl_FragColor = computeTAA(vUv, screenSpaceVelocity * edgef, edgef);\n        #else\n        gl_FragColor = computeTAA(vUv, screenSpaceVelocity, 1.);\n        #endif\n\n//        gl_FragColor = firstFrame /* || previousDepth > 0.999*/ ? currentRTTexelToLinear1(texture2D(currentRT, vUv)) : computeTAA(vUv, screenSpaceVelocity, edgef);\n//        gl_FragColor = vec4(1. - max(0., (d - 0.9) * 10.0), 0., 0., 1.0);\n//        gl_FragColor = vec4(10. * length(screenSpaceVelocity));\n//        gl_FragColor = vec4(abs(d-previousDepth) > 0.1, 0., 0., 1.);\n//        gl_FragColor = vec4(abs(d-previousDepth) > 0.1, 0., 0., 1.);\n\n    }\n\n    #include <colorspace_fragment>\n\n    #ifdef DEBUG_VELOCITY\n    float sampleViewZ = mix(-cameraNearFar.x, -cameraNearFar.y, c_frag.z);\n    vec3 worldPosition = getWorldPositionFromViewZ(c_frag.xy, sampleViewZ);\n    vec2 screenSpaceVelocity = computeScreenSpaceVelocity(worldPosition);\n//    screenSpaceVelocity *= min(1., edgef);\n    gl_FragColor = vec4(10. * length(screenSpaceVelocity), 0., 0., 1.);\n    #endif\n\n}\n","\n//https://web.archive.org/web/20170808071110/http://graphics.cs.williams.edu/papers/AlchemyHPG11/AlchemyHPG2011-present.pdf\n\n//uniform float opacity;\n//uniform sampler2D tDiffuse;\n//uniform sampler2D tLastFrame;\nuniform float currentFrameCount;\n#ifndef D_frameCount\n#define D_frameCount\nuniform float frameCount;\n#endif\nuniform float objectRadius;\nuniform float radius;\n//uniform float power;\n//uniform float bias;\n//uniform float falloff;\nuniform float tolerance;\nuniform float ssrRoughnessFactor;\nuniform bool autoRadius;\n//uniform bool giEnabled;\n\n#ifndef D_sceneBoundingRadius\n#define D_sceneBoundingRadius\nuniform float sceneBoundingRadius;\n#endif\n\n#if SSREFL_ENABLED == 2 // split mode\nuniform float ssrSplitX;\n#endif\n\n#ifdef HAS_VELOCITY_BUFFER\n#pragma <velocity_unpack>\n#else\n#define HAS_VELOCITY_BUFFER 0\n#endif\n#if HAS_VELOCITY_BUFFER == 0\n#include <computeScreenSpaceVelocity>\n#include <getWorldPositionFromViewZ>\n#endif\n\nvec3 ComputeReflectionL(vec3 N, vec2 E, vec3 V, float rough){\n//    vec3 L;\n//    L = reflect(normalize(V), N);\n//    return L;\n\n    float rough4 = rough *rough *rough *rough;\n    // importance sampling\n    float phi = 2.0 * PI * E.x;\n    //    float cos_theta = sqrt((1.0 - E.y) / (1.0 + (rough4 - 1.0) * E.y)); // ggx, NOISY\n    float cos_theta = pow(max(E.y, 0.000001), rough4 / (2.0 - rough4));// blinn\n    float sin_theta = sqrt(max(0., 1.0 - cos_theta * cos_theta));\n    vec3 half_vec = vec3(sin_theta * cos(phi), sin_theta * sin(phi), cos_theta);\n    vec3 tangentX = normalize(cross(abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0), N));\n    vec3 tangentY = cross(N, tangentX);\n    half_vec = half_vec.x * tangentX + half_vec.y * tangentY + half_vec.z * N;\n\n    // in view space\n    vec3 ray_dir = (2.0 * dot(V, half_vec)) * half_vec - V;\n//    ray_dir = normalize(ray_dir);\n\n    return ray_dir;\n\n}\n\nvec2 GetRandomE(float seed){\n\n    vec2 rand_e;// random\n    rand_e.x = interleavedGradientNoise(gl_FragCoord.xy, frameCount*34. + seed);\n    rand_e.y = fract(rand_e.x * 38.65435);\n    // https://www.slideshare.net/DICEStudio/stochastic-screenspace-reflections#p=67\n    rand_e.y = mix(rand_e.y, 1.0, 0.7);\n    return rand_e;\n\n}\n\nvec4 calculateSSR(in float seed, in vec3 screenPos, in vec3 normal, in float radiusFactor, in float roughness){\n\n//    if(roughness > 0.9) return vec4(0.);\n\n    vec3 viewPos = screenToView3(screenPos.xy, screenPos.z);\n    normal = normalize(normal);\n    vec2 E = GetRandomE(seed);\n    vec3 L = ComputeReflectionL(normal, E, -normalize(viewPos), roughness * ssrRoughnessFactor);\n\n    L = normalize(L);\n//    L *= sign(dot(L, normal));\n\n    float cameraDist = length(cameraPositionWorld);\n\n    float rayLen = objectRadius*sceneBoundingRadius;\n    rayLen = autoRadius ?\n    //    length(viewPos - screenToView3(screenPos.xy + objectRadius/10., screenPos.z)):\n    //    mix((cameraNearFar.y) + viewPos.z, -viewPos.z - cameraNearFar.x, L.z * 0.5 + 0.5)*objectRadius:\n    min(max(mix(\n    max(0.0, (cameraDist + rayLen) + viewPos.z),\n    max(0.0, -viewPos.z - max(0.0, cameraDist - rayLen)),\n    L.z * 0.5 + 0.5), rayLen *0.1), rayLen*5.) :\n    rayLen;\n//    rayLen = mix((cameraDist + objectRadius) + viewPos.z, -viewPos.z - (cameraDist - objectRadius), L.z * 0.5 + 0.5);\n\n    rayLen *= radiusFactor;\n//    rayLen = 10.;\n\n    float r = interleavedGradientNoise(gl_FragCoord.xy, frameCount + seed);\n\n    // jitter rayLen\n    //    rayLen = rayLen * (.75 + 0.5 * (random(r)));//mix(rayLen*(1.-.5), rayLen*(1.+.5), random(r));\n\n    rayLen = max(rayLen, 0.001);\n\n    int steps = SSR_STEP_COUNT / (currentFrameCount < float(SSR_LOW_QUALITY_FRAMES) ? 2 : 1);\n    vec3 state = vec3(0.,(r+0.5)/float(steps),2.);\n    viewPos += normal * max(-0.0001*viewPos.z, 0.001);\n\n    vec3 screenHitP = traceRay(viewPos, L * rayLen, tolerance * rayLen, state, steps);\n//    return vec4(screenHitP.x);\n//    return vec4(-viewPos.z,0,0,1);\n    if(state.z < 0.99){\n\n        if(currentFrameCount < 1.){\n            #if HAS_VELOCITY_BUFFER == 0\n            vec3 worldPosition = getWorldPositionFromViewZ(screenHitP.xy, screenHitP.z);\n            vec2 screenSpaceVelocity = computeScreenSpaceVelocity(worldPosition);\n            #else\n            vec2 screenSpaceVelocity = getVelocity(screenHitP.xy);\n            #endif\n            screenHitP.xy -= screenSpaceVelocity;\n        }\n\n        vec3 hitColor = (tLastFrameTexelToLinear(texture2D( tLastFrame , screenHitP.xy))).rgb;\n//        vec3 hitColor = tDiffuseTexelToLinear(texture2D( tDiffuse, screenHitP.xy )).rgb;\n//        vec3 hitNormal = getViewNormal(screenHitP.xy);\n\n        float ssrWeight = 1.;\n\n        return vec4(hitColor*ssrWeight, 1.);\n    }\n\n    return vec4(0.);\n}\n\n","\n//https://web.archive.org/web/20170808071110/http://graphics.cs.williams.edu/papers/AlchemyHPG11/AlchemyHPG2011-present.pdf\n\n//uniform float opacity;\n//varying vec2 vUv;\n//#ifndef D_frameCount\n//#define D_frameCount\n//uniform float frameCount;\n//#endif\nuniform float currentFrameCount;\nuniform float intensity;\nuniform float objectRadius;\n//uniform float radius;\nuniform float rayCount;\nuniform float power;\nuniform float bias;\nuniform float falloff;\nuniform float tolerance;\nuniform bool autoRadius;\n\nuniform vec2 screenSize;\n\n#ifndef D_sceneBoundingRadius\n#define D_sceneBoundingRadius\nuniform float sceneBoundingRadius;\n#endif\n\n#ifdef HAS_VELOCITY_BUFFER\n#pragma <velocity_unpack>\n#else\n#define HAS_VELOCITY_BUFFER 0\n#endif\n#if HAS_VELOCITY_BUFFER == 0\n#include <computeScreenSpaceVelocity>\n#include <getWorldPositionFromViewZ>\n#endif\n\nvec3 ComputeUniformL(vec3 N, vec2 E){\n    vec3 L;\n    L.xy = E;\n    L.z = interleavedGradientNoise(gl_FragCoord.xy, currentFrameCount*5.);\n    L = L * 2. - 1.;\n    return L;\n}\n\nvec2 GetRandomE(float seed){\n    vec2 rand_e;\n    rand_e.x = random3(vec3(gl_FragCoord.xy, currentFrameCount + seed));\n    rand_e.y = random3(vec3(gl_FragCoord.yx, rand_e.x + (currentFrameCount)*7.));\n    return rand_e;\n}\n\nfloat saturate2(float v, float mx){\n    return max(0., min(mx, v));\n}\n\nvec4 calculateGI(in float seed, in vec3 screenPos, in vec3 normal, in float radiusFactor){\n\n    vec3 viewPos = screenToView3(screenPos.xy, screenPos.z);\n\n    normal = normalize(normal);\n    vec2 E = GetRandomE(seed);\n    vec3 L = ComputeUniformL(normal, E);\n\n    L = normalize(L);\n    L *= sign(dot(L, normal));\n\n    float cameraDist = length(cameraPositionWorld);\n\n//    float rayLen = autoRadius ?\n//        length(viewPos - screenToView3(screenPos.xy + objectRadius/10., screenPos.z)):\n//    mix((cameraNearFar.y) + viewPos.z, -viewPos.z - cameraNearFar.x, L.z * 0.5 + 0.5)*objectRadius;\n\n    float rayLen = objectRadius*sceneBoundingRadius;\n    rayLen = autoRadius ?\n    //    length(viewPos - screenToView3(screenPos.xy + objectRadius/10., screenPos.z)):\n    //    mix((cameraNearFar.y) + viewPos.z, -viewPos.z - cameraNearFar.x, L.z * 0.5 + 0.5)*objectRadius:\n    min(max(mix(\n    max(0.0, (cameraDist + rayLen) + viewPos.z),\n    max(0.0, -viewPos.z - max(0.0, cameraDist - rayLen)),\n    L.z * 0.5 + 0.5), rayLen *0.1), rayLen*5.) :\n    rayLen;\n\n//    rayLen = min(-viewPos.z, rayLen);\n//    rayLen = mix((cameraDist + objectRadius) + viewPos.z, -viewPos.z - (cameraDist - objectRadius), L.z * 0.5 + 0.5);\n\n    rayLen *= radiusFactor;\n\n//    float r = interleavedGradientNoise(gl_FragCoord.xy, currentFrameCount*14. + seed) + 0.05;\n    float r = interleavedGradientNoise(gl_FragCoord.xy, currentFrameCount*14. + seed) + 0.05;\n\n    // jitter rayLen\n//    rayLen = rayLen * (.75 + 0.5 * (random(r)));//mix(rayLen*(1.-.5), rayLen*(1.+.5), random(r));\n\n    rayLen = max(rayLen, 0.001);\n\n    vec3 state = vec3(1.,(r+0.5)/float(RTAO_STEP_COUNT),2.);\n    viewPos += normal * max(-0.01*viewPos.z, 0.001);\n    vec3 screenHitP = traceRay(viewPos, L * rayLen, tolerance * rayLen, state, RTAO_STEP_COUNT);\n\n    vec3 viewHitP = screenToView3(screenHitP.xy, screenHitP.z);\n    vec3 LRes = viewHitP - viewPos;\n    if(state.z > 1.) LRes = vec3(9999999.);\n    float dist = length(LRes) * falloff;\n\n    float EPS = 0.01;\n    float zBias = (viewPos.z) * bias;\n    float ao = (max(dot(normal, L) + zBias, 0.)) / (dist*dist + EPS);\n\n    #if defined(SSGI_ENABLED) && SSGI_ENABLED > 0\n\n        if(currentFrameCount < 1.){\n            #if HAS_VELOCITY_BUFFER == 0\n            vec3 worldPosition = getWorldPositionFromViewZ(screenHitP.xy, screenHitP.z);\n            vec2 screenSpaceVelocity = computeScreenSpaceVelocity(worldPosition);\n            #else\n            vec2 screenSpaceVelocity = getVelocity(screenHitP.xy);\n            #endif\n            screenHitP.xy -= screenSpaceVelocity;\n        }\n\n        vec3 hitColor = tLastFrameTexelToLinear(texture2D(tLastFrame, screenHitP.xy)).rgb;\n        //    vec3 hitColor = tDiffuseTexelToLinear(texture2D( tDiffuse, screenHitP.xy )).rgb;\n        vec3 hitNormal = getViewNormal(screenHitP.xy);\n        float giWeight = 1.;\n        giWeight = saturate2(giWeight / (dist+EPS), 1.);\n        giWeight *= saturate2((dot(normal, L)), 1.0);\n        giWeight *= saturate2((dot(hitNormal, -L)), 1.0);\n        //    giWeight *= saturate2((1.-dot(hitNormal, normal) ), 1.1);\n\n        return vec4(hitColor*giWeight, ao);\n    #endif\n\n    return vec4(0,0,0,ao);\n}\n\n\nfloat normpdf(in float x, in float sigma)\n{\n    return exp(-0.5*x*x/(sigma*sigma));\n}\n//float normpdf(in float x, in float sigma)\n//{\n//    return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n//}\n//\n\n\n//uniform bool smoothEnabled; // last frame bilateral denoise\n//uniform vec4 smoothSigma; // color, depth, pixel, normal\n//uniform vec4 smoothScale; // color, depth, pixel, normal\n//#define BILATERAL_KERNEL 2\n\n//uniform vec4 smoothModes; // depthScale, 0, 0,\nvec4 getLastThis(sampler2D tex, float depth, vec3 normal){\n//    vec4 smoothSigma = vec4(5,10,2,2);\n    vec2 direction = vec2(1,1);\n\n    vec4 color = clamp(tLastThisTexelToLinear(texture2D(tex, vUv.xy)), 0., 5.);\n\n//    float depth;\n//    vec3 normal;\n//    getDepthNormal(vUv, depth, normal);\n\n//    if(!smoothEnabled || frameCount < 60. || vUv.x > 0.5)\n        return color;\n\n//    direction *= vec2(int(frameCount)%2, int(frameCount+1.)%2);\n\n//    float Z = 1.0;\n//    vec4 final_colour = Z * color;\n//    float factor;\n//    vec2 nuv;\n//    vec4 cc, np; float dp; vec3 nor;  // cc is color, np is position, dp is depth, nor is normal\n//    direction /= screenSize.xy;\n//\n//    // -1, 1, -2, 2, -3, 3\n//    for (int i = 0; i < BILATERAL_KERNEL; ++i)\n//    {\n//\n//        direction *= -1.;\n//        nuv = vUv + direction * float( i/2 + 1 ); // clamp to screen border\n//        getDepthNormal(nuv, dp, nor);\n//        if(dp > 0.99) continue;\n//\n//        cc = clamp(texture2D(tex, nuv), 0., 5.); // clamp(texsample(tDiffuse, float(i), float(j)), 0., 1.);\n//\n//        factor = 1.;\n//\n//        factor *= normpdf( length(cc-color)       * smoothScale.x, smoothSigma.x); //color\n//        factor *= normpdf( sqrt(abs(dp-depth))    * smoothScale.y, smoothSigma.y); //depth\n//        factor *= normpdf( float( i/2 + 1 )        * smoothScale.z, smoothSigma.z); //pixel distance\n//        factor *= normpdf( (1.-dot(normal, nor))  * smoothScale.w, smoothSigma.w); //normal\n////            factor *= normpdf(sqrt(length(np-pos))*smoothScale.y, smoothSigma.y); // position.\n//\n//        Z += factor;\n//        final_colour += factor*cc;\n//\n//    }\n//\n//    final_colour /= Z;\n//    return final_colour;\n}\n\nvoid main() {\n\n//    vec4 texel = texture2D( tDiffuse, vUv );\n    float depth;\n    vec3 normal;\n//    float alpha = opacity;\n    getDepthNormal(vUv, depth, normal);\n\n    if (depth > 0.99) {\n        discard;\n\n        gl_FragColor = getLastThis(tLastThis, depth, normal);\n\n        return;\n    }\n\n    float viewZ = depthToViewZ(depth);\n    vec3 screenPos = vec3(vUv.x, vUv.y, viewZ);\n\n    vec4 gi = vec4(0.);\n//    screenPos.z += 0.001;\n    gi += calculateGI(8., screenPos, normal, 1.);\n    if(rayCount > 1.5)\n        gi = max(gi, calculateGI(2., screenPos, normal, 0.4));\n    if(rayCount > 2.5)\n        gi = max(gi, calculateGI(3., screenPos, normal, 1.5));\n    if(rayCount > 3.5)\n        gi = max(gi, calculateGI(1., screenPos, normal, 0.6));\n    if(rayCount > 4.5)\n        gi = max(gi, calculateGI(3., screenPos, normal, 1.));\n\n//        gi += calculateGI(3., screenPos, normal, 1.);\n//        gi += calculateGI(4., screenPos, normal, 1.);\n//        gi += calculateGI(5., screenPos, normal, 1.);\n//        gi += calculateGI(6., screenPos, normal, 1.);\n//        gi += calculateGI(7., screenPos, normal, 1.);\n//        gi = gi / 6.;\n//        gi = gi / 3.;\n\n//     gl_FragColor = vec4(texel) * (1.-ao);\n\n    gi.a = min(1., gi.a);\n    gi.a = max(0., gi.a);\n//    gi = ao;\n//    gi *= intensity/1.;\n\n    gi.rgb = min(vec3(3.), gi.rgb);\n    gi.rgb = max(vec3(0.), gi.rgb);\n\n    if(currentFrameCount < 3.){\n        gl_FragColor = gi;\n        return;\n    }\n\n    gl_FragColor = (texture2D( tLastThis, vUv ));\n//    gl_FragColor = getLastThis(tLastThis, depth, normal);\n\n    //    if(gi.a < 0.001){\n    //        gl_FragColor.rgb = gl_FragColor.rgb;\n    //        gl_FragColor.a = (((gl_FragColor.a) * frameCount)/(frameCount+1.));\n    //    }else {\n    //        gl_FragColor = ((gi + (gl_FragColor) * frameCount)/(frameCount+1.));\n    //    }\n\n    gl_FragColor = ((gi + (gl_FragColor) * currentFrameCount)/(currentFrameCount+1.));\n\n    // todo: encodings??\n\n//    #include <colorspace_fragment>\n\n}\n","import {\n    Camera,\n    CopyShader,\n    ExtendedShaderPass,\n    GBufferPlugin,\n    generateUiConfig,\n    getOrCall,\n    ICamera,\n    IPassID,\n    IPipelinePass,\n    IRenderManager,\n    IScene,\n    IWebGLRenderer,\n    matDefineBool,\n    MaterialExtension,\n    Matrix4,\n    PipelinePassPlugin,\n    ProgressivePlugin,\n    serialize,\n    ThreeViewer,\n    uiConfig,\n    UiObjectConfig,\n    uiToggle,\n    uiVector,\n    uniform,\n    ValOrFunc,\n    Vector2,\n    WebGLRenderTarget,\n} from 'threepipe'\nimport {getShaders} from \"../../utils/shaders\";\n\nconst passId = 'taa'\ntype TemporalAAPassId = typeof passId\n\n/**\n * Temporal Anti-Aliasing Plugin\n *\n * This plugin uses a temporal anti-aliasing pass to smooth out the final image when the camera or some mesh is moving\n * @category Plugins\n */\nexport class TemporalAAPlugin\n    extends PipelinePassPlugin<TemporalAAPluginPass<TemporalAAPassId>, TemporalAAPassId> {\n    static readonly PluginType = 'TAA'\n    static readonly OldPluginType = 'TemporalAAPlugin' // todo swap\n    readonly passId = passId\n\n    // readonly materialExtension: MaterialExtension = uiConfigMaterialExtension(this._getUiConfig.bind(this), TemporalAAPlugin.PluginType)\n\n    constructor(enabled = true) {\n        super()\n        this.enabled = enabled\n        this.setDirty = this.setDirty.bind(this)\n    }\n\n\n    private _stableNoise = true\n    /**\n     * Same as BaseRenderer.stableNoise Use total frame count, if this is set to true, then frameCount won't be reset when the viewer is set to dirty.\n     * Which will generate different random numbers for each frame during postprocessing steps. With TAA set properly, this will give a smoother result.\n     */\n    @uiToggle('Stable Noise (Total frame count)')\n    get stableNoise(): boolean {\n        return this._viewer?.renderManager.stableNoise ?? this._stableNoise\n    }\n    set stableNoise(v: boolean) {\n        if (this._viewer) this._viewer.renderManager.stableNoise = v\n        this._stableNoise = v\n    }\n\n    @uiConfig(undefined, {unwrapContents: true}) declare protected _pass?: TemporalAAPluginPass<TemporalAAPassId>\n\n    private _gbufferUnpackExtension = undefined as MaterialExtension|undefined\n    private _gbufferUnpackExtensionChanged = ()=>{\n        if (!this._pass || !this._viewer) throw new Error('TemporalAAPlugin: pass/viewer not created yet')\n        const newExtension = this._viewer.renderManager.gbufferUnpackExtension\n        if (this._gbufferUnpackExtension === newExtension) return\n        if (this._gbufferUnpackExtension) this._pass.material.unregisterMaterialExtensions([this._gbufferUnpackExtension])\n        this._gbufferUnpackExtension = newExtension\n        if (this._gbufferUnpackExtension) this._pass.material.registerMaterialExtensions([this._gbufferUnpackExtension])\n        else this._viewer.console.warn('TemporalAAPlugin: GBuffer unpack extension removed')\n    }\n\n    protected _createPass() {\n        if (!this._viewer) throw new Error('TemporalAAPlugin: viewer not set')\n        if (!this._viewer.renderManager.gbufferTarget || !this._viewer.renderManager.gbufferUnpackExtension)\n            throw new Error('TemporalAAPlugin: GBuffer target not created. GBufferPlugin is required.')\n        const applyOnBackground = !!this._viewer.renderManager.msaa\n        const t = new TemporalAAPluginPass(this.passId, ()=>this._viewer?.getPlugin(ProgressivePlugin)?.target, applyOnBackground)\n        return t\n    }\n\n    dependencies = [GBufferPlugin, ProgressivePlugin] // todo use gbufferUnpackExtension from render manager to support depth buffer plugin as well.\n\n    onAdded(viewer: ThreeViewer) {\n        super.onAdded(viewer)\n        this._gbufferUnpackExtensionChanged()\n        viewer.renderManager.addEventListener('gbufferUnpackExtensionChanged', this._gbufferUnpackExtensionChanged)\n        viewer.renderManager.addEventListener('resize', this._pass!.onSizeUpdate)\n        // viewer.materialManager.registerMaterialExtension(this.materialExtension)\n    }\n\n    onRemove(viewer: ThreeViewer) {\n        viewer.renderManager.removeEventListener('gbufferUnpackExtensionChanged', this._gbufferUnpackExtensionChanged)\n        viewer.renderManager.removeEventListener('resize', this._pass!.onSizeUpdate)\n        super.onRemove(viewer)\n        // viewer.materialManager.unregisterMaterialExtension(this.materialExtension)\n    }\n\n    uiConfig: UiObjectConfig = {\n        type: 'folder',\n        label: 'TemporalAA Plugin',\n        onChange: this.setDirty.bind(this),\n        children: [\n            ...generateUiConfig(this) || [],\n        ],\n    }\n\n    protected _beforeRender(scene: IScene, camera: ICamera, renderManager: IRenderManager): boolean {\n        if (!super._beforeRender(scene, camera, renderManager)) return false\n        const pass = this.pass\n        const v = this._viewer\n        if (!pass || !v) return false\n\n        const frame = renderManager.frameCount\n        pass.taaEnabled = frame <= 1 && scene.renderCamera === scene.mainCamera\n        if (!pass.taaEnabled) return false\n\n        const cam = camera\n        if (!cam) return false\n\n        cam.updateMatrixWorld(true)\n\n        cam.updateShaderProperties(pass.material) // for cameraNearFar\n\n        pass.updateCameraProperties(cam)\n\n        pass.target = v.getPlugin(ProgressivePlugin)!.target as any\n        return true\n    }\n\n    // region to be done or removed\n\n    // static AddTemporalAAData(material: IMaterial, params?: IMaterialUserData['TemporalAA'], setDirty = true): IMaterialUserData['TemporalAA']|null {\n    //     const ud = material?.userData\n    //     if (!ud) return null\n    //     if (!ud[TemporalAAPlugin.PluginType]) {\n    //         ud[TemporalAAPlugin.PluginType] = {}\n    //     }\n    //     const data = ud[TemporalAAPlugin.PluginType]!\n    //     data.enable = true\n    //     params && Object.assign(data, params)\n    //     if (setDirty && material.setDirty) material.setDirty()\n    //     return data\n    // }\n\n    /**\n     * This uiConfig is added to each material by extension\n     * @param material\n     * @private\n     */\n    // private _getUiConfig(material: IMaterial) {\n    //     const config: UiObjectConfig = {\n    //         type: 'folder',\n    //         label: 'TemporalAA',\n    //         children: [\n    //             {\n    //                 type: 'checkbox',\n    //                 label: 'Enabled',\n    //                 get value() {\n    //                     return material.userData[TemporalAAPlugin.PluginType]?.enable ?? true\n    //                 },\n    //                 set value(v) {\n    //                     let data = material.userData[TemporalAAPlugin.PluginType]\n    //                     if (v === data?.enable) return\n    //                     if (!data) data = TemporalAAPlugin.AddTemporalAAData(material, undefined, false)!\n    //                     data.enable = v\n    //                     material.setDirty()\n    //                     config.uiRefresh?.(true, 'postFrame')\n    //                 },\n    //                 onChange: this.setDirty,\n    //             },\n    //         ],\n    //     }\n    //     return config\n    // }\n\n    // endregion\n}\n\nexport class TemporalAAPluginPass<Tid extends IPassID> extends ExtendedShaderPass implements IPipelinePass<Tid> {\n    before = ['progressive']\n    after = [] // leave empty so that this is placed right before progressive\n    required = ['render', 'progressive']\n\n    public target: ValOrFunc<WebGLRenderTarget|undefined>\n    public readonly passId: Tid\n\n    constructor(pid: Tid, target: ValOrFunc<WebGLRenderTarget|undefined>, applyOnBackground = false) {\n        super({\n            vertexShader: CopyShader.vertexShader,\n            fragmentShader: getShaders().temporalAA,\n            uniforms: {\n                currentRT: {value: null},\n                previousRT: {value: null},\n                previousRTSize: {value: new Vector2()},\n                cameraNearFar: {value: new Vector2()},\n                lastProjectionViewMatrix: {value: new Matrix4()},\n                currentProjectionViewMatrix: {value: new Matrix4()},\n                projection: {value: new Matrix4()},\n                inverseViewMatrix: {value: new Matrix4()},\n                jitterSample: {value: new Vector2()},\n                firstFrame: {value: true},\n            },\n            defines: {\n                ['QUALITY']: 1,\n                ['UNJITTER']: 0,\n                ['BACKGROUND_TAA']: applyOnBackground ? 1 : 0,\n            },\n\n        }, 'currentRT', 'previousRT')\n        this.passId = pid\n        this.onSizeUpdate = this.onSizeUpdate.bind(this)\n        this.target = target\n        this.clear = false\n        this.needsSwap = true\n\n    }\n\n    /**\n     * to switch with ssaa, for internal use only, dont set from outside\n     */\n    taaEnabled = true\n\n    render(renderer: IWebGLRenderer, writeBuffer?: WebGLRenderTarget | null, readBuffer?: WebGLRenderTarget, deltaTime?: number, maskActive?: boolean) {\n        if (!this.taaEnabled || !this.enabled) {\n            this.needsSwap = false\n            return\n        }\n        this.needsSwap = true\n\n        this.uniforms.previousRT.value = getOrCall(this.target)?.texture ?? null\n\n        super.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive)\n\n        // ;(renderer as any).baseRenderer.blit(writeBuffer.texture, this.target, {clear: false}) // this is done in the progressive plugin\n\n        this.uniforms.lastProjectionViewMatrix.value.copy(this.uniforms.currentProjectionViewMatrix.value)\n\n        this.uniforms.firstFrame.value = false\n\n    }\n\n\n    updateCameraProperties(camera?: Camera): void {\n        if (!camera) return\n        this.uniforms.currentProjectionViewMatrix.value.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n        // this.uniforms.lastProjectionViewMatrix.value.copy(this.lastProjectionViewMatrix_)\n        // this.uniforms.ProjectionMatrix.value.copy(this.projectionMatrix_)\n        this.uniforms.inverseViewMatrix.value.copy(camera.matrixWorld)\n    }\n    onSizeUpdate() {\n        this.uniforms.firstFrame.value = true\n        this.setDirty()\n    }\n    setSize(width: number, height: number) {\n        super.setSize(width, height)\n        this.onSizeUpdate()\n    }\n\n    @serialize() @uniform()\n    @uiVector('Feedback', undefined, 0.0001)\n        feedBack: Vector2 = new Vector2(0.88, 0.97)\n\n    @uiToggle()\n    @matDefineBool('DEBUG_VELOCITY', undefined, false, undefined, true)\n        debugVelocity = false\n\n    uiConfig: UiObjectConfig = {\n        type: 'folder',\n        label: 'Temporal AA Pass',\n        onChange: this.setDirty,\n        children: [\n            {\n                type: 'checkbox',\n                label: 'Enabled',\n                property: [this, 'enabled'],\n                onChange: ()=>this.onSizeUpdate(),\n            },\n            ...generateUiConfig(this)?.filter(c=>c && (c as any).label !== 'Enabled') || [],\n        ],\n    }\n\n}\n\ndeclare module 'threepipe' {\n    // interface IMaterialUserData {\n        // [TemporalAAPlugin.PluginType]?: {\n        //     enable?: boolean\n        // }\n    // }\n}\n","import {\n    BufferGeometry,\n    Camera,\n    Color,\n    DoubleSide,\n    GBufferRenderPass,\n    ICamera,\n    IObject3D,\n    IRenderManager,\n    IScene,\n    IUniform,\n    IWebGLRenderer,\n    LinearSRGBColorSpace,\n    MaterialExtension,\n    Matrix3,\n    Matrix4,\n    NoBlending,\n    PipelinePassPlugin,\n    Scene,\n    ShaderMaterial,\n    shaderReplaceString,\n    Texture,\n    TextureDataType,\n    ThreeViewer,\n    uiFolderContainer,\n    uiImage,\n    Group,\n    UnsignedByteType,\n    Vector2,\n    WebGLRenderer,\n    WebGLRenderTarget,\n} from 'threepipe'\nimport VelocityBufferUnpack from './shaders/VelocityBufferPlugin.unpack.glsl'\nimport ssVelocityVert from './shaders/VelocityBufferPlugin.mat.vert.glsl'\nimport ssVelocityFrag from './shaders/VelocityBufferPlugin.mat.frag.glsl'\nimport {TemporalAAPlugin} from '../postprocessing/TemporalAAPlugin'\n\n// type VelocityBufferPluginTarget = WebGLRenderTarget\nexport type VelocityBufferPluginTarget = WebGLRenderTarget\nexport type VelocityBufferPluginPass = GBufferRenderPass<'velocityBuffer', VelocityBufferPluginTarget>\n/**\n * Velocity Buffer Plugin\n *\n * Adds a pre-render pass to render the normal buffer to a render target that can be used for postprocessing.\n * @category Plugins\n */\n@uiFolderContainer('Velocity Buffer Plugin (for TAA)')\nexport class VelocityBufferPlugin\n    extends PipelinePassPlugin<VelocityBufferPluginPass, 'velocityBuffer'> {\n\n    readonly passId = 'velocityBuffer'\n    public static readonly PluginType = 'VelocityBuffer'\n    public static readonly OldPluginType = 'VelocityBufferPlugin' // todo swap\n\n    target?: VelocityBufferPluginTarget\n    @uiImage('Velocity Buffer', {readOnly: true}) texture?: Texture\n    readonly material: SSVelocityMaterial = new SSVelocityMaterial()\n\n    // @onChange2(VelocityBufferPlugin.prototype._createTarget)\n    // @uiDropdown('Buffer Type', threeConstMappings.TextureDataType.uiConfig)\n    readonly bufferType: TextureDataType // cannot be changed after creation (for now)\n\n    protected _createTarget(recreate = true) {\n        if (!this._viewer) return\n        if (recreate) this._disposeTarget()\n\n        if (!this.target) this.target = this._viewer.renderManager.createTarget<VelocityBufferPluginTarget>(\n            {\n                depthBuffer: true,\n                // samples: v.renderManager.composerTarget.samples || 0,\n                samples: 0,\n                type: this.bufferType,\n                // magFilter: NearestFilter,\n                // minFilter: NearestFilter,\n                generateMipmaps: false,\n                colorSpace: LinearSRGBColorSpace,\n            })\n        this.texture = this.target.texture\n        this.texture.name = 'velocityBuffer'\n\n        if (this._pass) this._pass.target = this.target\n    }\n    protected _disposeTarget() {\n        if (!this._viewer) return\n        if (this.target) {\n            this._viewer.renderManager.disposeTarget(this.target)\n            this.target = undefined\n        }\n        this.texture = undefined\n    }\n\n    protected _createPass() {\n        this._createTarget(true)\n        if (!this.target) throw new Error('VelocityBufferPlugin: target not created')\n        this.material.userData.isGBufferMaterial = true\n        const v = this._viewer!\n        const pass = new class extends GBufferRenderPass {\n            private _firstCall = true\n            render(renderer: IWebGLRenderer, writeBuffer?: WebGLRenderTarget | null, readBuffer?: WebGLRenderTarget, deltaTime?: number, maskActive?: boolean) {\n                if (v.renderManager.frameCount > 0) return\n                if (!this.enabled || !this.camera) return\n                const mat = this.overrideMaterial as ShaderMaterial\n                mat.uniforms.currentProjectionViewMatrix.value.copy(this.camera.projectionMatrix).multiply(this.camera.matrixWorldInverse)\n                if (this._firstCall) {\n                    mat.uniforms.lastProjectionViewMatrix.value.copy(mat.uniforms.currentProjectionViewMatrix.value)\n                    this._firstCall = false\n                }\n                super.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive)\n                mat.uniforms.lastProjectionViewMatrix.value.copy(mat.uniforms.currentProjectionViewMatrix.value)\n            }\n        }(this.passId, this.target, this.material, new Color(0.5, 0.5, 0.5), 1) // clear color 0.5 means 0 velocity\n        const preprocessMaterial = pass.preprocessMaterial\n        pass.preprocessMaterial = (m) => preprocessMaterial(m, m.userData[VelocityBufferPlugin.PluginType]?.disabled)\n        pass.before = ['render']\n        pass.after = []\n        pass.required = ['render']\n        return pass as any\n    }\n\n    // automatically register the unpack extension with TAA plugin\n    protected readonly _attachToTaa: boolean\n\n    constructor(\n        bufferType: TextureDataType = UnsignedByteType,\n        enabled = true,\n        _attachToTaa = true\n    ) {\n        super()\n        this.enabled = enabled\n        this.bufferType = bufferType\n        this._attachToTaa = _attachToTaa\n    }\n\n    onAdded(viewer: ThreeViewer) {\n        super.onAdded(viewer)\n        viewer.forPlugin(TemporalAAPlugin, (taa) => {\n            this._attachToTaa && taa.pass?.material.registerMaterialExtensions([this.unpackExtension])\n        }, (taa)=>{\n            taa.pass?.material?.unregisterMaterialExtensions([this.unpackExtension])\n        }, this)\n    }\n\n    onRemove(viewer: ThreeViewer): void {\n        this._disposeTarget()\n        return super.onRemove(viewer)\n    }\n\n    unpackExtension: MaterialExtension = {\n        shaderExtender: (shader)=>{\n            if(this.isDisabled()) return\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader,\n                '#pragma <velocity_unpack>',\n                '\\n' + VelocityBufferUnpack + '\\n')\n        },\n        computeCacheKey: ()=>this.isDisabled() ? '' : 'vb',\n        extraUniforms: {\n            tVelocity: ()=>({value: !this.isDisabled() ? this.target?.texture:null}),\n        },\n        extraDefines: {\n            ['HAS_VELOCITY_BUFFER']: ()=>!this.isDisabled() && this.target?.texture ? 1 : undefined,\n        },\n        priority: 100,\n        isCompatible: () => true,\n    }\n\n    setDirty() {\n        super.setDirty();\n        this.unpackExtension.setDirty?.()\n    }\n\n    protected _beforeRender(scene: IScene, camera: ICamera, renderManager: IRenderManager): boolean {\n        if (!super._beforeRender(scene, camera, renderManager)) return false\n        const pass = this.pass\n        if (!pass) return false\n        if (renderManager.frameCount > 0) return false\n        pass.scene = scene\n        pass.camera = camera\n        camera.updateShaderProperties(pass.overrideMaterial as ShaderMaterial)\n        return true\n    }\n\n}\n\n\ndeclare module 'threepipe' {\n    interface IMaterialUserData {\n        [VelocityBufferPlugin.PluginType]?: {\n            /**\n             * Disables rendering to the velocity buffer.\n             */\n            disabled?: boolean\n        }\n    }\n}\nexport class SSVelocityMaterial extends ShaderMaterial {\n\n    constructor() {\n        super({\n            vertexShader: ssVelocityVert,\n            fragmentShader: ssVelocityFrag,\n            uniforms: {\n                cameraNearFar: {value: new Vector2(0.1, 1000)},\n                alphaMap: {value: null},\n                alphaTest: {value: null},\n                alphaMapTransform: {value: /* @__PURE__*/ new Matrix3()},\n                currentProjectionViewMatrix: {value: new Matrix4()},\n                lastProjectionViewMatrix: {value: new Matrix4()},\n            },\n            blending: NoBlending, // todo?\n        })\n    }\n\n    extraUniformsToUpload: Record<string, IUniform> = {\n        modelMatrixPrevious: {value: new Matrix4().identity()},\n    }\n\n    private _previousWorldMatrices: Record<string, Matrix4> = {}\n\n    // this gets called for each object.\n    onBeforeRender(_r: WebGLRenderer, _s: Scene, _c: Camera, _geometry: BufferGeometry, object: IObject3D, group: Group) {\n        super.onBeforeRender(_r, _s, _c, _geometry, object, group)\n        const prevMatrix = this._previousWorldMatrices[object.uuid]\n        this.extraUniformsToUpload.modelMatrixPrevious.value.copy(prevMatrix ?? object.matrixWorld)\n\n        // todo: make sure all objects are only rendered once.\n        if (prevMatrix) {\n            prevMatrix.copy(object.matrixWorld)\n        } else {\n            this._previousWorldMatrices[object.uuid] = object.matrixWorld.clone()\n        }\n\n        // todo: add support for all this in the shaders.\n        let mat = object.material\n\n        if (Array.isArray(mat)) { // todo: add support for multi materials.\n            mat = mat[0]\n        }\n        this.uniforms.alphaMap.value = mat?.alphaMap ?? null\n        this.uniforms.alphaTest.value = !mat || !mat.alphaTest || mat.alphaTest < 0.0000001 ? 0.001 : mat.alphaTest\n\n        let x = this.uniforms.alphaMap.value ? 1 : undefined\n        if (x !== this.defines.USE_ALPHAMAP) {\n            if (x === undefined) delete this.defines.USE_ALPHAMAP\n            else this.defines.USE_ALPHAMAP = x\n            this.needsUpdate = true\n        }\n        x = mat?.userData.ALPHA_I_RGBA_PACKING ? 1 : undefined\n        if (x !== this.defines.ALPHA_I_RGBA_PACKING) {\n            if (x === undefined) delete this.defines.ALPHA_I_RGBA_PACKING\n            else this.defines.ALPHA_I_RGBA_PACKING = x\n            this.needsUpdate = true\n        }\n\n        this.side = mat?.side ?? DoubleSide\n    }\n}\n","#ifdef USE_ALPHAMAP\n#define USE_UV\n#endif\n#include <uv_pars_vertex>\n#include <batching_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\n//varying vec3 vViewPosition;\n\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldPositionPrevious;\n\nuniform mat4 modelMatrixPrevious;\n\nvoid main() {\n\n    #include <uv_vertex>\n    #include <batching_vertex>\n    #include <skinbase_vertex>\n\n    #include <begin_vertex>\n    #include <morphtarget_vertex>\n    #include <skinning_vertex>\n    #include <displacementmap_vertex>\n\n    // project_vertex\n\n    vec4 mvPosition = vec4( transformed, 1.0 );\n\n    #ifdef USE_INSTANCING\n\n    mvPosition = instanceMatrix * mvPosition;\n\n    #endif\n\n    vWorldPosition = (modelMatrix * mvPosition).xyz;\n    vWorldPositionPrevious = (modelMatrixPrevious * mvPosition).xyz;\n\n    mvPosition = modelViewMatrix * mvPosition;\n\n    gl_Position = projectionMatrix * mvPosition;\n\n    #include <logdepthbuf_vertex>\n    #include <clipping_planes_vertex>\n\n    //    vViewPosition = - mvPosition.xyz;\n\n}\n","varying vec3 vWorldPosition;\nvarying vec3 vWorldPositionPrevious;\nuniform mat4 currentProjectionViewMatrix;\nuniform mat4 lastProjectionViewMatrix;\n\nvec2 computeScreenSpaceVelocity2() {\n    vec4 currentPositionClip = currentProjectionViewMatrix * vec4(vWorldPosition, 1.0);\n    vec4 prevPositionClip = lastProjectionViewMatrix * vec4(vWorldPositionPrevious, 1.0);\n\n    vec2 currentPositionNDC = currentPositionClip.xy / currentPositionClip.w;\n    vec2 prevPositionNDC = prevPositionClip.xy / prevPositionClip.w;\n\n    if(prevPositionNDC.x >= 1.0 || prevPositionNDC.x <= -1.0 || prevPositionNDC.x >= 1.0 || prevPositionNDC.y <= -1.0) {\n        return vec2(0.0);\n    }\n    return 0.5 * (currentPositionNDC - prevPositionNDC);\n}\n\nvoid main() {\n    vec2 velocity = clamp(computeScreenSpaceVelocity2(), -1.0, 1.0);\n    velocity = sign(velocity) * pow(abs(velocity), vec2(1./4.));\n    velocity = velocity * 0.5 + 0.5;\n    gl_FragColor = vec4(velocity.x, velocity.y, 1., 1.);\n\n    //    float speed = length(computeScreenSpaceVelocity2());\n    //    gl_FragColor = vec4(speed, speed, speed, 1.);\n}\n","import {\n    AdditiveBlending,\n    CopyShader,\n    ExtendedShaderPass,\n    GBufferPlugin,\n    GBufferUpdater,\n    GBufferUpdaterContext,\n    generateUiConfig,\n    HalfFloatType,\n    IMaterial,\n    IMaterialUserData,\n    IPassID,\n    IPipelinePass,\n    IViewerEvent,\n    IWebGLRenderer,\n    matDefineBool,\n    MaterialExtension,\n    NoBlending,\n    onChange,\n    onChange2,\n    PipelinePassPlugin,\n    serialize,\n    ThreeViewer,\n    uiConfig,\n    uiConfigMaterialExtension,\n    uiFolderContainer,\n    UiObjectConfig,\n    uiSlider,\n    uiToggle,\n    uniform,\n    updateBit,\n    Vector2,\n    Vector4,\n    WebGLRenderTarget,\n} from 'threepipe'\nimport hdrBloom from './shaders/hdrBloom.glsl'\n\nconst passId = 'bloom'\ntype BloomPassId = typeof passId\n\n/**\n * Bloom Plugin\n *\n * Adds HDR Bloom post-processing effect to the scene\n * @category Plugins\n */\nexport class BloomPlugin\n    extends PipelinePassPlugin<BloomPluginPass<BloomPassId>, BloomPassId>\n    implements GBufferUpdater {\n    static readonly PluginType = 'Bloom'\n    static readonly OldPluginType = 'BloomPlugin' // todo swap\n    readonly passId = passId\n\n    readonly materialExtension: MaterialExtension = uiConfigMaterialExtension(this._getUiConfig.bind(this), BloomPlugin.PluginType)\n\n    protected _createPass() {\n        const pass = new BloomPluginPass(this.passId, Math.min(8, this._viewer?.renderManager.maxHDRIntensity || 8))\n        return pass\n    }\n\n    constructor(enabled = true) {\n        super()\n        this.enabled = enabled\n    }\n\n    @uiConfig(undefined, {unwrapContents: true}) declare protected _pass?: BloomPluginPass<BloomPassId>\n\n    dependencies = [GBufferPlugin]\n\n    onAdded(viewer: ThreeViewer) {\n        super.onAdded(viewer)\n        const gbuffer = viewer.getPlugin(GBufferPlugin)\n        if (gbuffer) {\n            gbuffer.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags.bind(this))\n            this._pass!.material.registerMaterialExtensions([gbuffer.unpackExtension])\n        } else viewer.addEventListener('addPlugin', this._onPluginAdd) // todo subscribe to remove plugin\n        viewer.materialManager.registerMaterialExtension(this.materialExtension)\n    }\n    private _onPluginAdd = (e: IViewerEvent)=>{ // not really required since gbuffer is now a dependency\n        if (e.plugin?.constructor?.PluginType !== GBufferPlugin.PluginType) return\n        const gbuffer = e.plugin as GBufferPlugin\n        gbuffer.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags.bind(this))\n        this._pass?.material.registerMaterialExtensions([gbuffer.unpackExtension])\n        this._viewer?.removeEventListener('addPlugin', this._onPluginAdd)\n    }\n    onRemove(viewer: ThreeViewer) {\n        viewer.removeEventListener('addPlugin', this._onPluginAdd)\n        const gbuffer = viewer.getPlugin(GBufferPlugin)\n        gbuffer?.unregisterGBufferUpdater(this.constructor.PluginType)\n        gbuffer && this._pass?.material.unregisterMaterialExtensions([gbuffer.unpackExtension])\n        viewer.materialManager.unregisterMaterialExtension(this.materialExtension)\n        super.onRemove(viewer)\n    }\n\n    updateGBufferFlags(data: Vector4, c: GBufferUpdaterContext): void {\n        if (!c.material || !c.material.userData) return\n        const disabled = c.material.userData[BloomPlugin.PluginType]?.enable === false ||\n            c.material.userData.pluginsDisabled\n        const x = disabled ? 0 : 1\n        data.w = updateBit(data.w, 2, x)\n    }\n\n    uiConfig: UiObjectConfig = {\n        type: 'folder',\n        label: 'Bloom Plugin',\n        onChange: this.setDirty.bind(this),\n        children: [\n            ...generateUiConfig(this) || [],\n        ],\n    }\n\n    static AddBloomData(material: IMaterial, params?: IMaterialUserData['Bloom'], setDirty = true): IMaterialUserData['Bloom']|null {\n        const ud = material?.userData\n        if (!ud) return null\n        if (!ud[BloomPlugin.PluginType]) {\n            ud[BloomPlugin.PluginType] = {}\n        }\n        const data = ud[BloomPlugin.PluginType]!\n        data.enable = true\n        params && Object.assign(data, params)\n        if (setDirty && material.setDirty) material.setDirty()\n        return data\n    }\n\n    /**\n     * This uiConfig is added to each material by extension\n     * @param material\n     * @private\n     */\n    private _getUiConfig(material: IMaterial) {\n        const config: UiObjectConfig = {\n            type: 'folder',\n            label: 'Bloom',\n            children: [\n                {\n                    type: 'checkbox',\n                    label: 'Enabled',\n                    get value() {\n                        return material.userData[BloomPlugin.PluginType]?.enable ?? true\n                    },\n                    set value(v) {\n                        let data = material.userData[BloomPlugin.PluginType]\n                        if (v === data?.enable) return\n                        if (!data) data = BloomPlugin.AddBloomData(material, undefined, false)!\n                        data.enable = v\n                        material.setDirty()\n                        config.uiRefresh?.(true, 'postFrame')\n                    },\n                    onChange: this.setDirty,\n                },\n            ],\n        }\n        return config\n    }\n}\n\n@uiFolderContainer('Bloom Pass')\nexport class BloomPluginPass<Tid extends IPassID> extends ExtendedShaderPass implements IPipelinePass<Tid> {\n    uiConfig?: UiObjectConfig = undefined\n    before = ['screen']\n    after = ['render', 'progressive']\n    required = ['render']\n    public readonly passId: Tid\n\n    constructor(pid: Tid, maxIntensity = 16) {\n        super({\n            vertexShader: CopyShader.vertexShader,\n            defines: {\n                ['PASS_STEP']: 1,\n                ['MAX_INTENSITY']: Math.min(maxIntensity, 16),\n            },\n            uniforms: {\n                tSource: {value: null},\n                tDiffuse: {value: null},\n                // intensity: {value: 0.2},\n                opacity: {value: 1.0},\n                // prefilter: {value: new Vector4(1, 0.5, 0, 0)},\n                tDiffuseSize: {value: new Vector2()},\n                weight: {value: 1},\n                // tNormalDepth: {value: null},\n                // tGBufferFlags: {value: null},\n            },\n            fragmentShader: hdrBloom,\n        }, 'tDiffuse', 'tSource')\n        this.passId = pid\n        this._updateWeights = this._updateWeights.bind(this)\n        this._thresholdsUpdated = this._thresholdsUpdated.bind(this)\n        this._updateWeights()\n        this._thresholdsUpdated()\n        this.clear = true\n\n        // for tweakpane UI. todo: check if required and why\n        // ;(this as any).userData = {setDirty: ()=>{\n        //         this.setDirty()\n        //     }}\n\n    }\n\n    @uniform() prefilter = new Vector4(2, 0.5, 0, 0)\n\n    @uiSlider('Threshold', [0, 2])\n    @onChange(BloomPluginPass.prototype._thresholdsUpdated)\n    @serialize() threshold = 2\n\n    @uiSlider('Soft Threshold', [0, 1])\n    @onChange(BloomPluginPass.prototype._thresholdsUpdated)\n    @serialize() softThreshold = 0.5\n\n    @uiSlider('Intensity', [0, 3])\n    @serialize() @uniform() intensity = 0.2\n\n    @uiToggle('Background Bloom')\n    @serialize()\n    @matDefineBool('BACKGROUND_BLOOM')\n        backgroundBloom = false\n\n    @uiSlider('Iterations', [2, 7], 1)\n    @onChange2(BloomPluginPass.prototype._updateWeights)\n    @serialize() bloomIterations = 4\n\n    private _currentIterations = 0 // could be less than bloomIterations based on canvas size\n\n    @uiSlider('Radius', [0, 1], 0.01)\n    @onChange2(BloomPluginPass.prototype._updateWeights)\n    @serialize() radius = 0.6\n\n    @uiSlider('Power', [0.2, 10], 0.01)\n    @onChange2(BloomPluginPass.prototype._updateWeights)\n    @serialize() power = 1\n\n    private _thresholdsUpdated() {\n        this.prefilter.x = this.threshold\n        this.prefilter.y = this.softThreshold\n        this.prefilter.z = 2 * this.prefilter.x * this.prefilter.y\n        this.prefilter.w = this.uniforms?.prefilter ? .125 / (this.uniforms.prefilter.value.z + 0.00001) : 0\n    }\n\n    @uiToggle('Debug')\n        bloomDebug = false\n\n    private _weights: any = []\n\n    render(renderer: IWebGLRenderer, writeBuffer?: WebGLRenderTarget | null, readBuffer?: WebGLRenderTarget, deltaTime?: number, maskActive?: boolean) {\n        const renderManager = renderer.renderManager\n        // prefilter\n        this.material.defines.PASS_STEP = 0\n\n        this.clear = true\n\n        this.needsSwap = false\n\n        const source = readBuffer\n        if (!source) {\n            console.warn('BloomPluginPass: No source to read from')\n            return\n        }\n        this.needsSwap = true\n\n        let sizeMultiplier = 0.5 // todo are we starting with 0.25? this should be 1 maybe? but more memory...\n        let width = source.width * sizeMultiplier\n        let height = source.height * sizeMultiplier\n        const textures: any[] = []\n        let currentDestination = renderManager.getTempTarget({sizeMultiplier: 1, type: HalfFloatType}) as any as WebGLRenderTarget\n        textures.push(currentDestination)\n        let currentSource = source\n        this.material.needsUpdate = true\n        this.material.uniforms.weight.value = this._weights[0]\n\n\n        super.render(renderer, currentDestination, currentSource, deltaTime, maskActive)\n\n        currentSource = currentDestination\n\n        const ci = this._currentIterations\n\n        let i = 1\n        const iter = Math.max(2, this.bloomIterations)\n        for (; i < iter; i++) {\n            width /= 2\n            height /= 2\n            sizeMultiplier /= 2\n            if (height < 2 || width < 2) {\n                break\n            }\n            currentDestination = renderManager.getTempTarget({sizeMultiplier, type: HalfFloatType}) as any as WebGLRenderTarget\n            textures.push(currentDestination)\n\n            this.material.defines.PASS_STEP = 1\n\n            let modifiedWeight = this._weights[i]\n            // if(i > 1)\n            {\n                modifiedWeight = this._weights[i - 1] !== 0 ? this._weights[i] / this._weights[i - 1] : this._weights[i]\n            }\n            this.material.uniforms.weight.value = modifiedWeight\n            this.material.needsUpdate = true\n            super.render(renderer, currentDestination, currentSource, deltaTime, maskActive)\n\n            currentSource = currentDestination\n            this._currentIterations = i + 1\n        }\n\n        // console.log(this._currentIterations)\n\n        if (ci !== this._currentIterations)\n            this._updateWeights(false)\n\n        this.clear = false\n\n        const oldAutoClear = renderer.autoClear\n        renderer.autoClear = false\n        for (i -= 2; i >= 0; i--) {\n            currentDestination = textures[i]\n            textures[i] = undefined\n\n            this.material.defines.PASS_STEP = 2\n            this.material.transparent = true\n            this.material.blending = AdditiveBlending\n            // this.material.blendSrc = OneFactor;\n            // this.material.blendDst = OneFactor;\n            this.material.needsUpdate = true\n            renderer.autoClear = false\n            super.render(renderer, currentDestination, currentSource, deltaTime, maskActive)\n            this.material.blending = NoBlending\n\n            renderManager.releaseTempTarget(currentSource as any)\n\n            currentSource = currentDestination\n        }\n\n        this.clear = true\n\n        renderer.autoClear = oldAutoClear\n\n        renderer.autoClear = true\n\n        if (this.bloomDebug) {\n            this.material.defines.PASS_STEP = 4\n            this.material.needsUpdate = true\n            super.render(renderer, writeBuffer, currentSource, deltaTime, maskActive)\n        } else {\n            this.uniforms.tSource.value = source.texture\n            this.material.defines.PASS_STEP = 3\n            this.material.needsUpdate = true\n            super.render(renderer, writeBuffer, currentSource, deltaTime, maskActive)\n            this.uniforms.tSource.value = null\n        }\n        renderManager.releaseTempTarget(currentSource as any)\n    }\n\n    private _updateWeights(setDirty = true) {\n        if (!this._weights) return // for first time onChange.\n        const radius = Math.max(Math.min(this.radius, 1), 0)\n        const iter = Math.max(2, this._currentIterations || this.bloomIterations)\n        const delta = 1 / (iter - 1)\n        for (let i = 0; i < iter; i++) {\n            let f = i * delta + 0.1\n            let oneMinusF = 1.2 - f\n            f = Math.pow(f, this.power)\n            oneMinusF = Math.pow(oneMinusF, this.power)\n            this._weights[i] = oneMinusF * (1 - radius) + f * radius\n        }\n        if (setDirty !== false) this.setDirty()\n    }\n\n}\n\ndeclare module 'threepipe' {\n    interface IMaterialUserData {\n        [BloomPlugin.PluginType]?: {\n            enable?: boolean\n        }\n    }\n}\n","#include <packing>\n// todo use this after threepipe update\n// include <gbuffer_unpack>\n\nuniform float intensity;\nuniform float opacity;\nuniform vec2 tDiffuseSize;\nvarying vec2 vUv;\nuniform float weight;\n\n#if PASS_STEP == 0\nuniform vec4 prefilter;\nvec4 Prefilter (vec4 c) {\n    //    float brightness = max(c.r, max(c.g, c.b));\n    //    float contribution = max(0., brightness - prefilter.x);\n    //    contribution /= max(brightness, 0.00001);\n    //    return vec4((c.rgb) * contribution, c.a);\n    //    return (c - vec3(prefilterThreshold)) * contribution;\n\n    #ifdef HAS_GBUFFER\n    #if !BACKGROUND_BLOOM\n    if(getDepth(vUv) > 0.999) {\n        return vec4(0.0);\n    }\n    #endif\n    #endif\n\n    float brightness = max(c.r, max(c.g, c.b));\n    float soft = brightness + prefilter.x * (prefilter.y - 1.);\n    soft = clamp(soft, 0., prefilter.z);\n    soft = soft * soft * prefilter.w;\n    float contribution = max(soft, brightness - prefilter.x);\n    contribution /= max(brightness, 0.001);\n    return vec4(c.rgb * contribution, c.a);\n\n}\n#endif\n\nvec4 Sample (vec2 uv) {\n    return min(vec4(MAX_INTENSITY, MAX_INTENSITY, MAX_INTENSITY, 1.), tDiffuseTexelToLinear( texture2D( tDiffuse, uv ) ));\n}\n\nvec4 SampleBox (vec2 uv, float delta) {\n    vec4 o = vec2(-delta, delta).xxyy / tDiffuseSize.xyxy;\n    vec4 s =\n    Sample(uv + o.xy) + Sample(uv + o.zy) +\n    Sample(uv + o.xw) + Sample(uv + o.zw);\n    return s * 0.25;\n}\n\nint getBloomBit(in int number) {\n    #ifdef WebGL2Context\n    return (number/4) % 2;\n    #else\n    return int(mod(floor(float(number)/4.), 2.));\n    #endif\n}\n\nvoid main() {\n    #if PASS_STEP == 0 //prefilter + down\n\n    #ifdef GBUFFER_HAS_FLAGS\n    int doBloom = getBloomBit(getGBufferFlags(vUv).a);\n    #else\n    int doBloom = 1;\n    #endif\n\n    gl_FragColor = float(doBloom) * weight * Prefilter(SampleBox(vUv, 1.));\n    gl_FragColor.a = 1.;\n\n    #elif PASS_STEP == 1 //down\n\n    gl_FragColor = weight * (SampleBox(vUv, 1.));\n    gl_FragColor.a = 1.;\n\n    #elif PASS_STEP == 2 //up\n\n    gl_FragColor = (SampleBox(vUv, 0.5));\n    gl_FragColor.a = 1.;\n\n    #elif PASS_STEP == 3 //final\n\n    vec4 texel = tSourceTexelToLinear ( texture2D(tSource, vUv) );\n    vec4 bloom = intensity * SampleBox(vUv, 0.5).rgba;\n    float brightness = max(bloom.r, max(bloom.g, bloom.b));\n    texel.rgb += bloom.rgb;\n    texel.a = min(1., texel.a + brightness);\n    gl_FragColor = texel;\n\n    #elif PASS_STEP == 4 //debug\n\n    vec4 texel = vec4(0.);\n    texel.rgb += intensity * SampleBox(vUv, 0.5).rgb;\n    texel.a = 1.;\n    gl_FragColor = texel;\n\n    #endif\n\n    #include <colorspace_fragment>\n\n}\n","import {\n    bindToValue,\n    Color,\n    CreateRenderTargetOptions,\n    ExtendedShaderMaterial,\n    ExtendedShaderPass,\n    FrameFadePlugin,\n    GBufferPlugin,\n    generateUiConfig,\n    HalfFloatType,\n    ICamera,\n    IPassID,\n    IPipelinePass,\n    IRenderManager,\n    IScene,\n    IViewerEvent,\n    IViewerPlugin,\n    IWebGLRenderer,\n    LinearSRGBColorSpace,\n    NearestFilter,\n    now,\n    PickingPlugin,\n    PipelinePassPlugin,\n    RGBAFormat,\n    serialize,\n    shaderUtils,\n    ThreeViewer,\n    uiFolderContainer,\n    UiObjectConfig,\n    uiSlider,\n    uiToggle,\n    uniform,\n    Vector2,\n    Vector3,\n    WebGLRenderTarget,\n} from 'threepipe'\nimport dofCombine from './shaders/dofCombine.glsl'\n// import dofBlurBox from './shaders/dofBlurBox.glsl'\nimport dofPoissonBox from './shaders/dofPoissonBox.glsl'\nimport poissonDiskSamples from './shaders/poissonDiskSamples.glsl'\nimport dofComputeCoC from './shaders/dofComputeCoC.glsl'\nimport dofExpandCoC from './shaders/dofExpandCoC.glsl'\n\nconst passId = 'depthOfField'\ntype DepthOfFieldPassId = typeof passId\n\n/**\n * Depth Of Field Plugin\n *\n * Adds a depth of field effect with configurable focal point.\n * @category Plugins\n */\nexport class DepthOfFieldPlugin\n    extends PipelinePassPlugin<DepthOfFieldPluginPass<DepthOfFieldPassId>, DepthOfFieldPassId> {\n    static readonly PluginType = 'DepthOfField'\n    static readonly OldPluginType = 'DepthOfFieldPlugin' // todo swap\n    readonly passId = passId\n\n    @serialize()\n    @uiToggle()\n        enableEdit = false\n\n    @serialize('focalPoint') // todo uiConfig\n    protected _focalPointHit: Vector3 = new Vector3(0, 0, 0)\n\n    @serialize()\n        crossFadeTime = 200 // ms\n\n    // readonly materialExtension: MaterialExtension = uiConfigMaterialExtension(this._getUiConfig.bind(this), DepthOfFieldPlugin.PluginType)\n\n    private _focalPointHitTime = 0\n\n    protected get _frameFadeTime() { return this.crossFadeTime * 2.5 } // ms\n\n    constructor(enabled = true, enableEdit = false) {\n        super()\n        this.enabled = enabled\n        this.enableEdit = enableEdit\n        this._onObjectHit = this._onObjectHit.bind(this)\n        this.setDirty = this.setDirty.bind(this)\n    }\n\n    // todo make this a property.\n    setFocalPoint(p: Vector3, fade = true, showGizmo = false) {\n        this._focalPointHit.copy(p)\n        if (fade) this._viewer?.getPlugin<FrameFadePlugin>('FrameFadePlugin')?.startTransition(this._frameFadeTime)\n        if (showGizmo) this._focalPointHitTime = now()\n        this.setDirty()\n    }\n    getFocalPoint() {\n        return this._focalPointHit\n    }\n\n    protected _onObjectHit(e: any) {\n        if (!this._pass || !e.intersects.intersect || this.isDisabled() || !this.enableEdit) return\n        this._focalPointHit.copy(e.intersects.intersect.point)\n        this._focalPointHitTime = e.time\n        e.intersects.selectedObject = null // this will prevent ObjectPicker to select the object\n        this._viewer?.getPlugin(FrameFadePlugin)?.startTransition(this._frameFadeTime)\n        this.setDirty()\n    }\n\n    protected _createPass() {\n        const pass = new DepthOfFieldPluginPass(this.passId)\n        return pass\n    }\n\n    dependencies = [GBufferPlugin] // todo use gbufferUnpackExtension from render manager to support depth buffer plugin as well.\n\n    onAdded(viewer: ThreeViewer) {\n        super.onAdded(viewer)\n        viewer.addEventListener('addPlugin', this._onPluginAdd)\n        viewer.addEventListener('removePlugin', this._onPluginRemove)\n        this._onPluginAdd({plugin: viewer.getPlugin(GBufferPlugin)})\n        this._onPluginAdd({plugin: viewer.getPlugin(PickingPlugin)})\n        // viewer.materialManager.registerMaterialExtension(this.materialExtension)\n    }\n\n    onRemove(viewer: ThreeViewer) {\n        viewer.removeEventListener('addPlugin', this._onPluginAdd)\n        viewer.removeEventListener('removePlugin', this._onPluginRemove)\n        this._onPluginRemove({plugin: viewer.getPlugin(GBufferPlugin)})\n        this._onPluginRemove({plugin: viewer.getPlugin(PickingPlugin)})\n        super.onRemove(viewer)\n        // viewer.materialManager.unregisterMaterialExtension(this.materialExtension)\n    }\n    private _onPluginAdd = (e: {plugin?: IViewerPlugin} & Partial<IViewerEvent>)=>{ // not really required since gbuffer is now a dependency\n        const plugin = e.plugin\n        if (!plugin) return\n        if (plugin.constructor?.PluginType === GBufferPlugin.PluginType) {\n            const gbuffer = plugin as GBufferPlugin\n            // gbuffer.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags.bind(this))\n            this._pass?.material.registerMaterialExtensions([gbuffer.unpackExtension])\n            this._pass?.computeCocMaterial.registerMaterialExtensions([gbuffer.unpackExtension])\n            this._pass?.expandCocMaterial.registerMaterialExtensions([gbuffer.unpackExtension])\n        }\n        if (plugin.constructor?.PluginType === PickingPlugin.PluginType) {\n            const picking = plugin as PickingPlugin\n            picking.addEventListener('hitObject', this._onObjectHit)\n        }\n    }\n    private _onPluginRemove = (e: {plugin?: IViewerPlugin} & Partial<IViewerEvent>)=>{ // not really required since gbuffer is now a dependency\n        const plugin = e.plugin\n        if (!plugin) return\n        if (plugin.constructor?.PluginType === GBufferPlugin.PluginType) {\n            const gbuffer = e.plugin as GBufferPlugin\n            // gbuffer.unregisterGBufferUpdater(this.constructor.PluginType)\n            this._pass?.material.unregisterMaterialExtensions([gbuffer.unpackExtension])\n            this._pass?.computeCocMaterial.unregisterMaterialExtensions([gbuffer.unpackExtension])\n            this._pass?.expandCocMaterial.unregisterMaterialExtensions([gbuffer.unpackExtension])\n        }\n        if (plugin.constructor?.PluginType === PickingPlugin.PluginType) {\n            const picking = e.plugin as PickingPlugin\n            picking.removeEventListener('hitObject', this._onObjectHit)\n        }\n    }\n\n    uiConfig: UiObjectConfig = {\n        type: 'folder',\n        label: 'DepthOfField',\n        onChange: this.setDirty.bind(this),\n        children: [\n            ...generateUiConfig(this) || [],\n            ()=>this._pass?.uiConfig,\n        ],\n    }\n\n    private _tempVec = new Vector3()\n    protected _beforeRender(scene: IScene, camera: ICamera, renderManager: IRenderManager): boolean {\n        if (!super._beforeRender(scene, camera, renderManager)) return false\n        const pass = this.pass\n        if (!pass) return false\n\n        if (pass.dofBlurMaterial.uniforms.frameCount) // blur mat could change.\n            renderManager?.updateShaderProperties(pass.dofBlurMaterial)\n\n        const cam = camera\n        if (!cam) return false\n\n        cam.updateMatrixWorld(true)\n\n        cam.updateShaderProperties(pass.material) // for cameraNearFar\n\n        cam.getWorldPosition(this._tempVec)\n        this._tempVec.subVectors(this._focalPointHit, this._tempVec)\n\n        pass.focalDepthRange.x = this._tempVec.length()\n        pass.focalDepthRange.x *= cam.getWorldDirection(new Vector3()).dot(this._tempVec.normalize())\n\n        let crossAlpha = (now() - this._focalPointHitTime) / this.crossFadeTime\n        crossAlpha = 1. - Math.min(1, Math.max(0, crossAlpha))\n        if (Math.abs(crossAlpha - pass.crossAlpha) > 0.01) {\n            pass.crossAlpha = crossAlpha\n            this.setDirty()\n        }\n        if (crossAlpha > 0) {\n            const projectedPoint = this._tempVec.copy(this._focalPointHit).project(cam).addScalar(1).divideScalar(2)\n            pass.crossCenter.set(projectedPoint.x, projectedPoint.y)\n\n            pass.computeCocMaterial.uniformsNeedUpdate = true // for cameraNearFar\n            pass.expandCocMaterial.uniformsNeedUpdate = true\n        }\n        return true\n    }\n\n    // region to be done or removed\n\n    // static AddDepthOfFieldData(material: IMaterial, params?: IMaterialUserData['DepthOfField'], setDirty = true): IMaterialUserData['DepthOfField']|null {\n    //     const ud = material?.userData\n    //     if (!ud) return null\n    //     if (!ud[DepthOfFieldPlugin.PluginType]) {\n    //         ud[DepthOfFieldPlugin.PluginType] = {}\n    //     }\n    //     const data = ud[DepthOfFieldPlugin.PluginType]!\n    //     data.enable = true\n    //     params && Object.assign(data, params)\n    //     if (setDirty && material.setDirty) material.setDirty()\n    //     return data\n    // }\n\n    // updateGBufferFlags(data: Vector4, c: GBufferUpdaterContext): void {\n    //     if (!c.material || !c.material.userData) return\n    //     const disabled = c.material.userData[DepthOfFieldPlugin.PluginType]?.enable === false ||\n    //         c.material.userData.pluginsDisabled\n    //     const x = disabled ? 0 : 1\n    //     data.w = updateBit(data.w, 4, x)\n    // }\n\n    /*\n        get depthRange() {\n            return this.pass?.focalDepthRange.y ?? 0\n        }\n\n        set depthRange(v: number) {\n            if (this.pass) this.pass.focalDepthRange.y = v\n            this.setDirty()\n        }\n\n        get nearBlurScale() {\n            return this.pass?.nearFarBlurScale.x ?? 0\n        }\n        set nearBlurScale(v: number) {\n            if (this.pass) this.pass.nearFarBlurScale.x = v\n            this.setDirty()\n        }\n\n        get farBlurScale() {\n            return this.pass?.nearFarBlurScale.y ?? 0\n        }\n        set farBlurScale(v: number) {\n            if (this.pass) this.pass.nearFarBlurScale.y = v\n            this.setDirty()\n        }\n    */\n\n    /**\n     * This uiConfig is added to each material by extension\n     * @param material\n     * @private\n     */\n    // private _getUiConfig(material: IMaterial) {\n    //     const config: UiObjectConfig = {\n    //         type: 'folder',\n    //         label: 'DepthOfField',\n    //         children: [\n    //             {\n    //                 type: 'checkbox',\n    //                 label: 'Enabled',\n    //                 get value() {\n    //                     return material.userData[DepthOfFieldPlugin.PluginType]?.enable ?? true\n    //                 },\n    //                 set value(v) {\n    //                     let data = material.userData[DepthOfFieldPlugin.PluginType]\n    //                     if (v === data?.enable) return\n    //                     if (!data) data = DepthOfFieldPlugin.AddDepthOfFieldData(material, undefined, false)!\n    //                     data.enable = v\n    //                     material.setDirty()\n    //                     config.uiRefresh?.(true, 'postFrame')\n    //                 },\n    //                 onChange: this.setDirty,\n    //             },\n    //         ],\n    //     }\n    //     return config\n    // }\n\n    // endregion\n}\n\n// const dofBlurMaterialBox = new ExtendedShaderMaterial({\n//     uniforms: {\n//         cocTexture: {value: null},\n//         colorTexture: {value: null},\n//         colorTextureSize: {value: new Vector2()},\n//         direction: {value: new Vector2()},\n//     },\n//     vertexShader: shaderUtils.defaultVertex,\n//     fragmentShader:  dofBlurBox,\n// }, ['colorTexture', 'cocTexture'])\nconst dofBlurMaterialPoisson = new ExtendedShaderMaterial({\n    uniforms: {\n        colorTexture: {value: null},\n        colorTextureSize: {value: new Vector2()},\n        direction: {value: new Vector2()},\n        frameCount: {value: 0},\n        blurRadius: {value: 16},\n    },\n    vertexShader: shaderUtils.defaultVertex,\n    fragmentShader: poissonDiskSamples + '\\n' + dofPoissonBox,\n    defines: {\n        ['DOF_MODE']: 1,\n    },\n}, ['colorTexture'])\n\n@uiFolderContainer('DepthOfField Pass')\nexport class DepthOfFieldPluginPass<Tid extends IPassID> extends ExtendedShaderPass implements IPipelinePass<Tid> {\n    uiConfig?: UiObjectConfig = undefined\n    before = ['progressive', 'screen']\n    after = ['render']\n    required = ['render']\n\n    public computeCocMaterial: ExtendedShaderMaterial\n    public expandCocMaterial: ExtendedShaderMaterial\n    public dofBlurMaterial: ExtendedShaderMaterial = dofBlurMaterialPoisson\n    // public dofBlurMaterialBox: ShaderMaterialEncodingSupport = dofBlurMaterialBox\n\n    @bindToValue({obj: 'focalDepthRange', key: 'y'})\n    @uiSlider('Depth Range', [0.25, 3])\n        depthRange: number\n\n    @bindToValue({obj: 'nearFarBlurScale', key: 'x'})\n    @uiSlider('Near Blur Scale', [0, 1])\n        nearBlurScale: number\n\n    @bindToValue({obj: 'nearFarBlurScale', key: 'y'})\n    @uiSlider('Far Blur Scale', [0, 1])\n        farBlurScale: number\n\n    @serialize()\n    @uniform() nearFarBlurScale = new Vector2(0.25, 0.25)\n    @serialize()\n    @uniform() focalDepthRange = new Vector2(0.5, 1.5)\n\n    @uniform() crossCenter = new Vector2(0.5, 0.5)\n\n    @uniform() crossRadius = 0.04\n    @uniform() crossAlpha = 1\n    @uniform() crossColor = new Color(0xff9900)\n    public readonly passId: Tid\n\n    constructor(pid: Tid) {\n        super({\n            uniforms: {\n                colorTexture: {value: null},\n                blurTexture: {value: null},\n                cocTexture: {value: null},\n                cocTextureSize: {value: new Vector2()},\n                cameraNearFar: {value: new Vector2()},\n            },\n            vertexShader: shaderUtils.defaultVertex,\n            fragmentShader: dofCombine,\n        }, 'colorTexture', 'cocTexture', 'blurTexture')\n        this.passId = pid\n\n        this.computeCocMaterial = new ExtendedShaderMaterial({\n            uniforms: {\n                colorTexture: {value: null},\n                cameraNearFar: this.uniforms.cameraNearFar,\n                nearFarBlurScale: this.uniforms.nearFarBlurScale,\n                focalDepthRange: this.uniforms.focalDepthRange,\n            },\n            vertexShader: shaderUtils.defaultVertex,\n            fragmentShader: dofComputeCoC,\n        }, ['colorTexture'])\n        // this.computeCocMaterial.uniforms.NearFarBlurScale.value.copy(this.nearFarBlurScale_)\n\n        this.expandCocMaterial = new ExtendedShaderMaterial({\n            uniforms: {\n                colorTexture: {value: null},\n                colorTextureSize: {value: new Vector2()},\n                direction: {value: new Vector2()},\n                nearFarBlurScale: this.uniforms.nearFarBlurScale,\n            },\n            vertexShader: shaderUtils.defaultVertex,\n            fragmentShader: dofExpandCoC,\n        }, ['colorTexture'])\n\n        // todo\n        // this.clear = true\n\n    }\n\n    render(renderer: IWebGLRenderer, writeBuffer?: WebGLRenderTarget | null, readBuffer?: WebGLRenderTarget, deltaTime?: number, maskActive?: boolean) {\n        if (!this.enabled) return\n        if (!readBuffer) {\n            console.error('DepthOfFieldPluginPass: No readBuffer')\n            return\n        }\n        const renderManager = renderer.renderManager\n\n        // const oldClearColor = renderer.getClearColor(new Color())\n        // const oldClearAlpha = renderer.getClearAlpha()\n        // const oldAutoClear = renderer.autoClear\n        // renderer.autoClear = true\n\n        const halfPars: CreateRenderTargetOptions = {\n            minFilter: NearestFilter, magFilter: NearestFilter,\n            // type: UnsignedByteType,\n            // encoding: RGBM16Encoding,\n            type: HalfFloatType,\n            // encoding: LinearEncoding,\n            colorSpace: LinearSRGBColorSpace,\n            sizeMultiplier: 0.5,\n            // samples: 1,\n            format: RGBAFormat,\n            depthBuffer: false,\n            generateMipmaps: false,\n        }\n\n        const cocRt = renderManager.getTempTarget(halfPars)\n        const renderTargetBlurTemp = renderManager.getTempTarget(halfPars)\n\n        // 1. Downsample the Original texture, and store coc in the alpha channel\n        this.computeCocMaterial.uniforms.colorTexture.value = readBuffer.texture\n        renderManager.blit(cocRt, {material: this.computeCocMaterial})\n\n        // 2. Blur Near field coc\n        this.expandCocMaterial.uniforms.colorTexture.value = cocRt.texture\n        this.expandCocMaterial.uniforms.direction.value.set(1, 0)\n        renderManager.blit(renderTargetBlurTemp, {material: this.expandCocMaterial})\n        this.expandCocMaterial.uniforms.colorTexture.value = renderTargetBlurTemp.texture\n        this.expandCocMaterial.uniforms.direction.value.set(0, 1)\n        renderManager.blit(cocRt, {material: this.expandCocMaterial})\n\n        // 3. Blur Dof\n        // if (this.dofBlurType_ === 1) {\n        if (this.dofBlurMaterial.uniforms.frameCount) {\n            this.dofBlurMaterial.uniforms.colorTexture.value = cocRt.texture\n            renderManager.blit(renderTargetBlurTemp, {material: this.dofBlurMaterial})\n        } else {\n            const renderTargetBlurTemp2 = renderManager.getTempTarget(halfPars)\n            this.dofBlurMaterial.uniforms.cocTexture.value = cocRt.texture\n            this.dofBlurMaterial.uniforms.colorTexture.value = cocRt.texture\n            this.dofBlurMaterial.uniforms.direction.value.set(1, 0)\n            renderManager.blit(renderTargetBlurTemp2, {material: this.dofBlurMaterial})\n            this.dofBlurMaterial.uniforms.colorTexture.value = renderTargetBlurTemp2.texture\n            this.dofBlurMaterial.uniforms.direction.value.set(0, 1)\n            renderManager.blit(renderTargetBlurTemp, {material: this.dofBlurMaterial})\n            renderManager.releaseTempTarget(renderTargetBlurTemp2)\n        }\n\n        // 4. Dof Combine\n        this.material.uniforms.blurTexture.value = renderTargetBlurTemp.texture\n        this.material.uniforms.cocTexture.value = cocRt.texture\n        super.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive)\n\n        renderManager.releaseTempTarget(cocRt)\n        renderManager.releaseTempTarget(renderTargetBlurTemp)\n\n    }\n\n}\n\n// declare module 'threepipe' {\n//     interface IMaterialUserData {\n// [DepthOfFieldPlugin.PluginType]?: {\n//     enable?: boolean\n// }\n// }\n// }\n","#include <common>\n#include <packing>\n\nvarying vec2 vUv;\n//uniform sampler2D blurTexture;\nuniform vec2 cocTextureSize;\nuniform vec2 nearFarBlurScale;\nuniform vec2 cameraNearFar;\nuniform vec2 focalDepthRange;\n\nuniform vec2 crossCenter;\nuniform float crossRadius;\nuniform float crossAlpha;\nuniform vec3 crossColor;\n\nfloat smoothBoundary(float d, float smooothFactor) {\n    smooothFactor *= 0.5;\n    float value = smoothstep(-smooothFactor,smooothFactor, d);\n    return value;\n}\n\nfloat circle( vec2 p, float r ) {\n    return min((length(p) - r), -(length(p) - r - 0.01));\n}\n\nfloat computeCoc() {\n    float depth = getDepth(vUv);\n    if(depth > 1.0 - 0.01) return max(nearFarBlurScale.x, nearFarBlurScale.y);\n    depth = mix(cameraNearFar.x, cameraNearFar.y, depth);\n    float coc = (depth - focalDepthRange.x)/focalDepthRange.y;\n    coc = clamp(coc, -1., 1.);\n    return (coc > 0.0 ? coc * nearFarBlurScale.y : coc * nearFarBlurScale.x);\n}\n\nvoid main() {\n    vec4 blur = blurTextureTexelToLinear(texture2D(blurTexture, vUv));\n    float scale = 0.5;\n    blur += blurTextureTexelToLinear(texture2D(blurTexture, vUv + scale * vec2(1.0, 1.0) / cocTextureSize));\n    blur += blurTextureTexelToLinear(texture2D(blurTexture, vUv + scale * vec2(-1.0, 1.0) / cocTextureSize));\n    blur += blurTextureTexelToLinear(texture2D(blurTexture, vUv + scale * vec2(-1.0, -1.0) / cocTextureSize));\n    blur += blurTextureTexelToLinear(texture2D(blurTexture, vUv + scale * vec2(1.0, -1.0) / cocTextureSize));\n    blur /= 5.0;\n\n    vec2 uvNearest = (floor(vUv * cocTextureSize) + 0.5) / cocTextureSize;\n    float coc = abs(min(2. * cocTextureTexelToLinear(texture2D(cocTexture, uvNearest)).a - 1., computeCoc()));\n    //coc = clamp(coc * coc * 8.0, 0.0, 1.0);\n    float cocLower = 0.005;\n    float cocHigher = 0.3;\n    vec4 outColor = vec4(mix(colorTextureTexelToLinear(texture2D(colorTexture, vUv)).rgb, blur.rgb, smoothstep(cocLower, cocHigher, coc)), 1.0);\n\n    vec2 d = vUv - crossCenter;\n\n    if(length(d) > crossRadius + 0.05) {\n        float dist = circle(d, crossRadius);\n        gl_FragColor = outColor;\n    } else {\n        d.x *= cocTextureSize.x/cocTextureSize.y;\n        float dist = circle(d, crossRadius);\n        dist = smoothBoundary(dist, 2. * fwidth(dist));\n        vec4 color = outColor;\n        vec3 dofCircleColor = mix(crossColor, color.rgb, 1.-crossAlpha);\n        gl_FragColor = vec4(mix(color.rgb, dofCircleColor, dist), color.a);\n\n    }\n\n    #include <colorspace_fragment>\n\n}\n","#include <common>\n#include <packing>\nvarying vec2 vUv;\nuniform vec2 nearFarBlurScale;\nuniform vec2 cameraNearFar;\nuniform vec2 focalDepthRange;\n\nfloat computeCoc() {\n    float depth = getDepth(vUv);\n    if(depth == 1.0) return max(nearFarBlurScale.x, nearFarBlurScale.y);\n    depth = mix(cameraNearFar.x, cameraNearFar.y, depth);\n    float coc = (depth - focalDepthRange.x)/focalDepthRange.y;\n    coc = clamp(coc, -1., 1.);\n    return (coc > 0.0 ? coc * nearFarBlurScale.y : coc * nearFarBlurScale.x);\n}\n\nvoid main() {\n    gl_FragColor = vec4(colorTextureTexelToLinear(texture2D(colorTexture, vUv)).rgb, 0.5 * computeCoc() + 0.5);\n\n    #include <colorspace_fragment>\n}\n","#include <common>\n#include <gbuffer_unpack>\nvarying vec2 vUv;\nuniform vec2 colorTextureSize;\nuniform vec2 direction;\nuniform vec2 nearFarBlurScale;\nconst float MAXIMUM_BLUR_SIZE = 4.0;\n\nfloat expandNear(const in vec2 offset, const in bool isBackground) {\n    float coc = 0.0;\n    vec2 sampleOffsets = MAXIMUM_BLUR_SIZE * offset / 5.0;\n    float coc0 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv)).a - 1.;\n    float coc1 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv - 5.0 * sampleOffsets)).a - 1.;\n    float coc2 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv - 4.0 * sampleOffsets)).a - 1.;\n    float coc3 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv - 3.0 * sampleOffsets)).a - 1.;\n    float coc4 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv - 2.0 * sampleOffsets)).a - 1.;\n    float coc5 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv - 1.0 * sampleOffsets)).a - 1.;\n    float coc6 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv + 1.0 * sampleOffsets)).a - 1.;\n    float coc7 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv + 2.0 * sampleOffsets)).a - 1.;\n    float coc8 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv + 3.0 * sampleOffsets)).a - 1.;\n    float coc9 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv + 4.0 * sampleOffsets)).a - 1.;\n    float coc10 = 2. * colorTextureTexelToLinear(texture2D(colorTexture, vUv + 5.0 * sampleOffsets)).a - 1.;\n\n    if(isBackground){\n        coc = abs(coc0) * 0.095474 +\n        (abs(coc1) + abs(coc10)) * 0.084264 +\n        (abs(coc2) + abs(coc9)) * 0.088139 +\n        (abs(coc3) + abs(coc8)) * 0.091276 +\n        (abs(coc4) + abs(coc7)) * 0.093585 +\n        (abs(coc5) + abs(coc6)) * 0.094998;\n    } else {\n        coc = min(coc0, 0.0);\n        coc = min(coc1 * 0.3, coc);\n        coc = min(coc2 * 0.5, coc);\n        coc = min(coc3 * 0.75, coc);\n        coc = min(coc4 * 0.8, coc);\n        coc = min(coc5 * 0.95, coc);\n        coc = min(coc6 * 0.95, coc);\n        coc = min(coc7 * 0.8, coc);\n        coc = min(coc8 * 0.75, coc);\n        coc = min(coc9 * 0.5, coc);\n        coc = min(coc10 * 0.3, coc);\n        if(abs(coc0) > abs(coc))\n        coc = coc0;\n    }\n    return coc;\n}\n\nvoid main() {\n    vec2 offset = 2. * direction/colorTextureSize;\n    bool isBackground = getDepth(vUv) > 1.0 - 0.001;\n    float coc = expandNear(offset, isBackground);\n    gl_FragColor = vec4(colorTextureTexelToLinear(texture2D(colorTexture, vUv)).rgb, 0.5 * coc + 0.5);\n\n    #include <colorspace_fragment>\n}\n","#ifndef SSRT_PARS_SNIP\n#define SSRT_PARS_SNIP\n\n#define pow2(a) a*a\n\nfloat getDepth2(const in vec2 uv, const in float lod) {\n    float viewDepth = getDepth(uv);\n    return depthToViewZ(viewDepth);\n}\n\n#define LOD_DEPTH 1.0// todo: generate mipmap depth and set.\n#define LOD_COLOR 5.0\n\n// multiple of 4\n//#define I_STEP_COUNT (1./float(STEP_COUNT))\n\nvoid _traceRay(in vec4 ray_origin, in vec4 ray_dir, in float tolerance, inout vec3 state, in int loopMax, in float iStepCount){\n    vec4 sample_uv;\n    float d, hit;\n    float dLod = 0.;//floor(LOD_DEPTH * roughness);\n\n    #pragma unroll_loop_start\n    for (int i = 0; i < 8; i++){\n        if ( UNROLLED_LOOP_INDEX < loopMax ){\n\n            sample_uv = ray_origin + ray_dir * state.y;\n            d = getDepth2(sample_uv.xy, dLod);\n            d = sample_uv.z/sample_uv.w - d;\n            if (abs(d + tolerance) < tolerance){\n\n                hit = clamp(state.x / (state.x - d), 0., 1.) - 1.;\n                hit = (state.y + hit * iStepCount);\n                state.z = min(state.z, hit);\n\n            }\n            state.x = d;//depth diff\n            state.y += 1. * iStepCount;\n\n        }\n    }\n    #pragma unroll_loop_end\n\n}\n\nvec3 traceRay(in vec3 ray_origin_view, in vec3 ray_dir_view, in float tolerance, inout vec3 state, in int _STEP_COUNT){\n    vec4 sample_uv;\n//    float stepCount = float(_STEP_COUNT);\n\n    vec4 ray_origin = viewToScreen3(ray_origin_view);\n\n    vec3 ray_end_view = ray_origin_view + ray_dir_view;\n    vec4 ray_dir = viewToScreen3(ray_end_view); // ray_end\n\n    // clamp ray to screen edge.\n    vec2 clamp_end = clamp(ray_dir.xy, vec2(0.), vec2(1.));\n    vec2 correction = abs(ray_dir.xy - clamp_end);\n    correction = ( step(0.01, correction) * correction / (abs(clamp_end - ray_origin.xy) + 0.01) ) + 1.; // = ((b-c)/(c-a) + 1) see bottom\n    correction.x = 1./min(max(correction.y, correction.x), 10.);\n\n    ray_dir = ray_dir - ray_origin;\n\n    ray_dir.xyw *= correction.x;\n//    tolerance /= correction.x;\n\n//    if(len(ray_dir.xyw) < 0.1){\n//        ray_dir.xyw = normalize(ray_dir.xyw)*0.1;\n//    }\n\n// godot, has issues https://github.com/repalash/Open-Shaders/blob/aede763ff6fb68c348092574d060c56200a255f5/Engines/godot/screen_space_reflection.glsl#L116\n//        float scaleMaxX = min(1.0, 0.99 * (1.0 - ray_origin.x) / max(1e-5, ray_dir.x));\n//        float scaleMaxY = min(1.0, 0.99 * (1.0 - ray_origin.y) / max(1e-5, ray_dir.y));\n//        float scaleMinX = min(1.0, 0.99 * ray_origin.x / max(1e-5, -ray_dir.x));\n//        float scaleMinY = min(1.0, 0.99 * ray_origin.y / max(1e-5, -ray_dir.y));\n//        ray_dir = ray_dir * min(scaleMaxX, scaleMaxY) * min(scaleMinX, scaleMinY);\n//    return vec3(min(scaleMaxX, scaleMaxY) * min(scaleMinX, scaleMinY));\n\n    float iStepCount = 1./float(_STEP_COUNT);\n    tolerance *= 0.125;\n//    tolerance *= iStepCount;\n\n    _traceRay(ray_origin, ray_dir, tolerance, state, _STEP_COUNT, iStepCount);\n    if(_STEP_COUNT > 8 && state.z > 0.98) _traceRay(ray_origin, ray_dir, tolerance, state, _STEP_COUNT-8, iStepCount);\n    if(_STEP_COUNT > 15 && state.z > 0.98) _traceRay(ray_origin, ray_dir, tolerance, state, _STEP_COUNT-16, iStepCount);\n    if(_STEP_COUNT > 23 && state.z > 0.98) _traceRay(ray_origin, ray_dir, tolerance, state, _STEP_COUNT-16, iStepCount);\n\n\n    sample_uv = ray_origin + ray_dir * state.z;\n    sample_uv.z /= sample_uv.w;\n\n    state.z = state.z < 0.999 ? state.z : 9999999.;\n    return sample_uv.xyz;\n}\n\n\n\n/**\nfor ray clipping\n\na = ray_origin\nb = ray_end\nc = clamp(b)\nx = c.y - a.y\ny = b.y - c.y\n(c.y-a.y)/(b.y-c.y) = m/(l-m)\nm/(l-m) = k\nm = kl - km\nm = kl/(1+k)\n\n((c-a)/(b-c) ) / (1 + (c-a)/(b-c))\nx/(y*(1+x/y))\nx/(y+x)\n1/(y/x+1)\n\nx/(y + yx)\n1/(y/x + y)\n\nray scale =\n\nk/(1+k)\n1/(1/k+1)\n\n=\n1/((b-c)/(c-a) + 1)\n\n**/\n#endif\n","import {\n    AViewerPluginSync, BaseGroundPlugin,\n    GBufferPlugin,\n    glsl,\n    IShaderPropertiesUpdater,\n    IWebGLRenderer,\n    matDefine,\n    MaterialExtension,\n    Matrix4,\n    PhysicalMaterial,\n    ProgressivePlugin,\n    serialize,\n    shaderReplaceString,\n    ThreeViewer,\n    uiFolderContainer,\n    uiSlider,\n    uiToggle,\n    updateMaterialDefines,\n    Vector2, uniform,\n    Vector3, onChange, RenderManager,\n} from 'threepipe'\nimport ssrtShader from './shaders/ssrt.glsl'\n\nconst ShaderChunk = RenderManager.ShaderChunk\n\n/**\n * SS Contact Shadows Plugin\n * Adds a material extension to PhysicalMaterial screen space ray traced contact shadows.\n * It also adds a UI to the material to edit the settings.\n * todo - remove It uses WEBGI_materials_clearcoat_tint glTF extension to save the settings in glTF files.\n * @category Plugins\n */\n@uiFolderContainer('SS Contact Shadows')\nexport class SSContactShadowsPlugin extends AViewerPluginSync {\n    static readonly PluginType = 'SSContactShadows'\n    static readonly OldPluginType = 'SSContactShadowsPlugin' // todo swap\n\n    @uiToggle('Enabled')\n    @serialize()\n    @onChange(SSContactShadowsPlugin.prototype.setDirty)\n        enabled = true\n\n    private _uniforms: any = {\n        sscsRadius: {value: 0.03},\n        sscsIntensity: {value: 1},\n        sscsTolerance: {value: 1.5},\n\n        // tLastFrame: {value: null}, // not needed since we dont need color\n\n        frameCount: {value: 0},\n\n        projection: {value: new Matrix4()},\n        cameraPositionWorld: {value: new Vector3()},\n        cameraNearFar: {value: new Vector2(0.1, 1000)},\n\n        sceneBoundingRadius: {value: 0},\n    }\n\n    @uniform({propKey: 'sscsRadius', onChange: SSContactShadowsPlugin.prototype.setDirty})\n    @uiSlider('Radius', [0.0001, 0.1], 0.0001)\n    @serialize() radius = 0.015\n    @uniform({propKey: 'sscsIntensity', onChange: SSContactShadowsPlugin.prototype.setDirty})\n    @uiSlider('Intensity', [0.0001, 1], 0.0001)\n    @serialize() intensity = 1\n    @uniform({propKey: 'sscsTolerance', onChange: SSContactShadowsPlugin.prototype.setDirty})\n    @uiSlider('Tolerance', [0.1, 5])\n    @serialize() tolerance = 1.5\n\n    private _defines: any = {\n        ['PERSPECTIVE_CAMERA']: 1, // set in PerspectiveCamera2\n    }\n    @matDefine('SSCS_DEBUG', undefined, true, SSContactShadowsPlugin.prototype.setDirty)\n    @uiToggle('Debug only SSCS') @serialize() onlySSCSDebug = false\n\n    @matDefine('SSCS_STEP_COUNT', undefined, true, SSContactShadowsPlugin.prototype.setDirty)\n    @uiSlider('Step count', [1, 8], 1)\n    @serialize() stepCount = 2\n\n    dependencies = [GBufferPlugin]\n\n    // private _defines: any = {\n    //     // eslint-disable-next-line @typescript-eslint/naming-convention\n    //     CLEARCOAT_TINT_DEBUG: false,\n    // }\n\n    // static AddSSContactShadows(material: PhysicalMaterial, params?: IMaterialUserData['_clearcoatTint']): IMaterialUserData['_clearcoatTint']|null {\n    //     const ud = material?.userData\n    //     if (!ud) return null\n    //     if (!ud._clearcoatTint) ud._clearcoatTint = {}\n    //     const tf = ud._clearcoatTint!\n    //     tf.enableTint = true\n    //     if (tf.tintColor === undefined) tf.tintColor = '#ffffff'\n    //     if (tf.thickness === undefined) tf.thickness = 0.1\n    //     if (tf.ior === undefined) tf.ior = 1.5\n    //     params && Object.assign(tf, params)\n    //     if (material.setDirty) material.setDirty()\n    //     return tf\n    // }\n\n    // private _multiplyPass?: MultiplyPass\n    readonly materialExtension: MaterialExtension = {\n        uuid: SSContactShadowsPlugin.PluginType,\n        priority: 5,\n        shaderExtender: (shader, _material, _renderer) => {\n            if (!(shader as any).defines.SSCS_ENABLED) return\n            const rsS = 'float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {'\n            const lsS = glsl`\n                #ifndef D_sceneBoundingRadius\n                #define D_sceneBoundingRadius\n                uniform float sceneBoundingRadius;\n                #endif\n                #ifndef D_frameCount\n                #define D_frameCount\n                uniform float frameCount;\n                #endif\n                float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, vec3 lightDirection ) {\n                    vec3 ray_origin_view = -vViewPosition;\n                    float rnd = interleavedGradientNoise(gl_FragCoord.xy, frameCount+34.);\n                    float cameraDist = length(cameraPositionWorld);\n                    // float radius = mix((cameraNearFar.y) + ray_origin_view.z, -ray_origin_view.z - cameraNearFar.x, rnd * 0.5 + 0.5)*sscsRadius;\n                    float radius = mix((cameraDist + sceneBoundingRadius) + ray_origin_view.z, -ray_origin_view.z - max(0.0, cameraDist - sceneBoundingRadius), rnd * 0.5 + 0.5)*sscsRadius;\n                    vec3 state = vec3(1.,(rnd+0.5)/float(SSCS_STEP_COUNT),2.);\n                    traceRay(ray_origin_view, normalize(lightDirection) * radius, sscsTolerance * radius * 2., state, SSCS_STEP_COUNT);\n                    state.z = state.z > 0.99 ? 1. : max(0.,min(state.z * state.z * (1.-sscsIntensity), 1.));\n                    #if defined(SSCS_DEBUG) && SSCS_DEBUG > 0\n                    return state.z;\n                    #endif\n            `\n            const shadowChunk = `\n#if SSCS_ENABLED\n\n    uniform float sscsIntensity;\n    uniform float sscsRadius;\n    uniform float sscsTolerance;\n\n    #define THREE_PACKING_INCLUDED // by threejs\n    #include <cameraHelpers>\n    #include <randomHelpers>\n    ${ssrtShader}\n  \n#endif\n            ` + shaderReplaceString(ShaderChunk.shadowmap_pars_fragment, rsS, `${lsS}\\n`).replace('return mix( 1.0, shadow, shadowIntensity );', 'return mix( 1.0, min(shadow, state.z), shadowIntensity );')\n\n            // todo shaderReplaceString\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <shadowmap_pars_fragment>', shadowChunk)\n\n            // Because this frag is also patched in Anisotropy\n            // no need for warning here.\n            shader.fragmentShader = shader.fragmentShader.replace('#include <lights_fragment_begin>', ShaderChunk.lights_fragment_begin)\n\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader,\n                'directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;',\n                'directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ], directLight.direction ) : 1.0;'\n            )\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader,\n                'directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;',\n                'directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ], directLight.direction ) : 1.0;')\n\n            // todo: point light?\n            // const rsL = ''\n            // const lsL = 'directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ], directLight.direction ) : 1.0;'\n            // const lightsFragmentBegin = ShaderChunk.lights_fragment_begin.replace(rsL, lsL)\n\n            // shader.fragmentShader = shader.fragmentShader.replace('#include <lightmap_fragment>', '')\n            // ;(shader as any).defines.USE_UV = ''\n\n            this._gbufferUnpackExtension?.shaderExtender?.(shader, _material, _renderer)\n        },\n        onObjectRender: (_, material, renderer: IWebGLRenderer) => {\n            const enabled: any = this.enabled &&\n            renderer.userData.screenSpaceRendering !== false &&\n            !material.userData?.pluginsDisabled &&\n            !material.userData?.sscsDisabled ? 1 : 0\n\n            // const tfUd = material.userData._clearcoatTint\n            // if (!tfUd?.enableTint) return\n            //\n            // this._uniforms.ccTintColor.value.set(tfUd.tintColor) // could be number or string also, apart from Color\n            // this._uniforms.ccThickness.value = tfUd.thickness\n            // this._uniforms.ccIor.value = tfUd.ior\n            updateMaterialDefines({\n                ...this._defines,\n                ['SSCS_ENABLED']: enabled,\n            }, material)\n        },\n        extraUniforms: {\n            ...this._uniforms, // todo should not be static because of multiple viewers\n        },\n        extraDefines: {},\n        computeCacheKey: (_: PhysicalMaterial) => {\n            return this.isDisabled() ? '0' : '1'\n        },\n        isCompatible: (material1: PhysicalMaterial) => {\n            return material1.isPhysicalMaterial\n        },\n        // getUiConfig: (material: PhysicalMaterial) => {\n        //     const viewer = this._viewer!\n        //     if (material.userData._clearcoatTint === undefined) material.userData._clearcoatTint = {}\n        //     const state = material.userData._clearcoatTint\n        //     const config: UiObjectConfig = {\n        //         type: 'folder',\n        //         label: 'Clearcoat Tint',\n        //         onChange: (ev)=>{\n        //             if (!ev.config) return\n        //             this.setDirty()\n        //         },\n        //         children: [\n        //             {\n        //                 type: 'checkbox',\n        //                 label: 'Enabled',\n        //                 get value() {\n        //                     return state.enableTint || false\n        //                 },\n        //                 set value(v) {\n        //                     if (v === state.enableTint) return\n        //                     if (v) {\n        //                         if (!SSContactShadowsPlugin.AddSSContactShadows(material))\n        //                             viewer.dialog.alert('Cannot add clearcoat tint.')\n        //                     } else {\n        //                         state.enableTint = false\n        //                         if (material.setDirty) material.setDirty()\n        //                     }\n        //                     config.uiRefresh?.(true, 'postFrame')\n        //                 },\n        //             },\n        //             {\n        //                 type: 'color',\n        //                 label: 'Tint color',\n        //                 hidden: () => !state.enableTint,\n        //                 property: [state, 'tintColor'],\n        //             },\n        //             {\n        //                 type: 'input',\n        //                 label: 'Thickness',\n        //                 hidden: () => !state.enableTint,\n        //                 property: [state, 'thickness'],\n        //             },\n        //             {\n        //                 type: 'slider',\n        //                 bounds: [0.8, 2.5],\n        //                 label: 'IOR',\n        //                 hidden: () => !state.enableTint,\n        //                 property: [state, 'ior'],\n        //             },\n        //         ],\n        //     }\n        //     return config\n        // },\n        updaters: ()=>\n            [\n                // this._viewer?.getPlugin(GBufferPlugin),\n                this._viewer?.getPlugin(ProgressivePlugin),\n                this._viewer?.scene.renderCamera,\n                this._viewer?.renderManager,\n                this._viewer?.scene,\n            ] as IShaderPropertiesUpdater[],\n    }\n\n    setDirty() {\n        this.materialExtension?.setDirty?.()\n        this._viewer?.setDirty()\n    }\n\n    // private _loaderCreate({loader}: {loader: GLTFLoader2}) {\n    //     if (!loader.isGLTFLoader2) return\n    //     loader.register((p) => new GLTFMaterialsSSContactShadowsExtensionImport(p))\n    // }\n\n    constructor(enabled = true) {\n        super()\n        // this._loaderCreate = this._loaderCreate.bind(this)\n        this.enabled = enabled\n\n        // // for tweakpane UI. todo\n        // ;(this as any).userData = {setDirty: ()=>{\n        //         this._viewer?.setDirty()\n        // }}\n    }\n\n    onAdded(v: ThreeViewer) {\n        super.onAdded(v)\n        // v.addEventListener('preRender', this._preRender)\n        v.assetManager.materials.registerMaterialExtension(this.materialExtension)\n        if (v.getPlugin(BaseGroundPlugin)) v.getPlugin(BaseGroundPlugin)!.material!.userData.sscsDisabled = false // todo remove after threepipe update\n        this._gbufferUnpackExtensionChanged()\n        v.renderManager.addEventListener('gbufferUnpackExtensionChanged', this._gbufferUnpackExtensionChanged)\n        // v.assetManager.importer.addEventListener('loaderCreate', this._loaderCreate as any)\n        // v.assetManager.exporter.getExporter('gltf', 'glb')?.extensions?.push(glTFMaterialsSSContactShadowsExtensionExport)\n\n    }\n\n    onRemove(v: ThreeViewer) {\n        v.assetManager.materials?.unregisterMaterialExtension(this.materialExtension)\n        v.renderManager.removeEventListener('gbufferUnpackExtensionChanged', this._gbufferUnpackExtensionChanged)\n        // v.assetManager.importer?.removeEventListener('loaderCreate', this._loaderCreate as any)\n        // const exporter = v.assetManager.exporter.getExporter('gltf', 'glb')\n        // if (exporter) {\n        //     const index = exporter.extensions?.indexOf(glTFMaterialsSSContactShadowsExtensionExport)\n        //     if (index !== undefined && index >= 0) exporter.extensions?.splice(index, 1)\n        // }\n        return super.onRemove(v)\n    }\n\n    private _gbufferUnpackExtension = undefined as MaterialExtension|undefined\n\n    private _gbufferUnpackExtensionChanged = ()=>{\n        if (!this._viewer) throw new Error('SSContactShadowPlugin: pass/viewer not created yet')\n        const newExtension = this._viewer.renderManager.gbufferUnpackExtension\n        if (this._gbufferUnpackExtension === newExtension) return\n        if (this._gbufferUnpackExtension) this.setGBufferUnpackExtension(undefined)\n        this._gbufferUnpackExtension = newExtension\n        if (this._gbufferUnpackExtension) this.setGBufferUnpackExtension(this._gbufferUnpackExtension)\n        else this._viewer.console.warn('SSContactShadowPlugin: GBuffer unpack extension removed')\n    }\n\n    setGBufferUnpackExtension(extension: MaterialExtension|undefined) {\n        this._gbufferUnpackExtension = extension\n        if (!this._gbufferUnpackExtension) return\n\n        // todo not possible to remove it?\n        Object.assign(this.materialExtension.extraUniforms!, this._gbufferUnpackExtension.extraUniforms)\n        Object.assign(this.materialExtension.extraDefines!, this._gbufferUnpackExtension.extraDefines)\n    }\n    // public static readonly CLEARCOAT_TINT_GLTF_EXTENSION = 'WEBGI_materials_clearcoat_tint'\n\n}\n\n// declare module '../../core/IMaterial' {\n//     interface IMaterialUserData {\n//         _clearcoatTint?: {\n//             enableTint?: boolean\n//             tintColor?: Color|number|string\n//             thickness?: number\n//             ior?: number\n//         }\n//     }\n// }\n\n/**\n * SSContactShadows Materials Extension\n *\n * Specification: https://webgi.xyz/docs/gltf-extensions/WEBGI_materials_clearcoat_tint.html\n */\n// class GLTFMaterialsSSContactShadowsExtensionImport implements GLTFLoaderPlugin {\n//     public name: string\n//     public parser: GLTFParser\n//\n//     constructor(parser: GLTFParser) {\n//         this.parser = parser\n//         this.name = SSContactShadowsPlugin.CLEARCOAT_TINT_GLTF_EXTENSION\n//     }\n//\n//     async extendMaterialParams(materialIndex: number, materialParams: any) {\n//         const parser = this.parser\n//         const materialDef = parser.json.materials[materialIndex]\n//         if (!materialDef.extensions || !materialDef.extensions[this.name]) return\n//         const extension = materialDef.extensions[this.name]\n//         if (!materialParams.userData) materialParams.userData = {}\n//         SSContactShadowsPlugin.AddSSContactShadows(materialParams)\n//         ThreeSerialization.Deserialize(extension, materialParams.userData._clearcoatTint)\n//     }\n// }\n//\n// const glTFMaterialsSSContactShadowsExtensionExport = (w: GLTFWriter2)=> ({\n//     writeMaterial: (material: any, materialDef: any) => {\n//         if (!material.isMeshStandardMaterial || !material.userData._clearcoatTint?.enableTint) return\n//         materialDef.extensions = materialDef.extensions || {}\n//\n//         const extensionDef: any = ThreeSerialization.Serialize(material.userData._clearcoatTint)\n//\n//         materialDef.extensions[ SSContactShadowsPlugin.CLEARCOAT_TINT_GLTF_EXTENSION ] = extensionDef\n//         w.extensionsUsed[ SSContactShadowsPlugin.CLEARCOAT_TINT_GLTF_EXTENSION ] = true\n//     },\n// })\n","#define PI 3.141592653589793\n\n// invalid -  https://github.com/repalash/Open-Shaders/blob/f226a633874528ca1e7c3120512fc4a3bef3d1a6/Engines/Unreal/Private/MonteCarlo.ush#L12  //[ Duff et al. 2017, \"Building an Orthonormal Basis, Revisited\" ]\n\nmat3 GetTangentBasis( vec3 TangentZ )\n{\n    vec3 up = vec3(0.0, 0.0, 1.0);\n    vec3 TangentX = normalize(cross(dot(TangentZ, up) < 0.8 ? up : vec3(1.0, 0.0, 0.0), TangentZ));\n    vec3 TangentY = cross(TangentZ, TangentX);\n    return mat3( TangentX, TangentY, TangentZ );\n}\n\nvec4 CosineSampleHemisphere( vec2 E )\n{\n    float Phi = 2. * PI * E.x;\n    float CosTheta = sqrt( E.y );\n    float SinTheta = sqrt( 1. - CosTheta * CosTheta );\n\n    vec3 H;\n    H.x = SinTheta * cos( Phi );\n    H.y = SinTheta * sin( Phi );\n    H.z = CosTheta;\n\n    float PDF = CosTheta * (1.0 /  PI);\n\n    return vec4( H, PDF );\n}\n\n\nvec4 UniformSampleHemisphere( vec2 E )\n{\n    float Phi = 2. * PI * E.x;\n    float CosTheta = E.y;\n    float SinTheta = sqrt( 1. - CosTheta * CosTheta );\n\n    vec3 H;\n    H.x = SinTheta * cos( Phi );\n    H.y = SinTheta * sin( Phi );\n    H.z = CosTheta;\n\n    float PDF = 1.0 / (2. * PI);\n\n    return vec4( H, PDF );\n}\n\n\nvec2 UniformSampleDiskConcentric( vec2 E )\n{\n    vec2 p = 2. * E - 1.;\n    float Radius;\n    float Phi;\n    if( abs( p.x ) > abs( p.y ) )\n    {\n        Radius = p.x;\n        Phi = (PI/4.) * (p.y / p.x);\n    }\n    else\n    {\n        Radius = p.y;\n        Phi = (PI/2.) - (PI/4.) * (p.x / p.y);\n    }\n    return vec2( Radius * cos( Phi ), Radius * sin( Phi ) );\n}\n\n// based on the approximate equal area transform from\n// http://marc-b-reynolds.github.io/math/2017/01/08/SquareDisc.html\nvec2 UniformSampleDiskConcentricApprox( vec2 E )\n{\n    vec2 sf = E * sqrt(2.0) - sqrt(0.5);// map 0..1 to -sqrt(0.5)..sqrt(0.5)\n    vec2 sq = sf*sf;\n    float root = sqrt(2.0*max(sq.x, sq.y) - min(sq.x, sq.y));\n    if (sq.x > sq.y)\n    {\n        sf.x = sf.x > 0. ? root : -root;\n    }\n    else\n    {\n        sf.y = sf.y > 0. ? root : -root;\n    }\n    return sf;\n}\n","import {\n    ExtendedShaderPass,\n    GBufferPlugin,\n    getOrCall,\n    getTexelDecoding,\n    glsl,\n    ICamera,\n    IMaterial,\n    IPassID,\n    IPipelinePass,\n    IRenderManager,\n    IScene,\n    IWebGLRenderer,\n    matDefine,\n    matDefineBool,\n    MaterialExtension,\n    Matrix4,\n    PhysicalMaterial,\n    PipelinePassPlugin,\n    ProgressivePlugin,\n    serialize,\n    shaderReplaceString,\n    shaderUtils,\n    SSAAPlugin,\n    Texture,\n    TextureDataType,\n    ThreeViewer,\n    uiConfig,\n    uiConfigMaterialExtension,\n    uiFolderContainer,\n    uiImage,\n    uiSlider,\n    uiToggle,\n    uiVector,\n    uniform,\n    UnsignedByteType,\n    ValOrFunc,\n    Vector2,\n    Vector3,\n    WebGLRenderTarget,\n} from 'threepipe'\n// import ssreflPass from './shaders/SSReflectionPlugin.pass.glsl' // todo\n// import ssreflPatch from './shaders/SSReflectionPlugin.patch.glsl'\nimport samplePointHelpers from './shaders/samplePointHelpers.glsl'\nimport ssrtShader from './shaders/ssrt.glsl'\n// import ssrShader from './shaders/ssreflection.glsl'\nimport ssreflPatch from './shaders/ssrPatch.glsl'\nimport ssrShaderMain from './shaders/ssreflectionMain.glsl'\nimport {getShaders} from \"../../utils/shaders\";\nimport {VelocityBufferPlugin} from \"../buffer/VelocityBufferPlugin\";\n\nexport type SSReflectionPluginTarget = WebGLRenderTarget\n\nconst passId = 'ssrefl'\ntype SSReflectionPassId = typeof passId\n\n/**\n * SSReflection Plugin\n *\n * Adds screen space reflections to the scene.\n * @category Plugins\n */\n@uiFolderContainer('SSReflection Plugin')\nexport class SSReflectionPlugin\n    extends PipelinePassPlugin<SSReflectionPluginPass, SSReflectionPassId> {\n\n    readonly passId = passId\n    public static readonly PluginType = 'SSReflectionPlugin'\n    public static readonly OldPluginType = 'SSReflection'\n\n    dependencies = [GBufferPlugin, SSAAPlugin]\n\n    target?: SSReflectionPluginTarget\n    @uiImage('SSReflection Buffer', {readOnly: true, hideOnEmpty: true}) texture?: Texture\n\n    @uiConfig(undefined, {unwrapContents: true}) declare protected _pass?: SSReflectionPluginPass\n\n    // @onChange2(SSReflectionPlugin.prototype._createTarget)\n    // @uiDropdown('Buffer Type', threeConstMappings.TextureDataType.uiConfig)\n    readonly bufferType: TextureDataType // cannot be changed after creation (for now)\n\n    // @onChange2(SSReflectionPlugin.prototype._createTarget)\n    // @uiSlider('Buffer Size Multiplier', [0.25, 2.0], 0.25)\n    readonly sizeMultiplier: number // cannot be changed after creation (for now)\n\n\n    constructor(\n        // previously inlineSSR\n        public readonly inlineShaderRayTrace = true, // todo: we need roughness in gbuffer for proper inline. this has other advantages also like we can do blurring and denoising etc\n        bufferType: TextureDataType = UnsignedByteType, // only when inline is false\n        sizeMultiplier = 1, // only when inline is false\n        enabled = true,\n    ) {\n        super()\n        this.enabled = enabled\n        this.bufferType = bufferType\n        this.sizeMultiplier = sizeMultiplier\n    }\n\n    protected _createTarget(recreate = true) {\n        if (!this._viewer) return\n        if (recreate) this._disposeTarget()\n        if (this.inlineShaderRayTrace) return // no need to create.\n        if (!this.target)\n            this.target = this._viewer.renderManager.createTarget<SSReflectionPluginTarget>(\n                {\n                    depthBuffer: false,\n                    type: this.bufferType,\n                    sizeMultiplier: this.sizeMultiplier,\n                    // magFilter: NearestFilter,\n                    // minFilter: NearestFilter,\n                    // generateMipmaps: false,\n                    // encoding: LinearEncoding,\n                })\n        this.texture = this.target.texture\n        this.texture.name = 'ssreflBuffer'\n\n        // if (this._pass) this._pass.target = this.target\n    }\n\n    protected _disposeTarget() {\n        if (!this._viewer) return\n        if (this.target) {\n            this._viewer.renderManager.disposeTarget(this.target)\n            this.target = undefined\n        }\n        this.texture = undefined\n    }\n\n    private _gbufferUnpackExtension = undefined as MaterialExtension|undefined\n    private _gbufferUnpackExtensionChanged = ()=>{\n        if (!this._pass || !this._viewer) throw new Error('SSReflectionPlugin: pass/viewer not created yet')\n        const newExtension = this._viewer.renderManager.gbufferUnpackExtension\n        if (this._gbufferUnpackExtension === newExtension) return\n        if (this._gbufferUnpackExtension) this._pass.setGBufferUnpackExtension(undefined)\n        this._gbufferUnpackExtension = newExtension\n        if (this._gbufferUnpackExtension) this._pass.setGBufferUnpackExtension(this._gbufferUnpackExtension)\n        else this._viewer.console.warn('SSReflectionPlugin: GBuffer unpack extension removed')\n    }\n\n    protected _createPass() {\n        if (!this._viewer) throw new Error('SSReflectionPlugin: viewer not set')\n        if (!this._viewer.renderManager.gbufferTarget || !this._viewer.renderManager.gbufferUnpackExtension)\n            throw new Error('SSReflectionPlugin: GBuffer target not created. GBufferPlugin is required.')\n        this._createTarget(true)\n        return new SSReflectionPluginPass(this.passId, ()=>this.target, this.inlineShaderRayTrace)\n    }\n\n    onAdded(viewer: ThreeViewer) {\n        super.onAdded(viewer)\n        // todo why?\n        if (viewer.getPlugin('Ground') || viewer.getPlugin('BaseGroundPlugin')) console.warn('GroundPlugin must be added after SSReflectionPlugin')\n        this._gbufferUnpackExtensionChanged()\n        viewer.renderManager.addEventListener('gbufferUnpackExtensionChanged', this._gbufferUnpackExtensionChanged)\n        viewer.forPlugin(VelocityBufferPlugin, (vbp) => {\n            this._pass?.material.registerMaterialExtensions([vbp.unpackExtension])\n        }, (vbp)=>{\n            this._pass?.material?.unregisterMaterialExtensions([vbp.unpackExtension])\n        }, this)\n    }\n\n    onRemove(viewer: ThreeViewer): void {\n        this._disposeTarget()\n        viewer.renderManager.removeEventListener('gbufferUnpackExtensionChanged', this._gbufferUnpackExtensionChanged)\n        return super.onRemove(viewer)\n    }\n\n    protected _beforeRender(_?: IScene, _1?: ICamera, _2?: IRenderManager): boolean {\n        if (!this._viewer) return false\n        const e = super._beforeRender(_, _1, _2)\n        if(!e) return e\n        const progressive = this._viewer.getPlugin(ProgressivePlugin)\n        this._pass?.updateShaderProperties([progressive])\n        return e\n    }\n\n    /**\n     * @deprecated use {@link target} instead\n     */\n    get ssrTarget() {\n        console.warn('SSReflectionPlugin: ssrTarget is deprecated, use target instead')\n        return this.target\n    }\n\n    fromJSON(data: any, meta?: any): this|null|Promise<this|null> {\n        // legacy\n        if (data.passes?.ssr) {\n            data = {...data}\n            data.pass = data.passes.ssr\n            delete data.passes\n            if (data.pass.enabled !== undefined) data.enabled = data.pass.enabled\n        }\n        return super.fromJSON(data, meta)\n    }\n\n    _viewerListeners = {\n        preRender: ()=>{\n            if(!this._viewer || this.isDisabled()) return\n            if(!this._pass) return\n\n            const renderCamera = this._viewer.scene.renderCamera\n            this._pass.uniforms.currentProjectionViewMatrix.value.multiplyMatrices(renderCamera.projectionMatrix, renderCamera.matrixWorldInverse)\n            this._pass.uniforms.inverseViewMatrix.value.copy(renderCamera.matrixWorld)\n        },\n        postRender: ()=>{\n            if(!this._viewer || this.isDisabled()) return\n            if(!this._pass) return\n\n            this._pass.uniforms.lastProjectionViewMatrix.value.copy(this._pass.uniforms.currentProjectionViewMatrix.value)\n        }\n    }\n\n}\n\n@uiFolderContainer('SSReflection Pass')\nexport class SSReflectionPluginPass extends ExtendedShaderPass implements IPipelinePass {\n    before = ['render']\n    after = ['gbuffer', 'depth']\n    required = ['render', 'progressive'] // gbuffer required check done in plugin.\n\n    @uiSlider('Intensity', [0, 4])\n    @serialize() @uniform() intensity = 1\n\n    @uiVector('Boost')\n    @serialize() @uniform() boost = new Vector3(1, 1, 1)\n\n    @uiSlider('Object Radius', [0.01, 2.])\n    @serialize() @uniform() objectRadius = 1\n\n    @uiToggle('Auto radius') @serialize() @uniform() autoRadius = true\n\n    @uiSlider('Power', [0, 3])\n    @serialize() @uniform() power = 1.1\n\n    @uiSlider('Tolerance', [0.1, 5])\n    @serialize() @uniform() tolerance = 0.5\n\n    @uiSlider('Roughness Factor', [0.1, 1.25])\n    @serialize() @uniform({propKey: 'ssrRoughnessFactor'}) roughnessFactor = 1\n\n    @uiSlider('Step count', [1, 32], 1, {tags: ['performance']})\n    @serialize()\n    @matDefine('SSR_STEP_COUNT', undefined, undefined, SSReflectionPluginPass.prototype.setDirty)\n        stepCount = 16\n\n    @uiSlider('Ray count', [1, 8], 1, {tags: ['performance']})\n    @serialize()\n    @matDefine('SSR_RAY_COUNT', undefined, undefined, SSReflectionPluginPass.prototype.setDirty)\n        rayCount = 1\n\n    @uiToggle('Ray Blend MAX')\n    @serialize()\n    @matDefineBool('SSR_RAY_BLEND_MAX', undefined, undefined, SSReflectionPluginPass.prototype.setDirty, true)\n        rayBlendMax = false\n\n    setDirty() {\n        this.materialExtension?.setDirty?.()\n        super.setDirty();\n    }\n\n    @uiSlider('Low Quality Frames', [0, 4], 1)\n    @serialize()\n    @matDefine('SSR_LOW_QUALITY_FRAMES', undefined, undefined, SSReflectionPluginPass.prototype.setDirty)\n        lowQualityFrames = 0\n\n    @uiToggle('Ignore front rays')\n    @serialize()\n    @matDefineBool('SSR_MASK_FRONT_RAYS', undefined, undefined, SSReflectionPluginPass.prototype.setDirty)\n        maskFrontRays = true\n\n    @uiSlider('Mask front rays factor', [-1, 1], 0.01, (that: SSReflectionPluginPass)=>({hidden: () => !that.maskFrontRays}))\n    @serialize() @uniform() maskFrontFactor = -0.2\n    public readonly passId: IPassID\n\n    @uiSlider('Split', [0, 1], 0.01, {tags: ['debug']})\n    @serialize() @uniform({propKey: 'ssrSplitX', onChange: SSReflectionPluginPass.prototype.setDirty})\n    split = 0\n\n    constructor(pid: IPassID,\n                public target?: ValOrFunc<WebGLRenderTarget|undefined>,\n                public readonly inlineShaderRayTrace = true) {\n        super({\n            defines: {\n                ['SSR_STEP_COUNT']: 16,\n                ['SSR_RAY_COUNT']: 4,\n                ['SSR_RAY_BLEND_MAX']: 0,\n                ['SSR_LOW_QUALITY_FRAMES']: 0, // todo: only on mobile\n                ['SSR_INLINE']: inlineShaderRayTrace ? '1' : '0',\n                // ['SSR_NON_PHYSICAL']: '0', only in inline, so it should not be here\n                ['SSR_MASK_FRONT_RAYS']: true,\n                ['PERSPECTIVE_CAMERA']: 1, // set in PerspectiveCamera2\n                // ['SSREFL_PACKING']: 1, // 1 is (r: ssrefl, gba: depth), 2 is (rgb: ssrefl, a: 1), 3 is (rgba: packed_ssrefl), 4 is (rgb: packed_ssrefl, a: 1)\n            },\n            uniforms: {\n                tLastThis: {value: null},\n                tLastFrame: {value: null}, // set in progressive plugin\n                // TODO required?\n                screenSize: {value: new Vector2(0, 0)}, // set in ExtendedRenderMaterial\n                currentFrameCount: {value: 0}, // set in RenderManager\n                frameCount: {value: 0}, // set in RenderManager\n                cameraNearFar: {value: new Vector2(0.1, 1000)}, // set in PerspectiveCamera2\n                cameraPositionWorld: {value: new Vector3()}, // set in PerspectiveCamera2\n                projection: {value: new Matrix4()}, // set in PerspectiveCamera2\n                // saoBiasEpsilon: {value: new Vector3(1, 1, 1)},\n\n                opacity: {value: 1}, // todo?\n                intensity: {value: 0.},\n                boost: {value: new Vector3(0, 0, 0)},\n                objectRadius: {value: 0},\n                autoRadius: {value: false},\n                power: {value: 0},\n                maskFrontFactor: {value: -0.1},\n                tolerance: {value: 0},\n                ssrRoughnessFactor: {value: 1},\n                sceneBoundingRadius: {value: 0}, // todo do same in SSAO\n\n                // reprojection/velocity\n                currentProjectionViewMatrix: {value: new Matrix4()},\n                lastProjectionViewMatrix: {value: new Matrix4()},\n                inverseViewMatrix: {value: new Matrix4()},\n\n                // split mode\n                ssrSplitX: {value: 0.5},\n            },\n\n            vertexShader: shaderUtils.defaultVertex,\n\n            fragmentShader: `\nvarying vec2 vUv;\n\n// for gbuffer\n#include <packing>\n#define THREE_PACKING_INCLUDED\n#include <cameraHelpers>\n#include <randomHelpers>\n${samplePointHelpers}\n\n${ssrtShader}\n\n${getShaders().ssReflection}\n\n${ssrShaderMain}\n            `,\n\n        }, 'tDiffuse', 'tLastThis', 'tLastFrame')\n        this.passId = pid\n\n        this.needsSwap = false\n        this.clear = true // todo\n\n        if (inlineShaderRayTrace) {\n            // inline... todo test non inline\n            Object.assign(this.materialExtension.extraUniforms!, {\n                tNormalDepth: this.material.uniforms.tNormalDepth,\n                tLastFrame: this.material.uniforms.tLastFrame,\n                objectRadius: this.material.uniforms.objectRadius,\n                autoRadius: this.material.uniforms.autoRadius,\n                tolerance: this.material.uniforms.tolerance,\n                ssrRoughnessFactor: this.material.uniforms.ssrRoughnessFactor,\n                frameCount: this.material.uniforms.frameCount,\n                currentFrameCount: this.material.uniforms.currentFrameCount,\n                projection: this.material.uniforms.projection,\n                cameraPositionWorld: this.material.uniforms.cameraPositionWorld,\n                cameraNearFar: this.material.uniforms.cameraNearFar,\n\n                sceneBoundingRadius: this.material.uniforms.sceneBoundingRadius,\n\n                // reprojection\n                currentProjectionViewMatrix: this.material.uniforms.currentProjectionViewMatrix,\n                lastProjectionViewMatrix: this.material.uniforms.lastProjectionViewMatrix,\n                inverseViewMatrix: this.material.uniforms.inverseViewMatrix,\n\n                ssrSplitX: this.material.uniforms.ssrSplitX,\n            })\n        }\n        // this._getUiConfig = this._getUiConfig.bind(this)\n    }\n\n    render(renderer: IWebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean) {\n        if (!this.enabled) return\n        if (this.inlineShaderRayTrace) {\n            this.needsSwap = false\n            return\n        }\n        const target = getOrCall(this.target)\n        if (!target) {\n            console.warn('SSReflectionPluginPass: target not defined. It must be set when inlineShaderRayTrace is false')\n            return\n        }\n        // this._updateParameters()\n        if (!this.material.defines.HAS_GBUFFER) {\n            console.warn('SSReflectionPluginPass: DepthNormalBuffer required for ssrefl')\n        }\n        renderer.renderManager.blit(writeBuffer, {\n            source: target.texture,\n        })\n        this.uniforms.tLastThis.value = writeBuffer.texture\n        super.render(renderer, target, readBuffer, deltaTime, maskActive)\n\n        this.needsSwap = false\n    }\n\n    beforeRender(scene: IScene, camera: ICamera, renderManager: IRenderManager) {\n        if (!this.enabled) return\n        this.updateShaderProperties([scene, camera, renderManager])\n    }\n\n    readonly materialExtension: MaterialExtension = {\n        extraUniforms: {\n            tSSReflMap: ()=>({value: getOrCall(this.target)?.texture ?? null}),\n            ssrPower: this.material.uniforms.power,\n            ssrIntensity: this.material.uniforms.intensity,\n            ssrMaskFrontFactor: this.material.uniforms.maskFrontFactor,\n            ssrBoost: this.material.uniforms.boost,\n        },\n        extraDefines: {\n            ['SSR_STEP_COUNT']: ()=>this.material.defines.SSR_STEP_COUNT,\n            ['SSR_RAY_COUNT']: ()=>this.material.defines.SSR_RAY_COUNT,\n            ['SSR_RAY_BLEND_MAX']: ()=>this.material.defines.SSR_RAY_BLEND_MAX,\n            ['SSR_LOW_QUALITY_FRAMES']: ()=>this.material.defines.SSR_LOW_QUALITY_FRAMES,\n            ['SSR_INLINE']: ()=>this.material.defines.SSR_INLINE,\n            ['SSR_MASK_FRONT_RAYS']: ()=>this.material.defines.SSR_MASK_FRONT_RAYS,\n            ['PERSPECTIVE_CAMERA']: ()=>this.material.defines.PERSPECTIVE_CAMERA,\n            // todo gbuffer stuff\n        },\n        shaderExtender: (shader, _material, _renderer) => {\n            if (!shader.defines?.SSREFL_ENABLED) return\n            const ls = `\n            \n            ${ssreflPatch}\n            \n            // reflectedLight.directDiffuse = vec3(0.);\n            // reflectedLight.indirectDiffuse = vec3(0.);\n            // reflectedLight.directSpecular = vec3(0.);\n            // reflectedLight.indirectSpecular = vec3(0.);\n            \n            `\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader,\n                '#glMarker beforeModulation', ls, {prepend: true})\n\n            this._gbufferUnpackExtension?.shaderExtender?.(shader, _material, _renderer)\n        },\n        onObjectRender: (_object, material, renderer: IWebGLRenderer) => {\n            let x: any = this.enabled &&\n            renderer.userData.screenSpaceRendering !== false &&\n            !material.userData?.pluginsDisabled &&\n            !material.userData?.ssreflDisabled ? this.split > 0 ? 2 : 1 : 0\n\n            if (material.defines!.SSREFL_ENABLED !== x) {\n                material.defines!.SSREFL_ENABLED = x\n                material.needsUpdate = true\n            }\n            x = material.userData?.ssreflNonPhysical ? 1 : 0\n            if (material.defines!.SSR_NON_PHYSICAL !== x) {\n                material.defines!.SSR_NON_PHYSICAL = x\n                material.needsUpdate = true\n            }\n        },\n        parsFragmentSnippet: ()=>glsl`\n            #if defined(SSREFL_ENABLED) && SSREFL_ENABLED > 0\n            uniform float ssrPower;\n            uniform float ssrIntensity;\n            uniform float ssrMaskFrontFactor;\n            uniform vec3 ssrBoost;\n            uniform sampler2D tSSReflMap;\n            uniform sampler2D tLastFrame;\n            ${getTexelDecoding('tSSReflMap', getOrCall(this.target)?.texture.colorSpace)}\n            ${getTexelDecoding('tLastFrame', this.material.uniforms!.tLastFrame.value?.colorSpace)}\n            ${!this.inlineShaderRayTrace ? '' : `\n#define THREE_PACKING_INCLUDED // by threejs\n#include <cameraHelpers>\n#include <randomHelpers>\n${samplePointHelpers}\n${ssrtShader}\n${getShaders().ssReflection}\n            `}\n            #include <simpleCameraHelpers>\n            #endif\n        `,\n        computeCacheKey: () => {\n            return (this.enabled ? '1' : '0') + getOrCall(this.target)?.texture?.colorSpace + Object.values(this.material.defines).map(v=>v + '').join(',')\n        },\n        uuid: SSReflectionPlugin.PluginType,\n        ...uiConfigMaterialExtension(this._getUiConfig.bind(this), SSReflectionPlugin.PluginType),\n        isCompatible: material => {\n            return (material as PhysicalMaterial).isPhysicalMaterial\n        },\n    }\n\n    /**\n     * Returns a uiConfig to toggle SSReflection on a material.\n     * This uiConfig is added to each material by extension\n     * @param material\n     * @private\n     */\n    protected _getUiConfig(material: IMaterial) {\n        return {\n            type: 'folder',\n            label: 'SSReflection',\n            children: [\n                {\n                    type: 'checkbox',\n                    label: 'Enabled',\n                    get value() {\n                        return !(material.userData.ssreflDisabled ?? false)\n                    },\n                    set value(v) {\n                        if (v === !(material.userData.ssreflDisabled ?? false)) return\n                        material.userData.ssreflDisabled = !v\n                        material.setDirty()\n                    },\n                    onChange: this.setDirty,\n                },\n                {\n                    type: 'checkbox',\n                    label: 'Non Physical',\n                    get value() {\n                        return material.userData.ssreflNonPhysical ?? false\n                    },\n                    set value(v) {\n                        if (v === (material.userData.ssreflNonPhysical ?? false)) return\n                        material.userData.ssreflNonPhysical = v\n                        material.setDirty()\n                    },\n                    onChange: this.setDirty,\n                },\n            ],\n        }\n    }\n\n    set uniformsNeedUpdate(value: true) {\n        this.material.uniformsNeedUpdate = value\n        this.setDirty()\n    }\n\n    protected _gbufferUnpackExtension: MaterialExtension|undefined\n    setGBufferUnpackExtension(extension: MaterialExtension|undefined) {\n        if (this._gbufferUnpackExtension === extension) return\n        if (this._gbufferUnpackExtension) this.material.unregisterMaterialExtensions([this._gbufferUnpackExtension])\n        this._gbufferUnpackExtension = extension\n        if (this._gbufferUnpackExtension) this.material.registerMaterialExtensions([this._gbufferUnpackExtension])\n\n        if (!this._gbufferUnpackExtension) return\n\n        // todo not possible to remove it?\n        Object.assign(this.materialExtension.extraUniforms!, this._gbufferUnpackExtension.extraUniforms)\n        Object.assign(this.materialExtension.extraDefines!, this._gbufferUnpackExtension.extraDefines)\n    }\n}\n\ndeclare module 'threepipe' {\n    interface IMaterialUserData {\n        /**\n         * Disable SSReflectionPlugin for this material.\n         */\n        ssreflDisabled?: boolean // default false\n        ssreflNonPhysical?: boolean // default false\n        // [SSReflectionPlugin.PluginType]?: {\n        //     enable?: boolean\n        //     nonPhysical?: boolean\n        // }\n    }\n}\n","import {\n    animateTarget,\n    AScreenPassExtensionPlugin,\n    Color,\n    DoubleSide,\n    GBufferPlugin,\n    getOrCall,\n    glsl,\n    ICamera, IGeometry,\n    IMaterial,\n    IObject3D,\n    IPassID,\n    IPipelinePass,\n    IRenderManager,\n    IScene, ITexture,\n    IUniform,\n    IWebGLRenderer,\n    matDefineBool,\n    onChange,\n    PickingPlugin,\n    RenderPass, SelectionObject, SelectionObjectArr,\n    serialize,\n    ShaderMaterial,\n    Texture,\n    TextureDataType,\n    ThreeViewer,\n    uiColor,\n    uiFolderContainer,\n    uiImage,\n    UiObjectConfig,\n    uiSlider,\n    uiToggle,\n    uniform,\n    UnsignedByteType,\n    ValOrFunc,\n    Vector2,\n    WebGLRenderTarget,\n} from 'threepipe'\nimport outlineShader from './shaders/outline.glsl'\nimport outlineDepthVertex from './shaders/outlineDepthVert.glsl'\nimport outlineDepthFrag from './shaders/outlineDepthFrag.glsl'\n\nexport type OutlinePluginTarget = WebGLRenderTarget\nexport type OutlinePluginPass = OutlineRenderPass<'outline', OutlinePluginTarget | undefined >\n\n/**\n * Outline Plugin\n * Adds an extension to {@link ScreenPass} material and a RenderPass to render the outlines and highlights of the selected objects.\n * It interfaces with the {@link PickingPlugin} to render the outlines of the selected objects.\n * The intensity, thickness, etc of the effect can be controlled with the `intensity`(previously outlineIntensity), `thickness` etc properties.\n *\n * @category Plugins\n */\n@uiFolderContainer('Selection Outline')\nexport class OutlinePlugin extends AScreenPassExtensionPlugin {\n    readonly passId = 'outline'\n    static readonly PluginType = 'OutlinePlugin'\n    static readonly OldPluginType = 'Outline'\n\n    readonly extraUniforms = {\n        outlineIntensity: {value: 1},\n        outlineThickness: {value: 2},\n        highlightTransparency: {value: 1},\n        outlineColor: {value: new Color(0xe98a65)},\n        enableHighlight: {value: true},\n        dpr: {value: 1} as IUniform<number>,\n\n        outlineBuffer: {value: null},\n        tDiffuseSize: {value: new Vector2(1024, 1024)},\n    } as const\n    extraDefines = {\n        ['DEBUG_OUTLINE']: '0',\n    } as const\n\n    /**\n     * The priority of the material extension when applied to the material in ScreenPass\n     * set to very low priority, so applied at the end.\n     */\n    priority = -101\n\n    @onChange(OutlinePlugin.prototype.setDirty)\n    @uiToggle('Enable')\n    @serialize() enabled: boolean\n\n    @uiToggle('Highlight')\n    @uniform({propKey: 'enableHighlight'})\n    @serialize() enableHighlight = false\n\n    @onChange(OutlinePlugin.prototype.setDirty)\n    @uiToggle('DynamicSelection')\n    @serialize() enableDynamicSelection = true\n\n    @uiSlider('Intensity', [0., 4], 0.001)\n    @uniform({propKey: 'outlineIntensity'})\n    @serialize('outlineIntensity') intensity = 2\n\n    @onChange(OutlinePlugin.prototype.setDirty)\n    @uiSlider('Transparency', [0., 1], 0.01)\n    @serialize() highlightTransparency = 0.84\n\n    @uiColor('Color')\n    @uniform({propKey: 'outlineColor'})\n    @serialize('outlineColor') color = new Color(0xe98a65)\n\n    @uiSlider('Thickness', [0, 10], 0.01)\n    @uniform({propKey: 'outlineThickness'})\n    @serialize('outlineThickness') thickness = 2\n\n    @uiToggle('Debug')\n    // todo onchange\n    @matDefineBool('DEBUG_OUTLINE', undefined, true)\n        debugOutline = false\n\n    @onChange(OutlinePlugin.prototype.setDirty)\n    @uiToggle('Highlight Selected Materials')\n        highlightSelectedMaterials = false\n\n    @onChange(OutlinePlugin.prototype.setDirty)\n    @uiToggle('Highlight Materials (same name)')\n        highlightMaterialSameNames = false\n\n    /**\n     * Highlight Transparency.\n     *\n     * For internal use, don't change. use {@link highlightTransparency} instead.\n     */\n    @uniform({propKey: 'highlightTransparency'})\n        transparency = 0\n\n    parsFragmentSnippet = () => {\n        if (this.isDisabled()) return ''\n\n        return glsl`\n            ${outlineShader}\n        `\n    }\n\n    protected _shaderPatch = 'diffuseColor = outline(diffuseColor);'\n\n    constructor(enabled = true, bufferType: TextureDataType = UnsignedByteType) {\n        super()\n        this.enabled = enabled\n        this.bufferType = bufferType\n    }\n    dependencies = [PickingPlugin, GBufferPlugin]\n\n    private _pickingWidgetDisabled = false\n    setDirty() {\n        super.setDirty()\n        if (!this._viewer) return\n        const picking = this._viewer.getPlugin(PickingPlugin)\n        let enabled = !this.isDisabled()\n        if (enabled) {\n            // special check for lines, as they look bad with the outline\n            const selected = picking?.getSelectedObject<IObject3D>() // primary object for line check\n            if (typeof selected?.type === 'string' && selected?.type?.includes('Line')) {\n                enabled = false\n            }\n        }\n        if (picking) {\n            if (enabled && picking.widgetEnabled) {\n                picking.widgetEnabled = false\n                this._pickingWidgetDisabled = true\n            } else if (!enabled && this._pickingWidgetDisabled) {\n                picking.widgetEnabled = true\n                this._pickingWidgetDisabled = false\n            }\n        }\n        this._viewer.setDirty()\n    }\n\n    // @serialize('pass')\n    protected _pass?: OutlinePluginPass\n\n    onAdded(viewer: ThreeViewer) {\n        super.onAdded(viewer)\n        this.setDirty() // for picking widget\n\n        this._pass = this._createPass()\n        this._pass.onDirty?.push(viewer.setDirty)\n        // this._pass.beforeRender = wrapThisFunction2(this._beforeRender, this._pass.beforeRender) // not needed at the moment\n        viewer.renderManager.registerPass(this._pass)\n\n        // todo use forPlugin and remove listener\n        const pickingPlugin = viewer.getPlugin(PickingPlugin)\n        pickingPlugin?.addEventListener('selectedObjectChanged', ()=> {\n            if (!this._animationCallBack && this) {\n                if (pickingPlugin?.getSelectedObject()) {\n                    if (this.enableDynamicSelection) {\n                        this.transparency = 1\n                        this._animationCallBack = this._startTransparencyAnimation(1, this.highlightTransparency, 400)\n                    } else {\n                        this.transparency = this.highlightTransparency\n                    }\n                } else {\n                    this.transparency = 1\n                }\n            }\n        })\n\n        // todo remove listener\n        document.addEventListener('mousemove', (e: MouseEvent)=> {\n            if (!this) return\n            if (!this.mouseInOutAnimationEnabled) return\n            if (!this.enableHighlight) return\n            const selectedObject = pickingPlugin?.getSelectedObject()\n            if (selectedObject && this.enableDynamicSelection) {\n                if (e.target !== viewer.canvas) {\n                    if (!this._animationCallBack && this._state === 'in') {\n                        this._animationCallBack = this._startTransparencyAnimation(this.highlightTransparency, 1, 600)\n                        this._state = 'out'\n                    }\n                } else {\n                    if (!this._animationCallBack && this._state === 'out') {\n                        this._animationCallBack = this._startTransparencyAnimation(1, this.highlightTransparency, 600)\n                        this._state = 'in'\n                    }\n                }\n            } else {\n                this.transparency = selectedObject ? this.highlightTransparency : 1\n            }\n        })\n    }\n    onRemove(viewer: ThreeViewer): void {\n        this._disposeTarget()\n        if (this._pass) {\n            viewer.renderManager.unregisterPass(this._pass)\n            if (this._pass.dispose) this._pass.dispose()\n        }\n        this._pass = undefined\n        return super.onRemove(viewer)\n    }\n\n    target?: OutlinePluginTarget\n\n    @uniform({propKey: 'outlineBuffer'})\n    @uiImage('Outline Buffer', {readOnly: true}) texture?: Texture\n\n    readonly material: ShaderMaterial = new ShaderMaterial({\n        uniforms: {\n            'cameraNearFar': {value: new Vector2(0.1, 100)},\n        },\n        vertexShader: outlineDepthVertex,\n        fragmentShader: outlineDepthFrag,\n        side: DoubleSide,\n    })\n\n    // @onChange2(OutlinePlugin.prototype._createTarget)\n    // @uiDropdown('Buffer Type', threeConstMappings.TextureDataType.uiConfig)\n    readonly bufferType: TextureDataType // cannot be changed after creation (for now)\n\n    protected _createTarget(recreate = true) {\n        if (!this._viewer) return\n        if (recreate) this._disposeTarget()\n\n        if (!this.target) this.target = this._viewer.renderManager.createTarget<OutlinePluginTarget>(\n            {\n                // depthBuffer: true,\n                sizeMultiplier: 1,\n                type: this.bufferType,\n                // magFilter: NearestFilter,\n                // minFilter: NearestFilter,\n                // generateMipmaps: false,\n                // colorSpace: LinearSRGBColorSpace,\n            })\n        this.texture = this.target.texture\n        this.texture.name = 'normalBuffer'\n    }\n    protected _disposeTarget() {\n        if (!this._viewer) return\n        if (this.target) {\n            this._viewer.renderManager.disposeTarget(this.target)\n            this.target = undefined\n        }\n        this.texture = undefined\n    }\n\n    private _getSelectedObject = () => {\n        if (!this._viewer) return null\n        const picking = this._viewer.getPlugin(PickingPlugin)\n        if (this.highlightSelectedMaterials) {\n            const mat = picking?.getSelectedObject<IObject3D>()?.material || null\n            if (this.highlightMaterialSameNames && mat) {\n                const names = Array.isArray(mat) ? mat.map(m => m.name) : [mat.name]\n                const mats = new Set<IMaterial>()\n                for (const name of names) {\n                    const mats1 = this._viewer?.assetManager?.materials?.findMaterialsByName(name)\n                    mats1?.forEach(m => mats.add(m))\n                }\n                return [...mats]\n            }\n            return mat\n        }\n        // @ts-expect-error fixed on update\n        const objects = picking ? picking.getSelectedObjects ? picking.getSelectedObjects() : [picking.getSelectedObject() || null] : null\n        return objects && objects.length > 0 ? objects.length === 1 ? objects[0] : objects : null\n    }\n\n    protected _createPass() {\n        this._createTarget(true)\n        if (!this.target) throw new Error('OutlinePlugin: target not created')\n\n        this.material.userData.isOutlinePluginMaterial = true\n        const pass = new OutlineRenderPass<'outline', OutlinePluginTarget|undefined>(this.passId, this._getSelectedObject, ()=>this.target, this.material)\n        return pass\n    }\n\n    protected _viewerListeners = {\n        preRender: ()=>{\n            if (this.isDisabled() || !this._viewer) return\n            // todo directly bind to value\n            this.extraUniforms.dpr.value = this._viewer.renderManager.renderScale * 2\n        },\n    }\n\n    // region animation\n\n    mouseInOutAnimationEnabled = true\n\n    private _state = 'in'\n\n    private _animationCallBack?: Promise<void>\n\n    private async _startTransparencyAnimation(from: number, to: number, duration: number) {\n        return animateTarget(this, 'transparency', {\n            from: from,\n            to: to,\n            duration: duration,\n            onComplete: () => {\n                this._animationCallBack = undefined\n            },\n        })\n    }\n\n    // endregion animation\n\n    // region deprecated\n\n    get outlineIntensity() {\n        console.warn('OutlinePlugin.outlineIntensity is deprecated, use OutlinePlugin.intensity instead')\n        return this.intensity\n    }\n    set outlineIntensity(v) {\n        console.warn('OutlinePlugin.outlineIntensity is deprecated, use OutlinePlugin.intensity instead')\n        this.intensity = v\n    }\n\n    get outlineColor() {\n        console.warn('OutlinePlugin.outlineColor is deprecated, use OutlinePlugin.intensity instead')\n        return this.intensity\n    }\n    set outlineColor(v) {\n        console.warn('OutlinePlugin.outlineColor is deprecated, use OutlinePlugin.intensity instead')\n        this.intensity = v\n    }\n\n    // endregion deprecated\n}\n\n@uiFolderContainer<OutlineRenderPass>((c: OutlineRenderPass)=>c.passId + ' Render Pass')\nexport class OutlineRenderPass<TP extends IPassID=IPassID, T extends WebGLRenderTarget | undefined = WebGLRenderTarget | undefined > extends RenderPass implements IPipelinePass<TP> { // todo: extend from jittered?\n    readonly isOutlineRenderPass = true\n    declare uiConfig: UiObjectConfig\n\n    @uiToggle('Enabled') enabled = true\n\n    declare scene?: IScene\n    before = ['render']\n    after = ['gbuffer']\n    required = ['render', 'gbuffer']\n\n    declare overrideMaterial: ShaderMaterial\n\n    constructor(public readonly passId: TP, private _getSelectedObjectOrMaterial: ()=>SelectionObject|SelectionObjectArr, public target: ValOrFunc<T>, overrideMaterial: ShaderMaterial) {\n        super(undefined, undefined, overrideMaterial, new Color(1, 1, 1), 1)\n    }\n\n    // constructor(private _getSelectedObjectOrMaterial: ()=>SelType, public target: WebGLRenderTarget, material: Material, clearColor: Color = new Color(1, 1, 1), clearAlpha = 1) {\n    //     super(undefined as any, undefined as any, material, clearColor, clearAlpha)\n    // }\n\n    /**\n     * Renders to {@link target}\n     * @param renderer\n     * @param writeBuffer - this is ignored? or used as transmissionRenderTarget?\n     * @param _1 - this is ignored\n     * @param deltaTime\n     * @param maskActive\n     */\n    render(renderer: IWebGLRenderer, writeBuffer?: WebGLRenderTarget|null, _1?: WebGLRenderTarget, deltaTime?: number, maskActive?: boolean) {\n        if (!this.scene || !this.camera || !this.enabled) return\n\n        const t = renderer.getRenderTarget()\n        const activeCubeFace = renderer.getActiveCubeFace()\n        const activeMipLevel = renderer.getActiveMipmapLevel()\n\n        const selectedObject = this._getSelectedObjectOrMaterial()\n        if (selectedObject) {\n            this._renderSelectedObject(renderer, selectedObject, writeBuffer || null, deltaTime, maskActive)\n        } else {\n            renderer.setRenderTarget(getOrCall(this.target) || null)\n            const color = new Color()\n            renderer.getClearColor(color)\n            renderer.setClearColor(new Color(0xffffff))\n            renderer.clear(true, true)\n            renderer.setClearColor(color)\n        }\n\n        renderer.setRenderTarget(t, activeCubeFace, activeMipLevel)\n    }\n\n    private _renderSelectedObject(renderer: IWebGLRenderer, selectedObject: SelectionObject|SelectionObjectArr, writeBuffer: WebGLRenderTarget | null, deltaTime: any, maskActive: any) {\n        if (!this.camera || !selectedObject) return\n        const selectionLayer = 6\n\n        // flatten array and get applied meshes from materials\n        const objs = (Array.isArray(selectedObject) ? selectedObject : [selectedObject])\n            .flatMap(o =>\n                (o as ITexture)?.isTexture ? [...(o as ITexture).appliedObjects?.values() || []] : o)\n            .flatMap(o =>\n                (o as IMaterial)?.isMaterial ? [...(o as IMaterial).appliedMeshes?.values() || []] :\n                    (o as IGeometry)?.isBufferGeometry ? [...(o as IGeometry).appliedMeshes?.values() || []] :\n                    o as IObject3D)\n\n        for (const o1 of objs) {\n            o1 && o1.traverse((o) => {\n                o.layers.enable(selectionLayer)\n            })\n        }\n\n        const mask = this.camera.layers.mask\n        this.camera.layers.set(selectionLayer)\n\n        const ud = (renderer as any).userData\n        if (!ud) console.error('threejs is not patched?')\n\n        ud.transmissionRenderTarget = writeBuffer\n\n        renderer.renderWithModes({\n            shadowMapRender: false,\n            backgroundRender: false,\n            opaqueRender: true,\n            transparentRender: true,\n            transmissionRender: true,\n            mainRenderPass: false,\n        }, ()=> super.render(renderer, writeBuffer as any, getOrCall(this.target), deltaTime as any, maskActive as any)) // here this.target is the write-buffer, variable writeBuffer is ignored\n\n        ud.transmissionRenderTarget = undefined\n\n        objs.forEach(o1=>o1.traverse(o => {\n            o.layers.disable(selectionLayer)\n        }))\n\n        this.camera.layers.mask = mask\n    }\n\n    public onDirty: (()=>void)[] = []\n\n    dispose() {\n        this.onDirty = []\n        this.scene = undefined\n        this.camera = undefined\n        super.dispose?.()\n    }\n\n    setDirty() {\n        this.onDirty.forEach(v=>v())\n    }\n\n    beforeRender(scene: IScene, camera: ICamera, _: IRenderManager): void {\n        this.scene = scene\n        this.camera = camera\n        camera.updateShaderProperties(this.overrideMaterial)\n    }\n\n}\n","uniform sampler2D outlineBuffer;\nuniform vec2 tDiffuseSize;\nuniform vec3 outlineColor;\nuniform float outlineThickness;\nuniform float outlineIntensity;\nuniform float highlightTransparency;\nuniform bool enableHighlight;\nuniform float dpr;\n\nfloat isSelected(vec2 uv) {\n    return 1. - texture2D(outlineBuffer, uv).b;\n}\n\nvec4 outline(in vec4 color) {\n    vec2 invSize = 1.0 / tDiffuseSize;\n\n    #if DEBUG_OUTLINE > 0\n    color = vec4(0., 0., 0., 1.);\n    //    return texture2D(outlineBuffer, vUv);\n    #endif\n\n    vec3 finalColor = color.rgb;\n\n    float c = isSelected(vUv);\n\n//    return vec4(c,c,c,1.);\n\n    if(c > 0.) {\n        vec4 uvOffset = 1.5 * dpr * outlineThickness * vec4(1.0, 0.0, -1.0, 1.0) * vec4(invSize, invSize);\n\n        float c1 = isSelected(vUv + uvOffset.xy);\n        float c2 = isSelected(vUv - uvOffset.xy);\n        float c3 = isSelected(vUv + uvOffset.yw);\n        float c4 = isSelected(vUv - uvOffset.yw);\n        float diff1 = (c1 - c2) * 0.5;\n        float diff2 = (c3 - c4) * 0.5;\n\n        float d = length(vec2(diff1, diff2));\n        // float trans = min(1., 10. * (1. - highlightTransparency));\n\n        vec4 highlightColor = enableHighlight ? vec4(c * outlineColor, (1. - highlightTransparency) * c) : vec4(0.);\n        vec4 edgeColor = vec4(outlineColor, 1.) * vec4(d);\n\n        float gbufferDepth = getDepth(vUv);\n        float outlineDepth = unpack16(texture2D(outlineBuffer, vUv).xy);\n        outlineDepth *= outlineDepth;\n        outlineDepth -= 0.005;\n\n        if(gbufferDepth < outlineDepth) {\n            highlightColor.rgb = highlightColor.rgb * 0.3;\n            edgeColor.rgb = edgeColor.rgb * 0.5;\n        }\n\n        vec4 outColor = edgeColor + highlightColor * (1. - d);\n        finalColor = mix(color.rgb, outlineIntensity * outColor.rgb, outColor.a);\n    } else {\n        finalColor.rgb = color.rgb;\n    }\n    return vec4(finalColor.rgb, color.a);\n}\n","#ifdef USE_ALPHAMAP\n#define USE_UV\n#endif\n\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\nvarying vec3 vViewPosition;\n\nvoid main() {\n\n    #include <skinbase_vertex>\n\n    #include <begin_vertex>\n    #include <morphtarget_vertex>\n    #include <skinning_vertex>\n    #include <displacementmap_vertex>\n    #include <project_vertex>\n    #include <logdepthbuf_vertex>\n    #include <clipping_planes_vertex>\n\n    vViewPosition = - mvPosition.xyz;\n\n}\n","uniform vec2 cameraNearFar;\nvarying vec3 vViewPosition;\n\nvec2 pack16(float value) {\n    float sMax = 65535.0;\n    int v = int(clamp(value, 0.0, 1.0)*sMax+0.5);\n    int digit0 = v/256;\n    int digit1 = v-digit0*256;\n    return vec2(float(digit0)/255.0, float(digit1)/255.0);\n}\n\nfloat linstep(float edge0, float edge1, float value) {\n    return clamp((value-edge0)/(edge1-edge0), 0.0, 1.0);\n}\n\nvoid main() {\n\n    float linearZ = linstep(-cameraNearFar.x, -cameraNearFar.y, -vViewPosition.z);\n    vec2 packedZ = pack16(pow(max(0., linearZ), 0.5));\n\n    gl_FragColor = vec4(packedZ.x, packedZ.y, 0., 0.);\n}\n","import ssaoBilateral from './shaders/ssaoBilateral.glsl'\nimport {\n    CopyShader,\n    ExtendedShaderPass, getOrCall,\n    IPass,\n    IWebGLRenderer,\n    serialize,\n    uniform, ValOrFunc,\n    Vector2,\n    WebGLRenderTarget\n} from \"threepipe\";\n\nexport class BilateralFilterPass extends ExtendedShaderPass implements IPass {\n    @serialize() @uniform() smoothEnabled = true\n    @serialize() @uniform() edgeSharpness = 0.1\n    // @serialize() @uniform() smoothSigma = new Vector4(1, 0.2, 4., 1)\n    // @serialize() @uniform() smoothScale = new Vector4(0, 10, 1, 0)\n\n    constructor(public target?: ValOrFunc<WebGLRenderTarget|undefined>, sourceAccessor = 'rgba') {\n        super({\n            vertexShader: CopyShader.vertexShader,\n            fragmentShader: `\n// for gbuffer\n#include <packing>\n#define THREE_PACKING_INCLUDED\n` + ssaoBilateral,\n            uniforms: {\n                bilDirection: {value: new Vector2(1, 0)},\n                // tNormalDepth: {value: null},\n                tDiffuse: {value: null},\n                tDiffuseSize: {value: new Vector2()},\n            },\n            defines: {\n                ['B_SRC_ACCESSOR']: sourceAccessor,\n            },\n        }, 'tDiffuse')\n        this.clear = false\n        this.needsSwap = false\n    }\n\n    render(renderer: IWebGLRenderer, writeBuffer: WebGLRenderTarget, _readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean) {\n        if (!this.enabled) return\n        const target = getOrCall(this.target)\n        if(!target) return\n\n        this.uniforms.bilDirection.value.set(1, 0)\n\n        this.uniforms.tDiffuse.value = target.texture\n        this.uniforms.tDiffuseSize.value.set(this.uniforms.tDiffuse.value?.image.width || 0, this.uniforms.tDiffuse.value?.image.height || 0)\n        super.render(renderer, writeBuffer, target, deltaTime, maskActive)\n\n        this.uniforms.bilDirection.value.set(0, 1)\n        this.uniforms.tDiffuse.value = writeBuffer.texture\n        this.uniforms.tDiffuseSize.value.set(this.uniforms.tDiffuse.value?.image.width || 0, this.uniforms.tDiffuse.value?.image.height || 0)\n        super.render(renderer, target, writeBuffer, deltaTime, maskActive)\n\n        // this.uniforms.bilDirection.value.set(-1, -1)\n        // this.uniforms.tDiffuse2.value = target.texture\n        // super.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive)\n\n    }\n}\n","import {\n    ExtendedShaderPass,\n    GBufferPlugin,\n    getOrCall,\n    getTexelDecoding,\n    glsl,\n    ICamera,\n    IMaterial,\n    IPassID,\n    IPipelinePass,\n    IRenderManager,\n    IScene,\n    IWebGLRenderer,\n    matDefine,\n    matDefineBool,\n    MaterialExtension,\n    Matrix4,\n    PhysicalMaterial,\n    PipelinePassPlugin,\n    ProgressivePlugin,\n    serialize,\n    shaderReplaceString,\n    shaderUtils,\n    SSAAPlugin,\n    SSAOPlugin,\n    Texture,\n    TextureDataType,\n    ThreeViewer,\n    uiConfig,\n    uiConfigMaterialExtension,\n    uiFolderContainer,\n    uiImage,\n    uiSlider,\n    uiToggle,\n    uniform,\n    UnsignedByteType,\n    ValOrFunc,\n    Vector2,\n    Vector3,\n    WebGLRenderTarget,\n} from 'threepipe'\n// import ssrtaoShader from './shaders/SSGIPlugin.pass.glsl' // todo\n// import ssgiPatch from './shaders/SSGIPlugin.patch.glsl'\nimport samplePointHelpers from './shaders/samplePointHelpers.glsl'\nimport ssrtShader from './shaders/ssrt.glsl'\nimport ssgiPatch from './shaders/giPatch.glsl'\n// import ssrtaoShader from './shaders/ssrtao.glsl'\nimport {BilateralFilterPass} from \"../../passes/BilateralFilterPass\";\nimport {getShaders} from \"../../utils/shaders\";\nimport {VelocityBufferPlugin} from \"../buffer/VelocityBufferPlugin\";\n\nexport type SSGIPluginTarget = WebGLRenderTarget\n\nconst passId = 'ssrtgi'\ntype SSGIPassId = typeof passId\n\n/**\n * SSGI Plugin\n *\n * Adds screen space reflections to the scene.\n * @category Plugins\n */\n@uiFolderContainer('SSGI Plugin')\nexport class SSGIPlugin\n    extends PipelinePassPlugin<SSGIPluginPass, SSGIPassId> {\n\n    readonly passId = passId\n    public static readonly PluginType = 'SSGIPlugin'\n    public static readonly OldPluginType = 'SSGI'\n\n    dependencies = [GBufferPlugin, SSAAPlugin]\n\n    target?: SSGIPluginTarget\n    @uiImage('SSGI Buffer', {readOnly: true}) texture?: Texture\n\n    @uiConfig(undefined, {unwrapContents: true}) declare protected _pass?: SSGIPluginPass\n\n    // @onChange2(SSGIPlugin.prototype._createTarget)\n    // @uiDropdown('Buffer Type', threeConstMappings.TextureDataType.uiConfig)\n    readonly bufferType: TextureDataType // cannot be changed after creation (for now)\n\n    // @onChange2(SSGIPlugin.prototype._createTarget)\n    // @uiSlider('Buffer Size Multiplier', [0.25, 2.0], 0.25)\n    readonly sizeMultiplier: number // cannot be changed after creation (for now)\n\n\n    constructor(\n        bufferType: TextureDataType = UnsignedByteType,\n        sizeMultiplier = 1,\n        enabled = true,\n    ) {\n        super()\n        this.enabled = enabled\n        this.bufferType = bufferType\n        this.sizeMultiplier = sizeMultiplier\n    }\n\n    protected _createTarget(recreate = true) {\n        if (!this._viewer) return\n        if (recreate) this._disposeTarget()\n        if (!this.target)\n            this.target = this._viewer.renderManager.createTarget<SSGIPluginTarget>(\n                {\n                    depthBuffer: false,\n                    type: this.bufferType,\n                    sizeMultiplier: this.sizeMultiplier,\n                    // magFilter: NearestFilter,\n                    // minFilter: NearestFilter,\n                    // generateMipmaps: false,\n                    // encoding: LinearEncoding,\n                })\n        this.texture = this.target.texture\n        this.texture.name = 'ssgiBuffer'\n\n        // if (this._pass) this._pass.target = this.target\n    }\n\n    protected _disposeTarget() {\n        if (!this._viewer) return\n        if (this.target) {\n            this._viewer.renderManager.disposeTarget(this.target)\n            this.target = undefined\n        }\n        this.texture = undefined\n    }\n\n    private _gbufferUnpackExtension = undefined as MaterialExtension|undefined\n    private _gbufferUnpackExtensionChanged = ()=>{\n        if (!this._pass || !this._viewer) throw new Error('SSGIPlugin: pass/viewer not created yet')\n        const newExtension = this._viewer.renderManager.gbufferUnpackExtension\n        if (this._gbufferUnpackExtension === newExtension) return\n        if (this._gbufferUnpackExtension) this._pass.setGBufferUnpackExtension(undefined)\n        this._gbufferUnpackExtension = newExtension\n        if (this._gbufferUnpackExtension) this._pass.setGBufferUnpackExtension(this._gbufferUnpackExtension)\n        else this._viewer.console.warn('SSGIPlugin: GBuffer unpack extension removed')\n    }\n\n    protected _createPass() {\n        if (!this._viewer) throw new Error('SSGIPlugin: viewer not set')\n        if (!this._viewer.renderManager.gbufferTarget || !this._viewer.renderManager.gbufferUnpackExtension)\n            throw new Error('SSGIPlugin: GBuffer target not created. GBufferPlugin is required.')\n        this._createTarget(true)\n        return new SSGIPluginPass(this.passId, ()=>this.target)\n    }\n\n    onAdded(viewer: ThreeViewer) {\n        super.onAdded(viewer)\n        // todo why?\n        if (viewer.getPlugin('Ground') || viewer.getPlugin('BaseGroundPlugin')) console.warn('GroundPlugin must be added after SSGIPlugin')\n\n        // todo updateGBufferFlags like in SSAOPlugin\n\n        this._gbufferUnpackExtensionChanged()\n        viewer.renderManager.addEventListener('gbufferUnpackExtensionChanged', this._gbufferUnpackExtensionChanged)\n        viewer.forPlugin(VelocityBufferPlugin, (vbp) => {\n            this._pass?.material.registerMaterialExtensions([vbp.unpackExtension])\n        }, (vbp)=>{\n            this._pass?.material?.unregisterMaterialExtensions([vbp.unpackExtension])\n        }, this)\n    }\n\n    onRemove(viewer: ThreeViewer): void {\n        this._disposeTarget()\n        viewer.renderManager.removeEventListener('gbufferUnpackExtensionChanged', this._gbufferUnpackExtensionChanged)\n        return super.onRemove(viewer)\n    }\n\n    fromJSON(data: any, meta?: any): this|null|Promise<this|null> {\n        // legacy\n        if (data.passes?.ssrtgi) {\n            data = {...data}\n            data.pass = data.passes.ssrtgi\n            delete data.passes\n            if (data.pass.enabled !== undefined) data.enabled = data.pass.enabled\n        }\n        return super.fromJSON(data, meta)\n    }\n\n    protected _beforeRender(_?: IScene, _1?: ICamera, _2?: IRenderManager): boolean {\n        if (!this._viewer) return false\n        const e = super._beforeRender(_, _1, _2)\n        if (e) { // && !lastEnabled) {\n            const ssao = this._viewer?.getPlugin<SSAOPlugin>('SSAOPlugin')\n            if (ssao && !ssao.isDisabled()) {\n                // const c = confirm('SSAO Plugin needs to be disabled to enable SSRTGI or SSRTAO. Disable now?')\n                // if (!c) {\n                //     this.enabled = false\n                //     e = false // for lastEnabled\n                // } else\n                ssao.disable(SSGIPlugin.PluginType)\n            }\n        }\n        // lastEnabled = e\n        if(!e) return e\n\n        const progressive = this._viewer.getPlugin(ProgressivePlugin)\n        this._pass?.updateShaderProperties([progressive])\n\n        return e\n    }\n\n    /**\n     * @deprecated use {@link target} instead\n     */\n    get rtgiTarget() {\n        console.warn('SSGIPlugin: rtgiTarget is deprecated, use target instead')\n        return this.target\n    }\n\n}\n\n@uiFolderContainer('SSGI Pass')\nexport class SSGIPluginPass extends ExtendedShaderPass implements IPipelinePass {\n    before = ['render']\n    after = ['gbuffer', 'depth']\n    required = ['render', 'progressive'] // gbuffer required check done in plugin.\n\n    @serialize() readonly bilateralPass: BilateralFilterPass\n\n    @uiToggle('GI Enabled')\n    @serialize()\n    @matDefineBool('SSGI_ENABLED', undefined, undefined, SSGIPluginPass.prototype.setDirty, false)\n    giEnabled = true // todo make getter/setter for legacy ssgiEnabled\n\n    @uiSlider('Intensity', [0, 4])\n    @serialize() @uniform() intensity = 2\n\n    @uiSlider('Power', [0, 3])\n    @serialize() @uniform() power = 1.1\n\n    @uiToggle('Auto radius') @serialize() @uniform() autoRadius = true\n\n    @uiSlider('Object Radius', [0.01, 10.0])\n    @serialize() @uniform() objectRadius = 1\n\n    @uiSlider('Tolerance', [0.1, 5])\n    @serialize() @uniform() tolerance = 1\n\n    @uiSlider('Bias', [-0.3, 0.3])\n    @serialize() @uniform() bias = 0.001\n\n    @uiSlider('Falloff', [0.0001, 4])\n    @serialize() @uniform() falloff = 0.7\n\n    // todo\n    // @uiSlider('Roughness Factor', [0.1, 5])\n    // @serialize() @uniform({propKey: 'ssgiRoughnessFactor'}) roughnessFactor = 1\n\n    @uiSlider('Ray Count', [1, 5], 1, {tags: ['performance']})\n    @serialize() @uniform() rayCount = 4\n\n    @uiSlider('Step count', [1, 16], 1, {tags: ['performance']})\n    @serialize()\n    @matDefine('RTAO_STEP_COUNT', undefined, undefined, SSGIPluginPass.prototype.setDirty)\n    stepCount = 8\n\n    @uiToggle('Smooth Enabled')\n    @serialize() smoothEnabled = true\n\n    @uiToggle('Render with Camera')\n    renderWithCamera = true\n\n    // todo\n    // @uiSlider('Low Quality Frames', [0, 4], 1)\n    // @serialize()\n    // @matDefine('SSRTAO_LOW_QUALITY_FRAMES', undefined, undefined, SSGIPluginPass.prototype.setDirty)\n    // lowQualityFrames = 0\n    //\n    // @uiToggle('Ignore front rays')\n    // @serialize()\n    // @matDefineBool('SSRTAO_MASK_FRONT_RAYS', undefined, undefined, SSGIPluginPass.prototype.setDirty)\n    // maskFrontRays = true\n    //\n    // @uiSlider('Mask front rays factor', [-1, 1], 0.01, (that: SSGIPluginPass)=>({hidden: () => !that.maskFrontRays}))\n    // @serialize() @uniform() maskFrontFactor = -0.2\n\n    @uiSlider('Split', [0, 1], 0.01, {tags: ['debug']})\n    @serialize() @uniform({propKey: 'ssrtaoSplitX', onChange: SSGIPluginPass.prototype.setDirty})\n    split = 0\n\n    public readonly passId: IPassID\n\n    constructor(pid: IPassID,\n                public target?: ValOrFunc<WebGLRenderTarget|undefined>,\n                giEnabled = true) {\n        super({\n            defines: {\n                ['RTAO_STEP_COUNT']: 16,\n                // ['SSRTAO_LOW_QUALITY_FRAMES']: 2,\n                // ['SSRTAO_MASK_FRONT_RAYS']: true,\n                ['PERSPECTIVE_CAMERA']: 1, // set in PerspectiveCamera2\n                // ['CHECK_GBUFFER_FLAG']: 0, // todo like ssao plugin\n            },\n            uniforms: {\n                // tDiffuse: {value: null},// todo\n                // tNormalDepth: {value: null},// todo\n\n                // smoothEnabled: {value: false},\n                // smoothSigma: {value: new Vector4(0.5, 0.2, 4., 0.4)},\n                // smoothScale: {value: new Vector4(1, 10, 1, 8)},\n\n                tLastThis: {value: null},\n                tLastFrame: {value: null}, // set in progressive plugin\n                // TODO required?\n                screenSize: {value: new Vector2(0, 0)}, // set in ExtendedRenderMaterial\n                currentFrameCount: {value: 0}, // set in RenderManager\n                frameCount: {value: 0}, // set in RenderManager\n                cameraNearFar: {value: new Vector2(0.1, 1000)}, // set in PerspectiveCamera2\n                cameraPositionWorld: {value: new Vector3()}, // set in PerspectiveCamera2\n                projection: {value: new Matrix4()}, // set in PerspectiveCamera2\n                // saoBiasEpsilon: {value: new Vector3(1, 1, 1)},\n\n                opacity: {value: 1}, // todo?\n                intensity: {value: 0.},\n                objectRadius: {value: 0},\n                autoRadius: {value: giEnabled ? false : true},\n                rayCount: {value: 0.1},\n                bias: {value: 0.015},\n                falloff: {value: 0.7},\n                power: {value: 1.1},\n                // maskFrontFactor: {value: -0.1},\n                tolerance: {value: 0},\n                // ssrtaoRoughnessFactor: {value: 1},\n                sceneBoundingRadius: {value: 0}, // todo do same in SSAO\n\n                // reprojection/velocity\n                currentProjectionViewMatrix: {value: new Matrix4()},\n                lastProjectionViewMatrix: {value: new Matrix4()},\n                inverseViewMatrix: {value: new Matrix4()},\n\n                // split mode\n                ssrtaoSplitX: {value: 0.5},\n            },\n\n            vertexShader: shaderUtils.defaultVertex,\n\n            fragmentShader: `\nvarying vec2 vUv;\n\n// for gbuffer\n#include <packing>\n#define THREE_PACKING_INCLUDED\n#include <cameraHelpers>\n#include <randomHelpers>\n${samplePointHelpers}\n\n${ssrtShader}\n\n${getShaders().calculateGI}\n            `,\n\n        }, 'tDiffuse', 'tLastThis', 'tLastFrame')\n        this.passId = pid\n        this.needsSwap = true\n\n        this.clear = true // todo\n        // this._getUiConfig = this._getUiConfig.bind(this)\n\n        this.giEnabled = giEnabled\n        this.bilateralPass = new BilateralFilterPass(this.target, 'rgba')\n\n        // this._multiplyPass = new GenericBlendTexturePass(this._target.texture as any, 'c = vec4((1.0-b.r) * a.xyz, a.a);')\n        // this._multiplyPass = new GenericBlendTexturePass(this._target.texture as any, 'c = vec4(pow(a.rgb, vec3(a.a*10.)), 1.0);')\n        // this._multiplyPass = new GenericBlendTexturePass(this._target.texture as any, 'c = vec4(b.rgb, 0.)+a;')\n        // this._multiplyPass = new GenericBlendTexturePass(this._target.texture as any, 'c = a;')\n        // this._multiplyPass = new GenericBlendTexturePass(this._target.texture as any, 'c = vec4(0.);')\n        // this._multiplyPass = new GenericBlendTexturePass(this._target.texture as any, 'c = vec4(vec3(pow(max(0.,1.-b.r), b.g*10.)), b.a);')\n    }\n\n    render(renderer: IWebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean) {\n        if (!this.enabled) return\n        this.needsSwap = false\n        // console.log(renderer.renderManager.frameCount)\n        if (!this.renderWithCamera && renderer.renderManager.frameCount < 2) {\n            return\n        }\n\n        const target = getOrCall(this.target)\n        if (!target) {\n            console.warn('SSGIPluginPass: target not defined.')\n            return\n        }\n\n        renderer.renderManager.blit(writeBuffer, {\n            source: target.texture,\n        })\n        if (!this.material.defines.HAS_GBUFFER) {\n            console.warn('SSGIPluginPass: DepthNormalBuffer required for ssrtao/ssgi')\n        }\n\n        this.uniforms.tLastThis.value = writeBuffer.texture\n\n        super.render(renderer, target, readBuffer, deltaTime, maskActive)\n\n        if (this.smoothEnabled) {\n            this.bilateralPass.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive)\n        }\n\n        this.uniforms.lastProjectionViewMatrix.value.copy(this.uniforms.currentProjectionViewMatrix.value)\n\n        // if (this._multiplyPass) {\n        //     this._multiplyPass.uniforms.tDiffuse2.value = this._target.texture as any\n        //     this._multiplyPass.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive)\n        //     this.needsSwap = true\n        // }\n    }\n\n    beforeRender(scene: IScene, camera: ICamera, renderManager: IRenderManager) {\n        if (!this.enabled) return\n        this.updateShaderProperties([scene, camera, renderManager])\n        this.uniforms.currentProjectionViewMatrix.value.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n        this.uniforms.inverseViewMatrix.value.copy(camera.matrixWorld)\n    }\n\n    readonly materialExtension: MaterialExtension = { // todo set priority wrt ssr etc\n        extraUniforms: {\n            tSSGIMap: ()=>({value: getOrCall(this.target)?.texture ?? null}),\n            ssaoPower: this.material.uniforms.power,\n            ssgiIntensity: this.material.uniforms.intensity,\n            ssrtaoSplitX: this.material.uniforms.ssrtaoSplitX,\n            // ssrMaskFrontFactor: this.material.uniforms.maskFrontFactor,\n        },\n        extraDefines: {\n            ['SSGI_ENABLED']: ()=>this.material.defines.SSGI_ENABLED,\n            // ['RTAO_STEP_COUNT']: ()=>this.material.defines.SRTAOSTEP_COUNT,\n            // ['SSRTAO_LOW_QUALITY_FRAMES']: ()=>this.material.defines.SSRTAO_LOW_QUALITY_FRAMES,\n            // ['SSRTAO_MASK_FRONT_RAYS']: ()=>this.material.defines.SSRTAO_MASK_FRONT_RAYS,\n            // ['PERSPECTIVE_CAMERA']: ()=>this.material.defines.PERSPECTIVE_CAMERA,\n            // todo gbuffer stuff\n        },\n        shaderExtender: (shader, _material, _renderer) => {\n            if (!shader.defines?.SSRTAO_ENABLED) return\n            const ls = `\n            \n            ${ssgiPatch}\n            \n#if defined(SSGI_ENABLED) && SSGI_ENABLED > 0\n            // reflectedLight.directDiffuse = vec3(0.);\n            // reflectedLight.indirectDiffuse = vec3(0.);\n            // reflectedLight.directSpecular = vec3(0.);\n            // reflectedLight.indirectSpecular = vec3(0.);\n#endif            \n            `\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader,\n                'vec3 totalDiffuse =', ls, {prepend: true})\n\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <aomap_fragment>', '')\n\n            // ;(shader as any).defines.USE_UV = '' // todo\n\n            // this._gbufferUnpackExtension?.shaderExtender?.(shader, _material, _renderer)\n        },\n        onObjectRender: (_object, material, renderer: IWebGLRenderer) => {\n            // const opaque = !material.transparent && (material as MeshPhysicalMaterial).transmission < 0.001\n            let x: any = this.enabled// && opaque\n            && (this.renderWithCamera || renderer.renderManager.frameCount > 1) &&\n            renderer.userData.screenSpaceRendering !== false &&\n            !material.userData?.pluginsDisabled &&\n            !material.userData?.ssrtaoDisabled &&\n            !material.userData?.ssaoDisabled ? this.split > 0 ? 2 : 1 : 0\n\n            if (material.defines!.SSRTAO_ENABLED !== x) {\n                material.defines!.SSRTAO_ENABLED = x\n                material.needsUpdate = true\n            }\n            // x = material.userData?.ssreflNonPhysical ? 1 : 0\n            // if (material.defines!.SSR_NON_PHYSICAL !== x) {\n            //     material.defines!.SSR_NON_PHYSICAL = x\n            //     material.needsUpdate = true\n            // }\n        },\n        parsFragmentSnippet: (_renderer)=>glsl`\n            #if defined(SSRTAO_ENABLED) && SSRTAO_ENABLED > 0\n            uniform float ssaoPower;\n            uniform float ssgiIntensity;\n            uniform sampler2D tSSGIMap;\n            #if defined(SSRTAO_ENABLED) && SSRTAO_ENABLED == 2\n            uniform float ssrtaoSplitX;\n            #endif\n            ${getTexelDecoding('tSSGIMap', getOrCall(this.target)?.texture.colorSpace)}\n            ${/*tLastFrame not requried in material extension\n            // uniform sampler2D tLastFrame;\n            ${getTexelDecoding('tLastFrame', this.material.uniforms!.tLastFrame.value?.colorSpace)}\n            */''} \n            #include <simpleCameraHelpers>\n            #endif\n        `,\n        computeCacheKey: () => {\n            const tex = getOrCall(this.target)?.texture\n            return (this.enabled ? '1' : '0') + tex?.colorSpace + tex?.uuid + Object.values(this.material.defines).map(v=>v + '').join(',')\n        },\n        uuid: SSGIPlugin.PluginType,\n        ...uiConfigMaterialExtension(this._getUiConfig.bind(this), SSGIPlugin.PluginType),\n        isCompatible: material => {\n            return (material as PhysicalMaterial).isPhysicalMaterial\n        },\n    }\n\n    /**\n     * Returns a uiConfig to toggle SSGI on a material.\n     * This uiConfig is added to each material by extension\n     * @param material\n     * @private\n     */\n    protected _getUiConfig(material: IMaterial) {\n        return {\n            type: 'folder',\n            label: 'SSGI',\n            children: [\n                {\n                    type: 'checkbox',\n                    label: 'Enabled',\n                    get value() {\n                        return !(material.userData.ssgiDisabled ?? false)\n                    },\n                    set value(v) {\n                        if (v === !(material.userData.ssgiDisabled ?? false)) return\n                        material.userData.ssgiDisabled = !v\n                        material.setDirty()\n                    },\n                    onChange: this.setDirty,\n                },\n                // todo ssao cast\n                // {\n                //     type: 'checkbox',\n                //     label: 'Non Physical',\n                //     get value() {\n                //         return material.userData.ssreflNonPhysical ?? false\n                //     },\n                //     set value(v) {\n                //         if (v === (material.userData.ssreflNonPhysical ?? false)) return\n                //         material.userData.ssreflNonPhysical = v\n                //         material.setDirty()\n                //     },\n                //     onChange: this.setDirty,\n                // },\n            ],\n        }\n    }\n\n    set uniformsNeedUpdate(value: true) {\n        this.material.uniformsNeedUpdate = value\n        this.setDirty()\n    }\n\n    protected _gbufferUnpackExtension: MaterialExtension|undefined\n    setGBufferUnpackExtension(extension: MaterialExtension|undefined) {\n        if (this._gbufferUnpackExtension === extension) return\n        if (this._gbufferUnpackExtension) {\n            this.material.unregisterMaterialExtensions([this._gbufferUnpackExtension])\n            this.bilateralPass.material.unregisterMaterialExtensions([this._gbufferUnpackExtension])\n        }\n        this._gbufferUnpackExtension = extension\n        if (this._gbufferUnpackExtension) {\n            this.material.registerMaterialExtensions([this._gbufferUnpackExtension])\n            this.bilateralPass.material.registerMaterialExtensions([this._gbufferUnpackExtension])\n        }\n\n        if (!this._gbufferUnpackExtension) return\n\n        // todo not possible to remove it?\n        // Object.assign(this.materialExtension.extraUniforms!, this._gbufferUnpackExtension.extraUniforms)\n        // Object.assign(this.materialExtension.extraDefines!, this._gbufferUnpackExtension.extraDefines)\n    }\n\n    // todo update gbuffer flag like in AO?\n\n    setDirty() {\n        this.materialExtension?.setDirty?.()\n        super.setDirty();\n    }\n\n}\n\ndeclare module 'threepipe' {\n    interface IMaterialUserData {\n        /**\n         * Disable SSGIPlugin for this material.\n         */\n        ssgiDisabled?: boolean // default false\n        ssreflNonPhysical?: boolean // default false\n        // [SSGIPlugin.PluginType]?: {\n        //     enable?: boolean\n        //     nonPhysical?: boolean\n        // }\n    }\n}\n","import {\n    AssetManager,\n    AViewerPluginSync,\n    getTexelDecoding,\n    glsl,\n    GLTF,\n    GLTFLoaderPlugin,\n    GLTFParser,\n    GLTFWriter2,\n    IMaterial,\n    IObject3D,\n    IShaderPropertiesUpdater,\n    ITexture,\n    makeSamplerUi,\n    MaterialExtension,\n    Matrix3,\n    PhysicalMaterial,\n    serialize,\n    RenderManager,\n    shaderReplaceString,\n    SRGBColorSpace,\n    ThreeViewer,\n    uiFolderContainer,\n    UiObjectConfig,\n    uiToggle,\n    updateMaterialDefines\n} from \"threepipe\";\nimport anisotropyBsdf from './shaders/anisotropyBsdf.glsl' // todo rename\nimport anisotropyTBN from './shaders/anisotropyTBN.glsl'\n\nconst ShaderChunk = RenderManager.ShaderChunk\n// shaders similar to filament https://github.com/repalash/Open-Shaders/blob/aede763ff6fb68c348092574d060c56200a255f5/Engines/filament\n\n/**\n * Anisotropy Plugin\n * Adds a material extension to PhysicalMaterial to support anisotropy maps.\n * Anisotropy is a directional material property that causes the material to reflect light differently depending on the direction of the surface. This is useful for materials like brushed metal, fabric, etc.\n * This is a separate implementation than the anisotropy property in three.js which satisfies `KHR_materials_anisotropy` glTF extension. It includes some additional properties like support for both rotation and directional maps(like Blender), noise, interfacing with the progressive plugin etc.\n *\n * It also adds a UI to the material to edit the settings.\n * It uses WEBGI_materials_anisotropy glTF extension to save the settings in glTF files.\n * @category Plugins\n */\n@uiFolderContainer('Anisotropy (MatExt)')\nexport class AnisotropyPlugin extends AViewerPluginSync {\n    static readonly PluginType = 'AnisotropyPlugin'\n\n    @uiToggle('Enabled', (that: AnisotropyPlugin)=>({onChange: that.setDirty}))\n    @serialize() enabled = true\n\n    // todo add support for bicubic filtering?\n    // @uiToggle('Bicubic', (that: AnisotropyPlugin)=>({onChange: that.setDirty}))\n    // @matDefine('CUSTOM_BUMP_MAP_BICUBIC', undefined, true, AnisotropyPlugin.prototype.setDirty)\n    // @serialize() bicubicFiltering = true\n\n    private _defines: any = {\n        // ['ANISOTROPY_BICUBIC']: false,\n    }\n    private _uniforms: any = {\n        anisotropyFactor: {value: 1},\n        anisotropyNoise: {value: 1},\n        anisotropyDirection: {value: 1},\n        anisotropyDirectionMap: {value: null},\n        anisotropy2MapUvTransform: {value: new Matrix3()},\n        frameCount: {value: 0},\n    }\n\n    public enableAnisotropy(material: IMaterial, map?: ITexture, factor?: number, noise?: number, directionMode?: 'CONSTANT' | 'ROTATION' | 'DIRECTION'): boolean {\n        const ud = material?.userData\n        if (!ud) return false\n        if (ud._isAnisotropic === undefined) {\n            const meshes = material.appliedMeshes\n            let possible = true\n            if (meshes) for (const {geometry} of meshes) {\n                if (geometry && (!geometry.attributes.position || !geometry.attributes.normal || !geometry.attributes.uv)) {\n                    possible = false\n                }\n                if (possible && geometry && !geometry.attributes.tangent) {\n                    geometry.computeTangents()\n                }\n            }\n            if (!possible) {\n                return false\n            }\n        }\n        ud._isAnisotropic = true\n        ud._anisotropyFactor = factor ?? ud._anisotropyFactor ?? 1\n        ud._anisotropyNoise = noise ?? ud._anisotropyNoise ?? 0\n        ud._anisotropyDirection = /*direction ?? */ ud._anisotropyDirection ?? 1 // direction when map is not used\n        ud._anisotropyDirectionMode = directionMode ?? ud._anisotropyDirectionMode ?? 'DIRECTION'\n        ud._anisotropyDirectionMap = map ?? ud._anisotropyDirectionMap ?? null\n        if (material.setDirty) material.setDirty()\n        return true\n    }\n\n    readonly materialExtension: MaterialExtension = {\n        uuid: AnisotropyPlugin.PluginType,\n        priority: 10, // more than sscs(which is 5)\n        shaderExtender: (shader, material, _renderer) => {\n            if (this.isDisabled() || !material?.userData._isAnisotropic) return\n            const rotMap: ITexture | undefined | null = material.userData?._anisotropyDirectionMap\n\n            const bsdfs = glsl`\n                //#if ANISOTROPY_ENABLED\n                #include <randomHelpers>\n                #ifndef D_frameCount\n                #define D_frameCount\n                uniform float frameCount;\n                #endif\n                ${rotMap ? getTexelDecoding('anisotropyDirectionMap', rotMap?.colorSpace) : ''}\\n\n            `\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <common>', bsdfs, {append: true})\n\n            // Because this frag is also patched in SSCS. todo set priority wrt sscs.\n            shader.fragmentShader = shader.fragmentShader.replace('#include <lights_fragment_begin>', ShaderChunk.lights_fragment_begin)\n\n            shader.fragmentShader = shaderReplaceString(\n                shaderReplaceString(shader.fragmentShader,\n                    'IncidentLight directLight;', anisotropyTBN, {prepend: true}),\n                'RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight )',\n                'RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight, anisotropicT, anisotropicB )', {replaceAll: true})\n\n            // eslint-disable-next-line @typescript-eslint/naming-convention\n            let lights_physical_pars_fragment = shaderReplaceString(ShaderChunk.lights_physical_pars_fragment,\n                'void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {',\n                'void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight, const in vec3 anisotropicT, const in vec3 anisotropicB ) {')\n            lights_physical_pars_fragment = shaderReplaceString(lights_physical_pars_fragment,\n                'vec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {',\n                anisotropyBsdf + '\\n', {prepend: true})\n            lights_physical_pars_fragment = shaderReplaceString(lights_physical_pars_fragment,\n                'BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material )',\n                'BRDF_GGX_Anisotropy( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularF90, material.roughness, anisotropicT, anisotropicB )')\n\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <lights_physical_pars_fragment>', lights_physical_pars_fragment)\n\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <normal_fragment_begin>', ShaderChunk.normal_fragment_begin)\n\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader,\n                '#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )',\n                '#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) || defined( USE_TANGENT )')\n\n            // eslint-disable-next-line @typescript-eslint/naming-convention\n            let lights_fragment_maps = glsl`\n                #if defined( USE_ENVMAP )\n                vec3 anisotropyBentNormal = indirectAnisotropyBentNormal(geometryNormal, geometryViewDir, material.roughness, anisotropicT, anisotropicB);\n                #endif\n            ` + ShaderChunk.lights_fragment_maps\n            lights_fragment_maps = shaderReplaceString(lights_fragment_maps,\n                'getIBLIrradiance( geometryNormal )',\n                'getIBLIrradiance( anisotropyBentNormal )')\n            lights_fragment_maps = shaderReplaceString(lights_fragment_maps,\n                'getIBLRadiance( geometryViewDir, geometryNormal, material.roughness )',\n                'getIBLRadiance( geometryViewDir, anisotropyBentNormal, material.roughness )')\n\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <lights_fragment_maps>', lights_fragment_maps)\n\n            shader.vertexShader = shaderReplaceString(shader.vertexShader, '#include <uv_pars_vertex>',\n                `\n#if defined(ANISOTROPY_ENABLED) && ANISOTROPY_ENABLED > 0\n    varying vec2 vAnisotropy2MapUv;\n    uniform mat3 anisotropy2MapUvTransform;\n#endif\n                `, {prepend: true},\n            )\n            shader.vertexShader = shaderReplaceString(shader.vertexShader, '#include <uv_vertex>',\n                `\n#if defined(ANISOTROPY_ENABLED) && ANISOTROPY_ENABLED > 0\n    vAnisotropy2MapUv = ( anisotropy2MapUvTransform * vec3( uv, 1 ) ).xy;\n#endif\n                `, {prepend: true},\n            )\n\n            if(!shader.defines) shader.defines = {}\n            shader.defines.USE_ANISOTROPY_BRDF = '' // for getting the brdf functions in shader\n            shader.defines.USE_UV = ''\n            shader.vertexTangents = true\n        },\n        onObjectRender: (object: IObject3D, material) => {\n            const userData = material.userData\n            if (!userData?._isAnisotropic) return\n            if (!object.isMesh || !object.geometry) return\n            if (!object.geometry.attributes.tangent) {\n                this._viewer?.console.error('AnisotropyPlugin - No tangents on the geometry, cannot use anisotropy. Make sure the tangents are computed before rendering the model. The model will render as black.', object)\n                // throw new Error('AnisotropyPlugin: No tangents on the geometry')\n                // mesh.geometry.computeTangents() // tangents must be set before onBeforeRender call, otherwise it's not set in the program.\n            }\n            this._uniforms.anisotropyFactor.value = userData._anisotropyFactor ?? 1\n            this._uniforms.anisotropyNoise.value = userData._anisotropyNoise ?? 0\n            this._uniforms.anisotropyDirection.value = userData._anisotropyDirection ?? 1\n            const tex = userData._anisotropyDirectionMap?.isTexture ? userData._anisotropyDirectionMap : null\n            this._uniforms.anisotropyDirectionMap.value = tex\n            if (tex) {\n                tex.updateMatrix()\n                this._uniforms.anisotropy2MapUvTransform.value.copy(tex.matrix)\n            }\n            updateMaterialDefines({\n                ...this._defines,\n                ['ANISOTROPY_ENABLED']: +this.enabled,\n                // CONSTANT | ROTATION | DIRECTION\n                ['ANISOTROPY_TEX_MODE']: !tex ? 0 : userData._anisotropyDirectionMode === 'DIRECTION' ? 2 : userData._anisotropyDirectionMode === 'ROTATION' ? 1 : 0,\n            }, material)\n        },\n        extraUniforms: {\n            // ...this._uniforms, // done in constructor\n        },\n        computeCacheKey: material1 => {\n            return (this.enabled ? '1' : '0') + (material1.userData?._isAnisotropic ? '1' : '0') + material1.userData?._anisotropyDirectionMap?.uuid // todo: srgb ext + material1.userData?._anisotropyDirectionMap?.encoding\n        },\n        isCompatible: (material1: PhysicalMaterial) => material1.isPhysicalMaterial,\n        updaters: () =>\n            [\n                // this._viewer?.getPlugin(ProgressivePlugin),\n                // this._viewer?.scene.mainCamera,\n                this._viewer?.renderManager,\n            ] as IShaderPropertiesUpdater[],\n        getUiConfig: material => {\n            const viewer = this._viewer!\n            const enableAnisotropy = this.enableAnisotropy.bind(this)\n            const state = material.userData\n            const config: UiObjectConfig = {\n                type: 'folder',\n                label: 'Anisotropy',\n                onChange: (ev)=>{\n                    if (!ev.config) return\n                    this.setDirty()\n                },\n                children: [\n                    {\n                        type: 'checkbox',\n                        label: 'Enabled',\n                        get value() {\n                            return state._isAnisotropic || false\n                        },\n                        set value(v) {\n                            if (v === state._isAnisotropic) return\n                            if (v) {\n                                if (!enableAnisotropy(material))\n                                    viewer.dialog.alert('AnisotropyPlugin - One or more geometries cannot be made anisotropic.')\n                            } else {\n                                state._isAnisotropic = false\n                                if (material.setDirty) material.setDirty()\n                            }\n                            config.uiRefresh?.(true, 'postFrame')\n                        },\n                    },\n                    {\n                        type: 'slider',\n                        label: 'Factor',\n                        bounds: [-2, 2],\n                        hidden: () => !state._isAnisotropic,\n                        property: [state, '_anisotropyFactor'],\n                        // onChange: this.setDirty,\n                    },\n                    {\n                        type: 'slider',\n                        label: 'Noise',\n                        bounds: [0, 2],\n                        hidden: () => !state._isAnisotropic,\n                        property: [state, '_anisotropyNoise'],\n                        // onChange: this.setDirty,\n                    },\n                    {\n                        type: 'dropdown',\n                        label: 'Mode',\n                        hidden: () => !state._isAnisotropic,\n                        property: [state, '_anisotropyDirectionMode'],\n                        children: ([\n                            'CONSTANT',\n                            'ROTATION',\n                            'DIRECTION',\n                        ] as string[]).map(value => ({\n                            label: value,\n                        })),\n                        onChange: ()=>{\n                            if (material.setDirty) material.setDirty()\n                            config.uiRefresh?.(true, 'postFrame')\n                        },\n                    },\n                    {\n                        type: 'slider',\n                        label: 'Direction',\n                        bounds: [0, 5],\n                        hidden: () => state._anisotropyDirectionMode === 'CONSTANT' || !state._isAnisotropic,\n                        property: [state, '_anisotropicDirection'],\n                        // onChange: this.setDirty,\n                    },\n                    {\n                        type: 'image',\n                        label: 'Texture',\n                        hidden: () => !state._isAnisotropic || state._anisotropyDirectionMode === 'CONSTANT',\n                        property: [state, '_anisotropyDirectionMap'],\n                        onChange: ()=>{\n                            if (material.setDirty) material.setDirty()\n                        },\n                    },\n                    makeSamplerUi(state as any, '_anisotropyDirectionMap', 'Sampler',() => !state._isAnisotropic || state._anisotropyDirectionMode === 'CONSTANT', ()=>material.setDirty && material.setDirty()),\n                ],\n            }\n            return config\n        },\n\n        // todo errors will be fixed on threepipe update\n        onMaterialUpdate: (material)=>{\n            if (!material.userData?._isAnisotropic) return\n            material.userData.__appliedMeshes?.forEach((m: any)=> this.tryComputeTangents(m, [material]))\n        },\n        onRegister: (material)=>{\n            if (!material.userData?._isAnisotropic) return\n            material.userData.__appliedMeshes?.forEach((m: any)=> this.tryComputeTangents(m, [material]))\n        },\n        onAddToMesh: (mesh: IObject3D)=>{\n            if(!mesh.isMesh) return\n            const m = mesh\n            const mats = Array.isArray(m.material) ? m.material : [m.material]\n            if (!mats.find(m1=>m1?.userData?._isAnisotropic)) return\n            this.tryComputeTangents(m, mats as any)\n        },\n    }\n\n    tryComputeTangents(m: IObject3D, mats: IMaterial[]) {\n        if (m.geometry && !m.geometry.attributes.tangent) {\n            let possible = true\n            if (!m.geometry.index || !m.geometry.attributes.position || !m.geometry.attributes.normal || !m.geometry.attributes.uv) {\n                possible = false\n            }\n            if (possible) m.geometry.computeTangents()\n            else mats.map(m1=>{\n                if (m1?.userData?._isAnisotropic) m1.userData._isAnisotropic = false\n            })\n        }\n    }\n\n    setDirty = (): void => {\n        this.materialExtension.setDirty?.()\n        this._viewer?.setDirty()\n    }\n\n    constructor() {\n        super()\n        Object.assign(this.materialExtension.extraUniforms!, this._uniforms)\n    }\n\n    onAdded(v: ThreeViewer) {\n        super.onAdded(v)\n        v.assetManager.materials.registerMaterialExtension(this.materialExtension)\n        v.assetManager.registerGltfExtension(anisotropyGLTFExtension)\n    }\n\n    onRemove(v: ThreeViewer) {\n        v.assetManager.materials?.unregisterMaterialExtension(this.materialExtension)\n        v.assetManager.unregisterGltfExtension(anisotropyGLTFExtension.name)\n        return super.onRemove(v)\n    }\n\n    // @uiButton('Enable Anisotropy (selected)', (that: AnisotropyPlugin)=>({hidden: ()=>!that._viewer?.getPlugin(PickingPlugin)}))\n    // makeSelectedAnisotropic = (): boolean => {\n    //     const material = (this._viewer?.getPlugin(PickingPlugin)?.getSelectedObject() as any)?.material as IMaterial\n    //     if (material?.assetType !== 'material') return false\n    //     return this.enableAnisotropy(material)\n    // }\n\n    /**\n     * @deprecated use {@link anisotropyGLTFExtension}\n     */\n    public static readonly ANISOTROPY_GLTF_EXTENSION = 'WEBGI_materials_anisotropy'\n\n\n    /**\n     * @deprecated - use {@link enableAnisotropy} instead\n     * @param material\n     */\n    public makeAnisotropic(material: IMaterial): boolean {\n        return this.enableAnisotropy(material)\n    }\n}\n\ndeclare module 'threepipe' {\n    interface IMaterialUserData {\n        /**\n         * Is the material anisotropic\n         */\n        _isAnisotropic?: boolean\n        /**\n         * Anisotropy factor\n         */\n        _anisotropyFactor?: number\n        /**\n         * Anisotropy noise factor\n         */\n        _anisotropyNoise?: number\n        /**\n         * Anisotropy direction mode\n         */\n        _anisotropyDirectionMode?: 'CONSTANT' | 'ROTATION' | 'DIRECTION'\n        /**\n         * Anisotropy direction map, when mode is ROTATION or DIRECTION\n         */\n        _anisotropyDirectionMap?: ITexture | null\n        /**\n         * Direction when map is not used, when mode is CONSTANT\n         */\n        _anisotropyDirection?: number\n    }\n}\n\n/**\n * Anisotropy Materials Extension\n *\n * Specification: https://webgi.xyz/docs/gltf-extensions/WEBGI_materials_anisotropy.html\n */\n\nclass GLTFMaterialsAnisotropyExtensionImport implements GLTFLoaderPlugin {\n    public name: string\n    public parser: GLTFParser\n\n    constructor(parser: GLTFParser) {\n\n        this.parser = parser\n        this.name = anisotropyGLTFExtension.name\n\n    }\n\n    async extendMaterialParams(materialIndex: number, materialParams: any) {\n\n        const parser = this.parser\n        const materialDef = parser.json.materials[materialIndex]\n\n        if (!materialDef.extensions || !materialDef.extensions[this.name]) {\n\n            return Promise.resolve()\n\n        }\n\n        const pending = []\n\n        const extension = materialDef.extensions[this.name]\n\n        if (!materialParams.userData) materialParams.userData = {}\n        materialParams.userData._isAnisotropic = true // single _ so that its saved when cloning( and tojson) but not when saving glb\n        materialParams.userData._anisotropyFactor = extension.anisotropyFactor ?? 0.0\n        materialParams.userData._anisotropyNoise = extension.anisotropyNoiseFactor ?? extension.anisotropyNoise ?? 0.\n\n        let {anisotropyDirectionMode, anisotropyDirection} = extension\n\n        // backwards compatibility. todo: make changes to blender plugin.\n        if (!anisotropyDirectionMode) anisotropyDirectionMode = extension.anisotropyTextureMode\n        if (!anisotropyDirection) anisotropyDirection = extension.anisotropyRotation\n\n        materialParams.userData._anisotropyDirectionMode = anisotropyDirectionMode && typeof anisotropyDirection?.index === 'number' ? anisotropyDirectionMode : 'CONSTANT'\n        if (anisotropyDirectionMode === 'ROTATION' || anisotropyDirectionMode === 'DIRECTION') {\n            pending.push(parser.assignTexture(materialParams.userData, '_anisotropyDirectionMap', anisotropyDirection).then((t: any) => {\n                // t.format = RGBFormat\n                t.colorSpace = SRGBColorSpace\n            }))\n            // pending.push(parser.assignTexture(materialParams, 'map', anisotropyDirection))\n        } else {\n            materialParams.userData._anisotropyDirection = anisotropyDirection ?? 0\n        }\n        return Promise.all(pending)\n    }\n\n    afterRoot(result: GLTF): Promise<void> | null {\n        result.scene?.traverse((object: any) => {\n            const mat = object.material?.userData?._isAnisotropic\n            if (!mat) return\n            const geom = object.geometry\n            if (!geom.attributes.tangent) {\n                geom.computeTangents()\n                geom.attributes.tangent.needsUpdate = true\n            }\n\n        })\n        return null\n    }\n\n}\n\n\nconst glTFMaterialsAnisotropyExtensionExport = (w: GLTFWriter2)=> ({\n    writeMaterial: (material: any, materialDef: any) => {\n        if (!material.isMeshStandardMaterial || !material.userData._isAnisotropic) return\n\n        if ((material.userData._anisotropyFactor || 0) < 0.001) return // todo: is this correct?\n\n        materialDef.extensions = materialDef.extensions || {}\n\n        const extensionDef: any = {}\n\n        extensionDef.anisotropyFactor = material.userData._anisotropyFactor || 1.0\n        extensionDef.anisotropyNoiseFactor = material.userData._anisotropyNoise || 0.0\n        extensionDef.anisotropyDirectionMode = material.userData._anisotropyDirectionMode || 'CONSTANT'\n\n        if (w.checkEmptyMap(material.userData._anisotropyDirectionMap) && extensionDef.anisotropyDirectionMode !== 'CONSTANT') {\n\n            const anisotropyDirectionMapDef = {index: w.processTexture(material.userData._anisotropyDirectionMap)}\n            w.applyTextureTransform(anisotropyDirectionMapDef, material.userData._anisotropyDirectionMap)\n            extensionDef.anisotropyDirection = anisotropyDirectionMapDef\n\n        } else {\n\n            extensionDef.anisotropyDirectionMode = 'CONSTANT'\n            extensionDef.anisotropyDirection = material.userData._anisotropyDirection || 0.0\n\n        }\n\n        materialDef.extensions[ anisotropyGLTFExtension.name ] = extensionDef\n        w.extensionsUsed[ anisotropyGLTFExtension.name ] = true\n    },\n})\n\nexport const anisotropyGLTFExtension = {\n    name: 'WEBGI_materials_anisotropy',\n    import: (p) => new GLTFMaterialsAnisotropyExtensionImport(p),\n    export: glTFMaterialsAnisotropyExtensionExport,\n    textures: {\n        anisotropyDirection: 'RGB',\n    },\n} satisfies AssetManager['gltfExtensions'][number]\n\n// https://github.com/mcneel/cycles/blob/ad3f1826cdeebc9a44c530ed450ed94f9148b5e6/src/kernel/shaders/stdosl.h#L385\n// vec3 rotate(vec3 p, float angle, vec3 a, vec3 b)\n// {\n//    vec3 axis = normalize(b - a);\n//    float cosang, sinang;\n//    sinang = sin(angle);\n//    cosang = cos(angle);\n//    float cosang1 = 1.0 - cosang;\n//    float x = axis.x, y = axis.y, z = axis.z;\n//    mat3 M = mat3(x * x + (1.0 - x * x) * cosang,\n//    x * y * cosang1 + z * sinang,\n//    x * z * cosang1 - y * sinang,\n//    x * y * cosang1 - z * sinang,\n//    y * y + (1.0 - y * y) * cosang,\n//    y * z * cosang1 + x * sinang,\n//    x * z * cosang1 + y * sinang,\n//    y * z * cosang1 - x * sinang,\n//    z * z + (1.0 - z * z) * cosang\n//    );\n//    return M * (p - a) + a;\n// }\n\n// vec3 rotate(vec3 p, float angle, vec3 b)\n// {\n//    vec3 axis = normalize(b);\n//    float cosang = cos(angle), sinang = sin(angle);\n//    float cosang1 = 1.0 - cosang;\n//    float x = axis.x, y = axis.y, z = axis.z;\n//    mat3 M = mat3(x * x + (1.0 - x * x) * cosang,\n//    x * y * cosang1 + z * sinang,\n//    x * z * cosang1 - y * sinang,\n//    x * y * cosang1 - z * sinang,\n//    y * y + (1.0 - y * y) * cosang,\n//    y * z * cosang1 + x * sinang,\n//    x * z * cosang1 + y * sinang,\n//    y * z * cosang1 - x * sinang,\n//    z * z + (1.0 - z * z) * cosang\n//    );\n//    return M * p;\n// }\n","\nfloat rnd = (random2(vUv.xy, frameCount)-0.5) * anisotropyNoise * material.roughness;\n\n#if ANISOTROPY_TEX_MODE < 2\n#if ANISOTROPY_TEX_MODE == 0 // CONSTANT rotation\nfloat rot = saturate(anisotropyDirection) ;\n//vec3 anisotropicT = normalize(mix(tbn[0], tbn[1], rot));\n#else // ROTATION map\nfloat rot = (anisotropyDirectionMapTexelToLinear(texture2D(anisotropyDirectionMap, vAnisotropy2MapUv)).r);\n#endif\nrot = rot * 2. * PI + rnd;\nvec2 rot2 = vec2(sin(rot), cos(rot));\n// Rotate tangent from cycles https://github.com/mcneel/cycles/blob/ad3f1826cdeebc9a44c530ed450ed94f9148b5e6/src/kernel/shaders/node_principled_bsdf.osl#L56\n//vec3 anisotropicT = normalize(rotate(tbn[0], rot, normal)); // rotate fn at the bottom\n//vec3 anisotropicT = (tbn[0] * sin(rot) + tbn[1] * cos(rot));\n\n#else // DIRECTION map\nvec2 rot2 = (anisotropyDirectionMapTexelToLinear(texture2D(anisotropyDirectionMap, vAnisotropy2MapUv)).rg * 2. - 1.) + vec2(rnd, rnd);\nrot2 = normalize(rot2);\n\nconst float anisoSpecMultiplier = 0.25;\n\nfloat matSpecAniso = (length(material.specularColor.rgb))*2.*PI;\nrot2 = mix(rot2, vec2(sin(matSpecAniso), cos(matSpecAniso)), anisoSpecMultiplier);\nrot2 = normalize(rot2);\n\n#endif\n\n\nvec3 anisotropicT = (tbn[0] * rot2.x + tbn[1] * rot2.y);\n\n\n// reproject on normal plane\nanisotropicT = normalize(anisotropicT - normal * dot(anisotropicT, normal));\nvec3 anisotropicB = normalize(cross(normal, anisotropicT));\n\n","import {\n    BufferGeometry2,\n    getOrCall,\n    IMaterial,\n    IShaderPropertiesUpdater,\n    IWebGLRenderer,\n    MaterialExtension,\n    MathUtils,\n    Matrix4,\n    Mesh2,\n    onChange,\n    PerspectiveCamera,\n    PhysicalMaterial,\n    Plane,\n    shaderReplaceString,\n    Texture,\n    ValOrFunc,\n    Vector2,\n    Vector3,\n    Vector4,\n    WebGLRenderTarget\n} from 'threepipe'\nimport poissonDiskSamples from './shaders/poissonDiskSamples.glsl'\nimport reflectorSample from './shaders/reflectorSample.glsl'\n\nexport class Reflector2<TG extends BufferGeometry2 = BufferGeometry2> extends Mesh2<TG, PhysicalMaterial> {\n    public type = 'Reflector'\n    public readonly isReflector2 = true\n    private _renderTarget: ValOrFunc<WebGLRenderTarget|undefined>\n    // private _renderTarget2: WebGLRenderTarget\n    public readonly textureMatrix: Matrix4\n\n    private _getRenderTarget(){\n        const target = getOrCall(this._renderTarget)\n        if(target) {\n            if (target.texture.generateMipmaps && (!MathUtils.isPowerOfTwo(target.texture.image.width) || !MathUtils.isPowerOfTwo(target.texture.image.height)))\n                target.texture.generateMipmaps = false\n\n            this.materialExtension.extraUniforms.tRefDiffuse.value = target.texture\n            this.materialExtension.extraUniforms.tRefDiffuseSize.value.set(target.width, target.height)\n            // this.materialExtension.extraUniforms.tRefDepth.value = target.depthTexture\n        }\n        return target\n    }\n\n    @onChange(Reflector2.prototype._updateExtension)\n    public enabled = true\n\n    @onChange(Reflector2.prototype._updateExtension)\n    public reflectorModePhysical = true // shows envmap in reflection\n\n    public reflectionTargetNeedsUpdate = true\n    public transparentReflectionBackground = true // todo change to reflectBackground or something\n\n    private _updateExtension() {\n        this.transparentReflectionBackground = this.reflectorModePhysical\n        this.materialExtension?.setDirty?.()\n    }\n\n    constructor(geometry: TG, renderTarget: ValOrFunc<WebGLRenderTarget|undefined>, clipBias = 0, material: PhysicalMaterial) {\n        super(geometry, material)\n\n        this._renderTarget = renderTarget\n        // todo: do we need to dispose this on RT dispose??\n        // this._renderTarget.depthTexture = new DepthTexture(renderTarget.width / 2, renderTarget.height / 2, UnsignedByteType)\n\n        const reflectorPlane = new Plane()\n        const normal = new Vector3()\n        const reflectorWorldPosition = new Vector3()\n        const cameraWorldPosition = new Vector3()\n        const rotationMatrix = new Matrix4()\n        const lookAtPosition = new Vector3(0, 0, -1)\n        const clipPlane = new Vector4()\n\n        const view = new Vector3()\n        const target = new Vector3()\n        const q = new Vector4()\n\n        const textureMatrix = new Matrix4()\n        const virtualCamera = new PerspectiveCamera()\n\n        this.onBeforeRender = (renderer: IWebGLRenderer, scene, camera) => {\n\n            if (!this.enabled || !(renderer as any).userData.mainRenderPass) return // mainRenderPass is set in RenderPass2\n\n            if (!this.reflectionTargetNeedsUpdate) {\n                return\n            }\n            const thisRenderTarget = this._getRenderTarget()\n            if(!thisRenderTarget){\n                console.warn('Reflector2: No render target set.')\n                return\n            }\n\n            const viewOffset = (camera as PerspectiveCamera).view ? Object.assign({}, (camera as PerspectiveCamera).view) : null\n            // clear camera jitter\n            viewOffset && (camera as PerspectiveCamera).clearViewOffset && (camera as PerspectiveCamera).clearViewOffset()\n\n            reflectorWorldPosition.setFromMatrixPosition(this.matrixWorld)\n            cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld)\n\n            rotationMatrix.extractRotation(this.matrixWorld)\n\n            normal.set(0, 0, 1)\n            normal.applyMatrix4(rotationMatrix)\n\n            view.subVectors(reflectorWorldPosition, cameraWorldPosition)\n\n            // Avoid rendering when reflector is facing away\n\n            if (view.dot(normal) > 0) return\n\n            view.reflect(normal).negate()\n            view.add(reflectorWorldPosition)\n\n            rotationMatrix.extractRotation(camera.matrixWorld)\n\n            lookAtPosition.set(0, 0, -1)\n            lookAtPosition.applyMatrix4(rotationMatrix)\n            lookAtPosition.add(cameraWorldPosition)\n\n            target.subVectors(reflectorWorldPosition, lookAtPosition)\n            target.reflect(normal).negate()\n            target.add(reflectorWorldPosition)\n\n            virtualCamera.position.copy(view)\n            virtualCamera.up.set(0, 1, 0)\n            virtualCamera.up.applyMatrix4(rotationMatrix)\n            virtualCamera.up.reflect(normal)\n            virtualCamera.lookAt(target)\n\n            virtualCamera.far = 2. // Used in WebGLBackground\n            virtualCamera.near = 0. // Used in WebGLBackground\n\n            virtualCamera.updateMatrixWorld()\n            virtualCamera.projectionMatrix.copy(camera.projectionMatrix)\n\n            // Update the texture matrix\n            textureMatrix.set(\n                0.5, 0.0, 0.0, 0.5,\n                0.0, 0.5, 0.0, 0.5,\n                0.0, 0.0, 0.5, 0.5,\n                0.0, 0.0, 0.0, 1.0\n            )\n            textureMatrix.multiply(virtualCamera.projectionMatrix)\n            textureMatrix.multiply(virtualCamera.matrixWorldInverse)\n            textureMatrix.multiply(this.matrixWorld)\n\n            // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html\n            // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf\n            reflectorPlane.setFromNormalAndCoplanarPoint(normal, reflectorWorldPosition)\n            reflectorPlane.applyMatrix4(virtualCamera.matrixWorldInverse)\n\n            clipPlane.set(reflectorPlane.normal.x, reflectorPlane.normal.y, reflectorPlane.normal.z, reflectorPlane.constant)\n\n            const projectionMatrix = virtualCamera.projectionMatrix\n\n            q.x = (Math.sign(clipPlane.x) + projectionMatrix.elements[ 8 ]) / projectionMatrix.elements[ 0 ]\n            q.y = (Math.sign(clipPlane.y) + projectionMatrix.elements[ 9 ]) / projectionMatrix.elements[ 5 ]\n            q.z = -1.0\n            q.w = (1.0 + projectionMatrix.elements[ 10 ]) / projectionMatrix.elements[ 14 ]\n\n            // Calculate the scaled plane vector\n            clipPlane.multiplyScalar(2.0 / clipPlane.dot(q))\n\n            // Replacing the third row of the projection matrix\n            projectionMatrix.elements[ 2 ] = clipPlane.x\n            projectionMatrix.elements[ 6 ] = clipPlane.y\n            projectionMatrix.elements[ 10 ] = clipPlane.z + 1.0 - clipBias\n            projectionMatrix.elements[ 14 ] = clipPlane.w\n\n            // Render\n            this.visible = false\n\n            const currentRenderTarget = renderer.getRenderTarget()\n\n            const currentXrEnabled = renderer.xr.enabled\n            const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate\n\n            renderer.xr.enabled = false // Avoid camera modification\n            renderer.shadowMap.autoUpdate = false // Avoid re-computing shadows\n\n            renderer.setRenderTarget(thisRenderTarget)\n\n            renderer.state.buffers.depth.setMask(true) // make sure the depth buffer is writable so it can be properly cleared, see #18897\n\n            // noinspection PointlessBooleanExpressionJS\n            if (renderer.autoClear === false) renderer.clear()\n\n            const sceneBackground = scene.background as any\n            // console.log((sceneBackground as any)?.uuid)\n            if (this.transparentReflectionBackground) scene.background = null // Avoid the background in the reflection\n\n            const renderBackground = !this.transparentReflectionBackground\n            if (sceneBackground?.isTexture && renderBackground) {\n                if (!sceneBackground.userData) sceneBackground.userData = {}\n                sceneBackground.userData.flipX = !sceneBackground.userData.flipX\n            }\n\n            renderer.renderWithModes({\n                shadowMapRender:false,\n                backgroundRender: renderBackground,\n                opaqueRender:true,\n                transparentRender:true,\n                transmissionRender:false, // todo: render transmissive objects somehow\n                screenSpaceRendering:false,\n            }, ()=> renderer.render(scene, virtualCamera))\n\n            if (sceneBackground?.isTexture && renderBackground) {\n                sceneBackground.userData.flipX = !sceneBackground.userData.flipX || undefined\n            }\n\n            if (this.transparentReflectionBackground) scene.background = sceneBackground\n\n            renderer.xr.enabled = currentXrEnabled\n            renderer.shadowMap.autoUpdate = currentShadowAutoUpdate\n\n            renderer.setRenderTarget(currentRenderTarget)\n\n            if (viewOffset?.enabled && (camera as PerspectiveCamera).setViewOffset)\n                (camera as PerspectiveCamera).setViewOffset(viewOffset.fullWidth, viewOffset.fullHeight, viewOffset.offsetX, viewOffset.offsetY, viewOffset.width, viewOffset.height)\n\n            // Restore viewport\n\n            const viewport = (camera as any).viewport\n\n            if (viewport !== undefined) {\n\n                renderer.state.viewport(viewport)\n\n            }\n\n            this.visible = true\n\n            this.reflectionTargetNeedsUpdate = false\n\n        }\n\n        this.textureMatrix = textureMatrix\n        this.materialExtension.extraUniforms.refTextureMatrix.value = textureMatrix\n\n    }\n\n    getRenderTarget() {\n        return this._renderTarget\n    }\n\n    readonly materialExtension = {\n        extraUniforms: {\n            // tRefDepth: {value: null},\n            tRefDiffuse: {value: null as Texture|null},\n            tRefDiffuseSize: {value: new Vector2()},\n            refTextureMatrix: {value: new Matrix4()},\n            frameCount: {value: 0},\n            sceneBoundingRadius: {value: 0},\n        },\n        extraDefines: {\n            // eslint-disable-next-line @typescript-eslint/naming-convention\n            USE_UV: '',\n        },\n        updaters: [] as IShaderPropertiesUpdater[] | (() => IShaderPropertiesUpdater[]),\n        shaderExtender: (shader, _material, _renderer) => {\n            if (this.enabled) {\n                shader.vertexShader = shaderReplaceString(shader.vertexShader, 'void main() {', 'void main() {\\nvRefUv = refTextureMatrix * vec4( position, 1.0 );')\n                // if (!shader.fragmentShader.includes('#include <map_fragment>')) console.error('Shader modified before this.')\n                const ls = '#glMarker beforeModulation'\n                shader.fragmentShader = shaderReplaceString(shader.fragmentShader, ls, `\n                    if(roughnessFactor < 0.95) {\n                        float d = 0.;//textureProj(tRefDepth, vRefUv).r;\n                        // d = min(2., max(0., (d-0.06) * ((7./3.-ior)) * sceneBoundingRadius));\n                        vec4 refBaseColor = getReflectionColor(material.roughness, material.roughness * d);\n                        // refBaseColor.rgb = vec3(refBaseColor.a);\n                        // refBaseColor.a *= 1.0 - clamp(material.roughness * .3, 0., 1.);\n                        `\n                    + (this.reflectorModePhysical ? `\n                        #if !defined(SSR_ENABLED) || SSR_ENABLED < 1 \n                        vec3 specularColor = EnvironmentBRDF(geometryNormal, geometryViewDir, material.specularColor.rgb, material.specularF90, material.roughness);\n                        #endif\n                        reflectedLight.indirectSpecular = mix(vec3(reflectedLight.indirectSpecular), saturate(specularColor.rgb * refBaseColor.rgb), refBaseColor.a);\n                        ` : `\n                        reflectedLight.indirectSpecular = saturate(diffuseColor.rgb * refBaseColor.rgb);\n                        diffuseColor.a *= refBaseColor.a;\n                        `) +\n                    '}\\n' + ls) // todo: this is a hacky way to handle transparent object, use a MeshBasicMaterial instead            // ;(shader as any).vertexUvs = true\n            }\n\n        },\n        parsVertexSnippet: ()=>!this.enabled ? '' : `\n\t\tuniform mat4 refTextureMatrix;\n\t\tvarying vec4 vRefUv;\n`,\n        parsFragmentSnippet: ()=>this.enabled ? poissonDiskSamples + '\\n' + reflectorSample : '',\n        computeCacheKey: (material: IMaterial)=>{\n            return this.enabled + ' ' + material.transparent + ' ' + this.reflectorModePhysical + ' '\n        },\n        onObjectRender: (_object, material) => {\n            if (material.userData.__lastTransparent !== material.transparent) {\n                material.needsUpdate = true\n                material.userData.__lastTransparent = material.transparent\n            }\n        },\n        isCompatible: material => {\n            return (material as PhysicalMaterial).isPhysicalMaterial\n        },\n        setDirty: ()=>(this.materialExtension as MaterialExtension).__setDirty?.()\n    } satisfies MaterialExtension\n}\n\n(Reflector2.prototype as any).isReflector = true\n","class e{static _xfnv1a(e){let t=2166136261;for(let i=0;i<e.length;i++)t=Math.imul(t^e.charCodeAt(i),16777619);return()=>(t+=t<<13,t^=t>>>7,t+=t<<3,t^=t>>>17,(t+=t<<5)>>>0)}}class t extends e{constructor(e){super(),Object.defineProperty(this,\"a\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.a=t._xfnv1a(e)()}next(){let e=this.a+=1831565813;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296}}class i extends e{constructor(e){super(),Object.defineProperty(this,\"a\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"b\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"c\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"d\",{enumerable:!0,configurable:!0,writable:!0,value:void 0});const t=i._xfnv1a(e);this.a=t(),this.b=t(),this.c=t(),this.d=t()}next(){this.a>>>=0,this.b>>>=0,this.c>>>=0,this.d>>>=0;let e=this.a+this.b|0;return this.a=this.b^this.b>>>9,this.b=this.c+(this.c<<3)|0,this.c=this.c<<21|this.c>>>11,this.d=this.d+1|0,e=e+this.d|0,this.c=this.c+e|0,(e>>>0)/4294967296}}class r extends e{constructor(e){super(),Object.defineProperty(this,\"a\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"b\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"c\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"d\",{enumerable:!0,configurable:!0,writable:!0,value:void 0});const t=r._xfnv1a(e);this.a=t(),this.b=t(),this.c=t(),this.d=t()}next(){const e=this.b<<9;let t=5*this.b;return t=9*(t<<7|t>>>25),this.c^=this.a,this.d^=this.b,this.b^=this.c,this.a^=this.d,this.c^=e,this.d=this.d<<11|this.d>>>21,(t>>>0)/4294967296}}var s;!function(e){e.sfc32=\"sfc32\",e.mulberry32=\"mulberry32\",e.xoshiro128ss=\"xoshiro128ss\"}(s||(s={}));class a{constructor(e,t=s.sfc32){Object.defineProperty(this,\"str\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"prng\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"generator\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.str=e,this.prng=t,this.generator=this._initializeGenerator()}next(){return this.generator.next()}_initializeGenerator(){if((e=>null===e)(e=this.str)||(e=>void 0===e)(e))return this.wrap();var e;switch(this.prng){case\"sfc32\":return new i(this.str);case\"mulberry32\":return new t(this.str);case\"xoshiro128ss\":return new r(this.str);default:return this.wrap()}}wrap(){return{next:()=>Math.random()}}}export{s as PRNG,a as default};\n","import {\n    Color,\n    copyObject3DUserData,\n    DirectionalLight2,\n    IDisposable,\n    Serialization,\n    SerializationMetaType,\n    serialize,\n    ThreeSerialization,\n    Vector2,\n    Vector3\n} from 'threepipe'\nimport Rand from \"rand-seed\";\n\nexport interface RDShadowParams {\n    frustumSize: number,\n    far: number,\n    bias: number,\n    width: number,\n    near: number,\n    enabled: boolean,\n    height: number,\n    normalBias: number,\n    radius: number\n}\n\nexport interface RDRandomParams {\n    minDistanceScale: Vector3,\n    distanceScale: number,\n    focus: number,\n    spread: number,\n    direction: Vector3\n    normalDirection: Vector3\n}\n\nexport class RandomizedDirectionalLight extends DirectionalLight2 implements IDisposable {\n    @serialize('shadowParams')\n    private _shadowParams: RDShadowParams = {\n        enabled: true,\n        radius: 2,\n        width: 1024,\n        height: 1024,\n        bias: -0.001,\n        normalBias: 0,\n        near: 1.5,\n        far: 4,\n        frustumSize: 4,\n    }\n\n    @serialize('randomParams')\n    private _randomParams: RDRandomParams = {\n        focus: 1, // 0 to 1\n        spread: 0.01, // 0 to 4\n        distanceScale: 50, // distance from target sort of\n        minDistanceScale: new Vector3(10, 10, 10), // distance from target sort of\n        // normalDirection: new Vector3(0.01, 0.33, 0.9).normalize(),\n        normalDirection: new Vector3(0.01, 0.98, 0.01).normalize(),\n        direction: new Vector3(-.9, 0.5, -1.),\n        // direction: new Vector3(3, 2, 1).multiply(this.camera.position),\n    }\n    isRandomizedDirectionalLight = true\n\n    // Set renderer.shadowMap settings if using shadows.\n    constructor(color?: Color | string | number, intensity?: number, shadow?: Partial<RDShadowParams>, random?: Partial<RDRandomParams>) {\n        super(color, intensity)\n        this.shadowParams = shadow ?? {}\n        this.randomParams = random ?? {}\n        this.updateShadowParams = this.updateShadowParams.bind(this)\n        // this.target.removeFromParent()\n    }\n\n    /**\n     * call setter to change. or call updateShadowParams after changing\n     */\n    get shadowParams(): Partial<RDShadowParams> {\n        return this._shadowParams\n    }\n\n    set shadowParams(value: Partial<RDShadowParams>) {\n        // @ts-expect-error ignore\n        Object.keys(value).forEach(key => value[key] === undefined && delete value[key])\n        this._shadowParams = {...this._shadowParams, ...value}\n        this.updateShadowParams()\n    }\n\n\n    get randomParams(): Partial<RDRandomParams> {\n        return this._randomParams\n    }\n\n    set randomParams(value: Partial<RDRandomParams>) {\n        // @ts-expect-error ignore\n        Object.keys(value).forEach(key => value[key] === undefined && delete value[key])\n        Object.assign(this._randomParams, value)\n    }\n\n    updateShadowParams() {\n        this.castShadow = this._shadowParams.enabled\n\n        this.shadow.mapSize.x = this._shadowParams.width // default\n        this.shadow.mapSize.y = this._shadowParams.height // default\n        // this.shadow.bias = -0.001;\n        this.shadow.bias = this._shadowParams.bias\n        this.shadow.normalBias = this._shadowParams.normalBias\n        // this.shadow.normalBias = 0.0000001;\n        // this.shadow.camera.near = 20;\n        // this.shadow.camera.far = 75;\n        // this.shadow.camera.near = this._shadowParams.near;\n        // this.shadow.camera.far = this._shadowParams.far;\n        this.refreshShadowCamNearFar()\n\n        this.shadow.radius = this._shadowParams.radius\n\n        this.shadow.camera.right = this._shadowParams.frustumSize / 2\n        this.shadow.camera.left = -this._shadowParams.frustumSize / 2\n        this.shadow.camera.top = this._shadowParams.frustumSize / 2\n        this.shadow.camera.bottom = -this._shadowParams.frustumSize / 2\n\n        this.shadow.camera.updateProjectionMatrix()\n        this.matrixWorldNeedsUpdate = true\n    }\n\n    randomizePosition(seed: number, focus: number|null = null, spread: number|null = null) {\n        // todo remove dependency to rand-seed\n        const rand = new Rand(seed.toString())\n\n        const rnd = new Vector2(rand.next() * Math.PI * 2, Math.asin(rand.next() * 2 - 1))\n        let dir = new Vector3(Math.cos(rnd.x) * Math.cos(rnd.y), Math.sin(rnd.y), Math.sin(rnd.x) * Math.cos(rnd.y))\n        // const dir = vec3.random(vec3.create(), 30);\n        // const light_params = {\n        //     directionalWeight: 0.7,\n        //     randomWeight: 1.5,\n        //     sampleHemisphere: true,\n        //     direction: new Vector3(-2, 1, 2),\n        //     // direction: new Vector3(3, 2, 1).multiply(this.camera.position),\n        // }\n        // if (rand.next() < Math.pow(focus ?? this._randomParams.focus, 2)) {\n        //     dir.multiplyScalar((spread ?? this._randomParams.spread) * Math.sqrt(rand.next())).add(this._randomParams.direction);\n        // }\n\n        /**\n         * @type {string}\n         */\n        // let h = this._randomParams.hemisphere;\n        // while ((h?.length ?? 0) >= 2) { // negate direction if < or > 0\n        //     if ((dir[h[0]] * (h[1] === '+' ? -1 : 1)) < 0) dir[h[0]] *= -1;\n        //     h = h.substr(2);\n        // }\n\n        const v2 = new Vector2()\n\n        for (let kk = 0; kk < 5; kk++) {\n            v2.set(rand.next(), rand.next())\n            dir = getSample(v2, this._randomParams.normalDirection, 0.4)\n\n            if (rand.next() < Math.sqrt(focus ?? this._randomParams.focus)) {\n                v2.set(rand.next(), rand.next())\n                dir = getSample(v2, this._randomParams.direction, Math.pow((spread ?? this._randomParams.spread) / 2., 2))\n            }\n\n            const cd = dir.dot(this._randomParams.normalDirection)\n            if (cd > 0 && cd < 0.4) break\n        }\n        dir.normalize()\n\n        dir.multiplyScalar(this._randomParams.distanceScale)\n\n        // dir.x += Math.sign(dir.x) * this._randomParams.minDistanceScale.x;\n        // dir.y += Math.sign(dir.y) * this._randomParams.minDistanceScale.y;\n        // dir.z += Math.sign(dir.z) * this._randomParams.minDistanceScale.z;\n        // dir.z = 15. + 10 * dir.z / 50;\n        // vec3.mul(dir, dir, [500, 500, 500]);\n        // console.log(vec3.len(dir));\n        // vec3.add(dir, dir, [0,10,0]);\n\n        // let useY = Math.max(...dir.toArray()) !== dir.y;\n        // let up = new Vector3(!useY?1:0, useY?1:0, 0).cross(dir).normalize();\n        // console.log(dir);\n        this.position.set(0, 0, 0)\n        this.target.position.copy(dir.normalize().negate())\n        this.target.updateMatrixWorld()\n        this.refreshShadowCamNearFar()\n\n        this.updateMatrixWorld()\n\n    }\n\n    refreshShadowCamNearFar() {\n        const dist = new Vector3().subVectors(this.target.position, this.shadow.camera.position).length()\n        this.shadow.camera.near = dist - this._shadowParams.near * this._shadowParams.frustumSize / 2\n        this.shadow.camera.far = dist + this._shadowParams.far * this._shadowParams.frustumSize / 2\n    }\n\n    dispose(): void {\n        // todo;\n    }\n\n    // todo move to commons and base class in threepipe like materials\n    toJSON(meta?: SerializationMetaType, _internal = false): any {\n        // todo uncomment after ts-browser-helpers update\n        // if (!_internal) {\n        //     return ThreeSerialization.Serialize(this, meta, false)\n        // }\n        const {userData, children} = this\n        this.userData = {}\n        this.children = []\n        const data = super.toJSON(meta)\n        const copiedData = copyObject3DUserData({}, userData)\n        data.userData = Serialization.Serialize(copiedData) // no meta here, since we dont support textures etc inside lights\n        this.userData = userData\n        this.children = children\n\n        data.type = 'DirectionalLight2'\n        data.target = this.target.position.toArray()\n        // return Object.assign(data, serializeObject(this, true, meta)) // for subclasses like RandomizedDirectionalLight\n        return {\n            ...data,\n            ...ThreeSerialization.Serialize(this, meta, true), // this will serialize the properties of this class(like defined with @serialize and @serialize attribute)\n        } // for subclasses like RandomizedDirectionalLight\n // this will call toJSON again, but with baseOnly=true, that's why we set isThis to false.\n    }\n\n    // todo move to commons and base class in threepipe\n    fromJSON(data: any, meta?: SerializationMetaType, _internal = false): this | null {\n        // todo uncomment after ts-browser-helpers update\n        // if(!_internal) {\n        //     return ThreeSerialization.Deserialize(data, this, meta, false)\n        // }\n\n        if (data.type !== 'DirectionalLight2') return null // todo type\n        const target = data.target\n        const object = data.object\n        if (data.target) {\n            this.target.position.fromArray(data.target)\n            this.target.updateMatrixWorld()\n            delete data.target\n        }\n        if (data.object) {\n            delete data.object\n        }\n        ThreeSerialization.Deserialize(data, this, meta, true)\n        if (target) {\n            data.target = target\n        }\n        if (object) {\n            if (object.color !== undefined) this.color.set(object.color)\n            if (object.intensity !== undefined) this.intensity = object.intensity\n            data.object = object\n        }\n        // todo: shadow (use ObjectLoader)\n\n\n        // for this class\n        this.updateShadowParams()\n\n\n        return this\n    }\n\n    // fromJSON(data: any, meta?: any): this | null {\n    //     // if (!super.fromJSON(data, meta)) return null\n    //     this.updateShadowParams()\n    //     return this\n    // }\n\n//\n    // setDefaultPosition() {\n    //     this.position.copy(this._randomParams.direction).multiplyScalar(this._randomParams.distanceScale)\n    //     this.position.z = 15. + 10 * this.position.z / 50;\n    //     this.updateMatrixWorld()\n    // }\n}\n\n/**\n     * @param dir {Vector3}\n     * @param extent {number}\n     * @return {Vector3}\n     */\nfunction getSample(rand: Vector2, dir: Vector3, extent: number) {\n    dir = dir.clone().normalize()\n    const o1 = new Vector3(0., -dir.z, dir.y).normalize()\n    const o2 = new Vector3().crossVectors(dir, o1).normalize()\n\n    // Convert to spherical coords aligned to dir\n    const r = rand\n    r.x = r.x * 2. * Math.PI\n    r.y = 1.0 - r.y * extent\n\n    const oneminus = Math.sqrt(1.0 - r.y * r.y)\n    return o1.multiplyScalar(Math.cos(r.x) * oneminus).add(o2.multiplyScalar(Math.sin(r.x) * oneminus)).add(dir.multiplyScalar(r.y))\n}\n//\n// glsl`\n// // http://www.fractalforums.com/fragmentarium/inigo-quilez's-brute-force-global-illumination/15/\n// vec3 getSample(vec3 dir, float extent) {\n//     //TotalCompendium.pdf 34\n//\n//     // Create orthogonal vector (fails for z,y = 0)\n//     vec3 o1 = normalize(vec3(0., -dir.z, dir.y));\n//     vec3 o2 = normalize(cross(dir, o1));\n//\n//     // Convert to spherical coords aligned to dir\n//     vec2 r = getUniformRandomVec2();\n//     r.x=r.x*2.*PI;\n//     r.y=1.0-r.y*extent;\n//\n//     float oneminus = sqrt(1.0-r.y*r.y);\n//     return cos(r.x)*oneminus*o1+sin(r.x)*oneminus*o2+r.y*dir;\n// }\n//\n//\n// vec3 getSampleBiased(vec3  dir, float power) {\n//     // create orthogonal vector (fails for z,y = 0)\n//     vec3 o1 = normalize( vec3(0., -dir.z, dir.y));\n//     vec3 o2 = normalize(cross(dir, o1));\n//\n//     // Convert to spherical coords aligned to dir;\n//     vec2 r = rand(viewCoord*(float(backbufferCounter)+1.0));\n//     if (Stratify) {r*=0.1; r+= cx;}\n//     r.x=r.x*2.*PI;\n//     r.y = 1.0-r.y;\n//\n//     // This should be cosine^n weighted.\n//     // See, e.g. http://people.cs.kuleuven.be/~philip.dutre/GI/TotalCompendium.pdf\n//     // Item 36\n//     r.y=pow(r.y,1.0/(power+1.0));\n//\n//     float oneminus = sqrt(1.0-r.y*r.y);\n//     vec3 sdir = cos(r.x)*oneminus*o1+\n//         sin(r.x)*oneminus*o2+\n//         r.y*dir;\n//\n//     return sdir;\n// }\n// `\n\n","import {AnyOptions, glsl, ITexture, Shader, ShadowMaterial, uniform, WebGLRenderer} from 'threepipe'\n\n// Full screen shadow material, used for baking shadow maps.\nexport class FSShadowMaterial extends ShadowMaterial /*implements IMaterial*/ {\n    public readonly typeSlug = 'fsShadow'\n    assetType: 'material' = 'material'\n\n    private _uniforms: any = {}\n    @uniform({propKey: 'tLastThis'})\n    public lastFrameTexture: ITexture | null = null\n\n    get materialObject(): ShadowMaterial {\n        return this\n    }\n\n    onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void {\n        shader.vertexShader = shader.vertexShader.replace('#include <project_vertex>', `\n#include <project_vertex>\ngl_Position = vec4(uv*2.-1., 0, 1.); \n        `) // todo: write to uv2?\n        shader.vertexShader = shader.vertexShader.replace('void main() {', `\nvarying vec2 vUv;\nvoid main() {\n    vUv = uv;\n        `)\n        shader.fragmentShader = shader.fragmentShader.replace('void main() {', `\nvarying vec2 vUv;\nuniform sampler2D tLastThis;\nvoid main() {\n        `)\n        shader.fragmentShader = shader.fragmentShader.replace('gl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );', glsl`\nfloat shadow = getShadowMask();\n\n//shift the color by dither_shift\nshadow = clamp(shadow + mix(-1./512., 1./512., rand( gl_FragCoord.xy )), 0., 1.);\n\nfloat last = unpackRGBAToDepth(texture2D(tLastThis, vUv));\ngl_FragColor = packDepthToRGBA(mix(last, shadow, opacity));\n//if not useMovingAverage:\n//gl_FragColor = packDepthToRGBA(shadow * opacity + last);\n        `)\n        Object.assign(shader.uniforms, this._uniforms)\n        super.onBeforeCompile(shader, renderer)\n    }\n\n    customProgramCacheKey(): string {\n        return super.customProgramCacheKey()\n    }\n\n    toJSON(): any {\n        throw new Error('Method not supported for this material.')\n    }\n    fromJSON(): this | null {\n        throw new Error('Method not supported for this material.')\n    }\n\n    copyProps(): this {\n        throw new Error('Method not supported for this material.')\n    }\n\n    setDirty(options?: AnyOptions): void {\n        this.needsUpdate = true\n        this.dispatchEvent({...options, type: 'materialUpdate'}) // this sets sceneUpdate in root scene\n    }\n}\n","import {\n    BasicShadowMap,\n    BufferGeometry,\n    glsl,\n    IDisposable,\n    Layers,\n    MaterialExtension,\n    Mesh,\n    NoBlending,\n    NoColorSpace,\n    onChange,\n    PhysicalMaterial, RenderManager,\n    RGBAFormat,\n    serialize,\n    ShaderMaterial2,\n    shaderReplaceString, shaderUtils,\n    SimpleEventDispatcher,\n    Texture,\n    ThreeSerialization,\n    ThreeViewer,\n    UnsignedByteType,\n    Vector2,\n    Vector3,\n    WebGLRenderTarget,\n} from 'threepipe'\nimport {RandomizedDirectionalLight} from \"./RandomizedDirectionalLight\";\nimport {FSShadowMaterial} from \"./FSShadowMaterial\";\nimport seperableShadowBlur from './shaders/seperableShadowBlur.glsl'\n\nconst ShaderChunk = RenderManager.ShaderChunk\n\nexport class ShadowMapBaker extends SimpleEventDispatcher<'shadowBaking'|'shadowBaked'> implements IDisposable {\n    enabled = true // do not serialize // this is to disable baking for a while, toggling this does not reset the baked shadow map\n\n    get attachedMesh(): Mesh<BufferGeometry, PhysicalMaterial> | undefined {\n        return this._attachedMesh\n    }\n\n    set attachedMesh(value: Mesh<BufferGeometry, PhysicalMaterial> | undefined) {\n        if (this._attachedMesh !== value) {\n            this._attachedMesh && this.cleanupMaterial()\n            this._attachedMesh = value\n            this._attachedMesh && this._updateMaterial()\n        }\n    }\n    private _shadowMat: FSShadowMaterial\n    private _shadowBlurMat: ShaderMaterial2\n\n    get target(): WebGLRenderTarget | undefined {\n        return this._target\n    }\n\n    private _target?: WebGLRenderTarget\n\n    get light(): RandomizedDirectionalLight {\n        return this._light\n    }\n\n    @serialize('randomizedLight') private readonly _light: RandomizedDirectionalLight\n    private readonly _lightLayer = 5 // todo: get free one from the viewer.\n    private _viewer: ThreeViewer\n\n    constructor(viewer: ThreeViewer) {\n        super()\n        this._viewer = viewer\n        const light = new RandomizedDirectionalLight(0xffffff, 10, {\n            near: 1.5,\n            far: 20,\n            bias: 0.0,\n            frustumSize: 4,\n            width: 1024,\n            height: 1024,\n            enabled: true,\n            radius: 10,\n            normalBias: 0,\n        }, {\n            direction: new Vector3(0.2, 1, 0.2).normalize(),\n            spread: 0.9,\n            focus: 1.0,\n            distanceScale: 20,\n            minDistanceScale: new Vector3(10, 10, 10),\n            normalDirection: new Vector3(0, 1, 0),\n        })\n        light.shadow.camera.updateProjectionMatrix()\n        light.layers.disableAll()\n        light.layers.set(this._lightLayer)\n\n        this._light = light\n        viewer.scene.addObject(this._light, {addToRoot: true})\n\n        this._shadowMat = new FSShadowMaterial({\n            color: '#ffffff',\n            toneMapped: false,\n            depthWrite: false,\n            depthTest: false,\n            premultipliedAlpha: false,\n            opacity: 1,\n            transparent: false,\n            blending: NoBlending,\n        })\n\n        this._shadowBlurMat = new ShaderMaterial2({\n            uniforms: {\n                'colorTexture': {value: null},\n                'step': {value: 0.1},\n                'size': {value: new Vector2(0.5, 0.5)},\n                'direction': {value: new Vector2(0.5, 0.5)},\n            },\n\n            vertexShader: shaderUtils.defaultVertex,\n\n            fragmentShader: seperableShadowBlur,\n        })\n    }\n\n    dispose() {\n        // todo: dispose everything and remove light from scene.\n        this._shadowMat.dispose()\n        this._target = undefined\n        this.reset()\n    }\n\n    public cleanupMaterial() {\n        this._updateMaterial(true)\n    }\n\n    private _frameNumber = 0\n\n    @onChange(ShadowMapBaker.prototype.reset)\n    @serialize() maxFrameNumber = 400\n\n    @onChange(ShadowMapBaker.prototype.reset)\n    @serialize() smoothShadow = false\n\n    @serialize()\n    @onChange(ShadowMapBaker.prototype.reset)\n    shadowMapType = BasicShadowMap // this is fine since we are randomizing\n\n    private _attachedMesh: Mesh<BufferGeometry, PhysicalMaterial> | undefined\n\n    @onChange(ShadowMapBaker.prototype._groundMapModeChanged)\n    @serialize() groundMapMode: 'aoMap' | 'map' | 'alphaMap' = 'aoMap'\n\n    @serialize()\n    @onChange(ShadowMapBaker.prototype._alphaVignetteChanged)\n    alphaVignette = true // only works for transparent and transmissive materials.\n\n    @serialize()\n    @onChange(ShadowMapBaker.prototype._alphaVignetteChanged)\n    alphaVignetteAxis = 'xy' // x or y or xy.\n\n    private _groundMapModeChanged() {\n        if (this._attachedMesh) {\n            this.cleanupMaterial()\n            this._updateMaterial()\n            if (this.groundMapMode === 'alphaMap') this._attachedMesh.material.transparent = true\n            else this._attachedMesh.material.transparent = false\n        }\n        this.reset()\n    }\n    private _alphaVignetteChanged() {\n        this.materialExtension?.setDirty?.()\n        this._viewer?.setDirty()\n    }\n\n    fromJSON(data: any, meta?: any, _internal: boolean = false): this {\n        if(!_internal) {\n            return ThreeSerialization.Deserialize(data, this, meta, false)\n        }else {\n            ThreeSerialization.Deserialize(data, this, meta, true)\n            this.reset()\n        }\n        return this\n    }\n\n    reset(): void {\n        // this._updateMaterial()\n        this._frameNumber = 0\n    }\n\n    get frameNumber() {\n        return this._frameNumber\n    }\n\n    shadowAutoUpdate = true\n\n    private _bakeCounter = 0\n\n    @serialize() maxBakeCount = Infinity\n\n    autoUpdateShadow(): boolean {\n        if (this.shadowAutoUpdate) {\n            if (this._bakeCounter >= this.maxBakeCount) return false\n            if (!this.updateShadow()) return false\n            if (this._frameNumber === this.maxFrameNumber) {\n                this.dispatchEvent({type: 'shadowBaked', bakeCount: ++this._bakeCounter})\n            } else if (this._frameNumber > 0 && this._frameNumber < this.maxFrameNumber) {\n                this.dispatchEvent({type: 'shadowBaking', progress: this._frameNumber / this.maxFrameNumber, bakeCount: this._bakeCounter})\n            }\n            return true\n        }\n        return false\n    }\n\n    updateShadow(): boolean {\n        if (!this.enabled) return false\n        const mesh = this._attachedMesh\n        if (!mesh) return false\n        if (++this._frameNumber > this.maxFrameNumber) return false\n\n        const customSize = 1024\n        if (!this._target) {\n            this._target = this._viewer.renderManager.createTarget({ // todo: dispose somewhere\n                // type: HalfFloatType,\n                type: UnsignedByteType,\n                depthBuffer: false,\n                size: customSize ? new Vector2(customSize, customSize) : undefined,\n                sizeMultiplier: customSize ? undefined : 1,\n                // encoding: sRGBEncoding,\n                colorSpace: NoColorSpace,\n                format: RGBAFormat,\n            }) as WebGLRenderTarget\n            // this._target.texture.userData.serializableRenderTarget = true // not working properly and exported image size is high, see BaseRenderer\n        }\n\n        if (this._frameNumber < 3)\n            this._light.randomizePosition(0, 1, 0)\n        else\n            this._light.randomizePosition(this._frameNumber)\n        mesh.castShadow = false\n        const renderer = this._viewer.renderManager.renderer\n        const shadowMap = renderer.shadowMap\n\n        const shadowMapType = shadowMap.type\n        const shadowMapNeedsUpdate = shadowMap.needsUpdate\n        const shadowMapAutoUpdate = shadowMap.autoUpdate\n        shadowMap.type = this.shadowMapType\n        shadowMap.needsUpdate = true\n        shadowMap.autoUpdate = false\n\n        const scene = this._viewer.scene\n        // disable all other lights\n        const sceneLightLayer = new Layers()\n        sceneLightLayer.disableAll()\n        scene.traverse((o: any) => {\n            if (o.isLight && o !== this._light) {\n                o.userData.__gp_layers = o.layers\n                o.layers = sceneLightLayer\n            }\n        })\n        const cam = scene.mainCamera\n        if ((cam.layers.mask & 1 << this._lightLayer) !== 0) throw 'Camera can render pseudo directional light, check layers'\n\n        cam.layers.enable(this._lightLayer)\n        mesh.layers.disable(this._lightLayer)\n\n        // scene.modelObject.traverse((o: any)=>{\n        //     if (o.assetType === 'widget') {\n        //         o.traverse((o1: any)=> {\n        //             o1.castShadow = false\n        //         })\n        //     }\n        // })\n\n        renderer.renderWithModes({\n            shadowMapRender:true,\n            backgroundRender:false,\n            sceneRender:false,\n        }, ()=> renderer.render(scene, scene.mainCamera))\n        // scene.modelObject.traverse((o: any)=>{\n        //     if (o.assetType === 'widget') {\n        //         o.castShadow = false\n        //     }\n        // })\n\n        cam.layers.disable(this._lightLayer)\n\n        // Only render light layer\n        const camLayers = cam.layers.mask\n        cam.layers.set(this._lightLayer)\n        mesh.layers.enable(this._lightLayer)\n\n        const lastThisTarget = (customSize ? this._viewer.renderManager.getTempTarget({\n            type: UnsignedByteType,\n            depthBuffer: false,\n            size: new Vector2(customSize, customSize),\n            // encoding: sRGBEncoding,\n            colorSpace: NoColorSpace,\n            format: RGBAFormat,\n        }) : this._viewer.renderManager.composerTarget) as WebGLRenderTarget\n\n        const texture = lastThisTarget.texture as Texture\n        const lastThisTargetColorSpace = texture.colorSpace\n        texture.colorSpace = NoColorSpace\n\n        this._viewer.renderManager.blit(lastThisTarget, {clear: true, source: this._target.texture})\n\n        {\n\n            // const currentEnvironment = scene.modelObject.environment\n            // const currentBackground = scene.modelObject.background\n            const currentMaterial = mesh.material\n            const currentFrustumCulled = mesh.frustumCulled\n            const currentRt = renderer.getRenderTarget()\n            const activeCubeFace = renderer.getActiveCubeFace()\n            const activeMipLevel = renderer.getActiveMipmapLevel()\n            // scene.modelObject.background = null\n            // scene.modelObject.environment = null\n            mesh.material = this._shadowMat as any\n            mesh.frustumCulled = false\n            renderer.setRenderTarget(this._target)\n\n            const useMovingAverage = false\n            this._shadowMat.opacity = useMovingAverage ? 1. / this.maxFrameNumber : Math.max(1. / this.maxFrameNumber, 1. / this._frameNumber)\n            this._shadowMat.lastFrameTexture = lastThisTarget.texture\n            this._shadowMat.needsUpdate = true\n\n            renderer.renderWithModes({\n                shadowMapRender:false,\n                backgroundRender:false,\n                opaqueRender:true,\n                transparentRender:false,\n                transmissionRender:false,\n            }, ()=> renderer.render(scene, scene.mainCamera))\n\n            renderer.setRenderTarget(currentRt, activeCubeFace, activeMipLevel)\n            mesh.frustumCulled = currentFrustumCulled\n            mesh.material = currentMaterial\n            // scene.modelObject.environment = currentEnvironment\n            // scene.modelObject.background = currentBackground\n\n            if (this.smoothShadow)\n                this._applySmoothFilter(this._target, lastThisTarget as WebGLRenderTarget)\n        }\n\n        lastThisTarget.texture.colorSpace = lastThisTargetColorSpace\n        if (customSize) {\n            this._viewer.renderManager.releaseTempTarget(lastThisTarget)\n        }\n\n        mesh.layers.disable(this._lightLayer)\n        cam.layers.mask = camLayers\n\n        // enable all other lights\n        scene.modelObject.traverse((o: any) => {\n            if (o.isLight && o !== this._light.lightObject) {\n                o.layers = o.userData.__gp_layers\n                delete o.userData.__gp_layers\n            }\n        })\n\n        shadowMap.type = shadowMapType\n        shadowMap.needsUpdate = shadowMapNeedsUpdate\n        shadowMap.autoUpdate = shadowMapAutoUpdate\n\n        mesh.castShadow = true\n\n        if (this._frameNumber < 3 || this._frameNumber > Math.min(100, this.maxFrameNumber)\n            && this._frameNumber % 4 === 0\n        ) {\n            // if (this._attachedMesh)\n            //     this.materialExtension.extraUniforms!.transitionOpacity.value = Math.min(1, 4. * this._frameNumber / this.maxFrameNumber)\n\n            this._updateMaterial()\n            // this._viewer.setDirty()\n            // mesh.dispatchEvent({type: 'materialUpdate'})\n            mesh.material.setDirty()\n        }\n\n        return true\n    }\n\n    private _updateMaterial(isNull = false) {\n        if (!this._attachedMesh) return\n        if (isNull) {\n            if (this._attachedMesh.material.alphaMap === this._target?.texture) {\n                this._attachedMesh.material.alphaMap = null\n            }\n            if (this._attachedMesh.material.aoMap === this._target?.texture) {\n                this._attachedMesh.material.aoMap = null\n            }\n            if (this._attachedMesh.material.map === this._target?.texture) {\n                this._attachedMesh.material.map = null\n            }\n\n        } else if (this._target) {\n            if (this.groundMapMode === 'alphaMap') {\n                this._attachedMesh.material.alphaMap = this._target.texture\n            }\n            if (this.groundMapMode === 'aoMap') {\n                this._attachedMesh.material.aoMap = this._target.texture\n            }\n            if (this.groundMapMode === 'map') {\n                this._attachedMesh.material.map = this._target.texture\n            }\n        }\n\n        // needed in DepthNormalPass when rendering to depth\n        if (this._attachedMesh.material) {\n            this._attachedMesh.material.userData.ALPHA_I_RGBA_PACKING = !isNull && this.groundMapMode === 'alphaMap'\n            this._attachedMesh.material.alphaTest = !isNull && this.groundMapMode === 'alphaMap' ? 0.01 : 0\n\n            this._attachedMesh.material.needsUpdate = true\n        }\n        // console.log(this._attachedMesh.material, target)\n    }\n\n    private _applySmoothFilter(shadowReadBuffer: WebGLRenderTarget, shadowWriteBuffer: WebGLRenderTarget) {\n        this._shadowBlurMat.uniforms.colorTexture.value = shadowReadBuffer.texture\n        this._shadowBlurMat.uniforms.direction.value.set(1, 0)\n        this._shadowBlurMat.uniforms.size.value.set(shadowReadBuffer.width, shadowReadBuffer.height)\n        this._viewer.renderManager.blit(shadowWriteBuffer, {material: this._shadowBlurMat})\n\n        this._shadowBlurMat.uniforms.colorTexture.value = shadowWriteBuffer.texture\n        this._shadowBlurMat.uniforms.direction.value.set(0, 1)\n        this._shadowBlurMat.uniforms.size.value.set(shadowWriteBuffer.width, shadowWriteBuffer.height)\n        this._viewer.renderManager.blit(shadowReadBuffer, {material: this._shadowBlurMat})\n    }\n\n    readonly materialExtension: MaterialExtension = {\n\n        parsFragmentSnippet: (_renderer, _material)=> {\n            return glsl`\n            uniform float transitionOpacity;\n            `\n        },\n\n        extraUniforms: {\n            transitionOpacity: {\n                value: 1,\n            },\n        },\n\n        shaderExtender: (shader, _material, renderer) => {\n            if (this.groundMapMode === 'aoMap') {\n\n                shader.fragmentShader = shaderReplaceString(shader.fragmentShader,\n                    '#include <aomap_fragment>',\n                    shaderReplaceString(ShaderChunk.aomap_fragment,\n                        'float ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;',\n                        'float ambientOcclusion = ( mix(1., unpackRGBAToDepth(texture2D( aoMap, vAoMapUv ) ), transitionOpacity) - 1.0) * aoMapIntensity + 1.0;'\n                    ))\n                // material.materialObject.transparent = false\n\n            } else if (this.groundMapMode === 'map') {\n\n                shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <map_fragment>',\n                    shaderReplaceString(ShaderChunk.map_fragment,\n                        'diffuseColor *= sampledDiffuseColor',\n                        'float groundShadow = mix(1., unpackRGBAToDepth(sampledDiffuseColor), transitionOpacity); diffuseColor.rgb *= groundShadow; diffuseColor.a *= max(0., 1.-groundShadow) * transitionOpacity;'\n                    ))\n                // material.materialObject.transparent = false\n\n            } else if (this.groundMapMode === 'alphaMap') {\n\n                shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <alphamap_fragment>',\n                    shaderReplaceString(ShaderChunk.alphamap_fragment,\n                        'texture2D( alphaMap, vAlphaMapUv ).g',\n                        '1. - unpackRGBAToDepth( texture2D( alphaMap, vAlphaMapUv ) )',\n                        {replaceAll: true},\n                    ))\n                // material.materialObject.transparent = true\n\n            }\n\n            shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <opaque_fragment>',\n                glsl`#include <opaque_fragment>\n                #ifndef OPAQUE\n                    #ifdef USE_AOMAP\n                        #if NUM_DIR_LIGHT_SHADOWS > 0\n                            // TODO find a better solution\n                            float alphaMod = length(reflectedLight.directDiffuse)*4./float(NUM_DIR_LIGHT_SHADOWS);\n                        #else\n                            float alphaMod = 1.;\n                        #endif\n                        float t1 = 1. - ambientOcclusion;\n                        float t2 = max(1. - alphaMod, 0.);\n                        float t = t1 + t2;\n                        gl_FragColor.a *= max(t, 0.);\n                    #endif\n                #endif\n            `)\n\n            if (this.alphaVignette && renderer.capabilities.isWebGL2) {\n                (shader as any).defines.USE_UV = ''\n                shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <opaque_fragment>',\n                    glsl`#include <opaque_fragment>\n                    #ifndef OPAQUE\n                    float weight = 0.;\n                    #ifdef USE_UV // why are we checking for this? this is always supposed to be true\n                    weight = 2.*abs(length(0.5 - vUv.${this.alphaVignetteAxis}));\n                    #endif\n                    #if defined(USE_LIGHTMAP) || defined(USE_AOMAP)\n                    weight = 2.*abs(length(0.5 - vAoMapUv.${this.alphaVignetteAxis}));\n                    #endif\n                    weight = min(1., max(0., weight))-0.5;\n                    weight = min(1., max(0., 1.0-2.*weight));\n                    weight = pow(weight, 1.5);\n                    gl_FragColor.a *= weight;\n                    //gl_FragColor.rgb /= max(0.01, weight);\n                    gl_FragColor = saturate(gl_FragColor);\n                    //gl_FragColor.a = 0.5;\n                    #endif\n                    `)\n            }\n        },\n        computeCacheKey: ()=>{\n            return this.groundMapMode + '.' + this.alphaVignette + '.' + this.alphaVignetteAxis\n        },\n        onObjectRender: (_object, material) => {\n            if (material.userData.gMapMode !== this.groundMapMode) {\n                material.userData.gMapMode = this.groundMapMode\n                material.needsUpdate = true\n            }\n        },\n        isCompatible: material => {\n            return (material).isPhysicalMaterial\n        },\n    }\n\n    // render(mesh: Mesh<BufferGeometry, PhysicalMaterial) {\n    //     this._viewer.renderManager.renderModel(mesh, this._viewer.scene.activeCamera!)\n    // }\n}\n\n","#include <packing>\n\nuniform sampler2D colorTexture;\nuniform vec2 size;\nuniform vec2 direction;\nuniform float step;\n\nvarying vec2 vUv;\n\nvoid main() {\n\n    float sum = 0.0;\n    vec2 uvDelta = step * direction / size;\n\n    sum += unpackRGBAToDepth(texture2D(colorTexture, vUv - 1. * uvDelta)) * 0.3333;\n    sum += unpackRGBAToDepth(texture2D(colorTexture, vec2(vUv.x, vUv.y))) * 0.3333;\n    sum += unpackRGBAToDepth(texture2D(colorTexture, vUv + 1. * uvDelta)) * 0.3333;\n\n    gl_FragColor = packDepthToRGBA(sum);\n\n}","import {\n    BaseGroundPlugin,\n    BasicShadowMap,\n    bindToValue,\n    Event,\n    generateUiConfig,\n    IGeometry,\n    IMaterial,\n    IScene,\n    ISceneEventMap,\n    LinearFilter,\n    LinearMipmapLinearFilter,\n    Mesh2,\n    NoColorSpace,\n    onChange,\n    PCFShadowMap,\n    PCFSoftShadowMap,\n    PlaneGeometry,\n    RGBAFormat,\n    serialize,\n    ThreeViewer,\n    UiObjectConfig,\n    uiToggle,\n    UnsignedByteType,\n    VSMShadowMap,\n} from 'threepipe'\nimport {SSReflectionPlugin} from '../postprocessing/SSReflectionPlugin'\nimport {Reflector2} from '../../utils/Reflector2'\nimport {ShadowMapBaker} from '../../utils/ShadowMapBaker'\n\nexport class AdvancedGroundPlugin extends BaseGroundPlugin {\n    public static readonly PluginType: string = 'AdvancedGroundPlugin'\n\n    get shadowBaker(): ShadowMapBaker | undefined {\n        return this._shadowBaker\n    }\n\n    @onChange(AdvancedGroundPlugin.prototype._refresh3)\n    @uiToggle('Baked Shadows') @serialize() bakedShadows = true\n    @onChange(AdvancedGroundPlugin.prototype._refresh3)\n    @uiToggle('Planar Reflections') @serialize() groundReflection = false\n    @onChange(AdvancedGroundPlugin.prototype._refresh3)\n    @uiToggle('Physical Reflections') @serialize() physicalReflections = false\n    @onChange(AdvancedGroundPlugin.prototype._refresh3)\n    @uiToggle('Auto Shadow Frustum Size') @serialize() autoFrustumSize = true\n\n    // because of inheritance breaks onChange\n    private _refresh3(): void {\n        this.refresh()\n    }\n\n    @serialize('shadowBaker')\n    private _shadowBaker?: ShadowMapBaker\n    // private _showDebug: boolean\n\n    /**\n     * autoBakeShadows - when true, shadows are baked automatically on scene update(whenever any object in the scene changes), set it to `false` to trigger baking manually with {@see bakeShadows()}\n     */\n    autoBakeShadows = true\n\n    /**\n     * bake shadows manually, to be used with {@see autoBakeShadows} set to false\n     */\n    bakeShadows() {\n        this._shadowBaker?.reset()\n    }\n\n    constructor() {\n        super()\n        this._onSceneUpdate = this._onSceneUpdate.bind(this)\n        const generatedUi = generateUiConfig(this)\n        const matUI = generatedUi.find(f=>typeof f === 'function')!\n        this.uiConfig = {\n            label: 'Ground',\n            type: 'folder',\n            children: [\n                ...generatedUi.filter(f => f !== matUI),\n                ...this._extraUiConfig(),\n                matUI,\n            ],\n        }\n    }\n\n    protected _createMesh(mesh?: Mesh2<IGeometry & PlaneGeometry, IMaterial>) {\n        if (mesh) throw new Error('AdvancedGroundPlugin - mesh should not be provided')\n        const reflector = new Reflector2<IGeometry&PlaneGeometry>(this._geometry, ()=>this._viewer?.renderManager.createTarget({\n            // type: HalfFloatType,\n            type: UnsignedByteType,\n            format: RGBAFormat,\n            colorSpace: NoColorSpace, // todo: we can do rgbm if only opaque objects will be reflected\n            size: {width: 1024, height: 1024},\n            generateMipmaps: true,\n            depthBuffer: true,\n            minFilter: LinearMipmapLinearFilter,\n            magFilter: LinearFilter,\n            // isAntialiased: this._viewer.isAntialiased,\n        })!, 0, this._createMaterial())\n        const superOnBeforeRender = reflector.onBeforeRender\n\n        // todo why is this required?\n        reflector.onBeforeRender = (...params) => {\n            let ssr = this._viewer?.getPluginByType<SSReflectionPlugin>('SSReflectionPlugin')\n            if (ssr && ssr.isDisabled()) ssr = undefined\n            if (ssr) ssr.disable(reflector.uuid, false) // todo: do we need to disable ssao also?\n\n            // todo  ssbevel\n            // let ssbevel = this._viewer?.getPluginByType<SSBevelPlugin>('SSBevelPlugin')?.pass?.passObject\n            // if (ssbevel && !ssbevel.enabled) ssbevel = undefined\n            // if (ssbevel) ssbevel.enabled = false\n\n            superOnBeforeRender(...params)\n\n            if (ssr) ssr.enable(reflector.uuid, false)\n            // if (ssbevel) ssbevel.enabled = true // todo ssbevel\n        }\n        return reflector\n    }\n\n    declare _mesh: Reflector2<IGeometry&PlaneGeometry>\n\n    onAdded(viewer: ThreeViewer) {\n        super.onAdded(viewer)\n    }\n\n    protected _postFrame() {\n        super._postFrame()\n        if (!this._viewer) return\n        if (!this.enabled) return\n        if (this._shadowBaker && this.bakedShadows) {\n            this._shadowBaker.autoUpdateShadow()\n        }\n\n    }\n    protected _preRender() {\n        super._preRender()\n        if (!this._viewer) return\n        this._mesh.reflectionTargetNeedsUpdate = this._viewer.renderManager.frameCount < 1\n    }\n\n    onRemove(viewer: ThreeViewer) {\n        // todo\n        return super.onRemove(viewer)\n    }\n\n    protected _removeMaterial() {\n        if (!this._material) return\n        if (this._shadowBaker && (this._material as any).groundMatExtension) {\n            this._material.unregisterMaterialExtensions?.([this._shadowBaker.materialExtension])\n            delete (this._material as any).groundMatExtension\n        }\n        if ((this._material as any).reflectorMatExtension) {\n            const ext = this._mesh.materialExtension\n            if (!ext) this._viewer?.console.warn('AdavancedGroundPlugin: unable to find the extension to unregister')\n            this._material.unregisterMaterialExtensions?.([ext])\n            delete (this._material as any).reflectorMatExtension\n        }\n        // todo: remove map or render target thats assigned\n\n        super._removeMaterial()\n    }\n\n    protected _onSceneUpdate(event: ISceneEventMap['addSceneObject' | 'sceneUpdate'] & Event<'addSceneObject' | 'sceneUpdate', IScene>) {\n        super._onSceneUpdate(event)\n        // Skip widget/widgetRoot changes (e.g. selection widgets being added/removed)\n        if (event?.object?.assetType === 'widget' || event?.object?.userData?.isWidgetRoot) return\n        if (event.geometryChanged === false) return\n        this.autoResetShadows()\n    }\n\n    autoResetShadows = () => {\n        if (this.autoBakeShadows) this._shadowBaker?.reset()\n    }\n\n    public refresh(): void {\n        if (!this._viewer) return\n        if (!this.isDisabled()) {\n            if (this.bakedShadows && !this._shadowBaker) {\n                this._shadowBaker = new ShadowMapBaker(this._viewer)\n                this._shadowBaker.attachedMesh = this._mesh\n            } else if (!this.bakedShadows && this._shadowBaker) {\n                this._shadowBaker.reset()\n                this._shadowBaker.cleanupMaterial()\n            }\n            const ref = this._mesh\n            if (ref.isReflector2) {\n                ref.enabled = this.groundReflection\n                ref.reflectorModePhysical = this.physicalReflections\n            }\n        }\n        super.refresh()\n        // this._viewer.setDirty(this)\n    }\n\n    protected _refreshTransform() {\n        if (!super._refreshTransform()) return false\n        if (this.autoFrustumSize) {\n            const baker = this.shadowBaker\n            if (baker) {\n                const fs = this.size / 2\n                if (fs !== baker.light.shadowParams.frustumSize) {\n                    baker.light.shadowParams.frustumSize = fs\n                    baker.light.updateShadowParams()\n                    baker.reset()\n                }\n                // ground.bakeShadows()\n            }\n        }\n        return true\n    }\n\n    // see BaseGroundPlugin\n    fromJSON(data: any, meta?: any): this | null {\n        if (!super.fromJSON(data, meta)) return null\n        if (data.autoFrustumSize === undefined) this.autoFrustumSize = false // for files which were saved before this option was added.\n        return this\n    }\n\n    protected _refreshMaterial() {\n        if (!this._viewer) return false\n        super._refreshMaterial()\n        if (!this._material) return\n\n        if (this.groundReflection && this._mesh.isReflector2 && !(this._material as any).reflectorMatExtension) {\n            const ext = this._mesh.materialExtension\n            ext.updaters = [this._viewer.scene, this._viewer.renderManager]\n            this._material.registerMaterialExtensions?.([ext])\n            ;(this._material as any).reflectorMatExtension = true\n        }\n        if (this.bakedShadows && this._shadowBaker && !(this._material as any).groundMatExtension) {\n            this._material.registerMaterialExtensions?.([this._shadowBaker.materialExtension])\n            ;(this._material as any).groundMatExtension = true\n        }\n\n        this._material.userData.ssreflDisabled = this.groundReflection\n        this._material.userData.ssreflNonPhysical = !this.physicalReflections\n        this._material.userData.ssaoDisabled = true\n        this._material.userData.sscsDisabled = true\n        this._viewer.setDirty(this)\n    }\n\n    uiConfig: UiObjectConfig\n    protected _extraUiConfig(): (UiObjectConfig | (() => UiObjectConfig|UiObjectConfig[]))[] {\n        return [\n            {\n                label: 'Shadow Frames',\n                type: 'input',\n                hidden: ()=> !this._shadowBaker,\n                stepSize: 1,\n                bounds: [1, 1000],\n                property: ()=>[this._shadowBaker, 'maxFrameNumber'],\n            },\n            {\n                label: 'Alpha Vignette',\n                type: 'checkbox',\n                hidden: ()=> !this._material || (this._material.transmission || 0) < 0.0001 && !this._material.transparent,\n                property: ()=>[this._shadowBaker, 'alphaVignette'],\n                limitedUi: true,\n                onChange: ()=>this.uiConfig?.uiRefresh?.(true, 'postFrame'),\n            },\n            {\n                label: 'Alpha Vignette Axis',\n                type: 'dropdown',\n                hidden: ()=> !this._shadowBaker?.alphaVignette || !this._material || (this._material.transmission || 0) < 0.0001 && !this._material.transparent,\n                property: ()=>[this._shadowBaker, 'alphaVignetteAxis'],\n                children: ['x', 'y', 'xy'].map(v => ({label: v, value: v})),\n                limitedUi: true,\n            },\n            {\n                label: 'Shadow type',\n                type: 'dropdown',\n                hidden: ()=> !this._shadowBaker,\n                property: ()=>[this._shadowBaker, 'groundMapMode'],\n                children: [\n                    {label: 'aoMap'},\n                    {label: 'map'},\n                    {label: 'alphaMap'},\n                ],\n                limitedUi: true,\n            },\n            {\n                label: 'Smooth Shadow',\n                type: 'checkbox',\n                property: ()=>[this._shadowBaker, 'smoothShadow'],\n            },\n            {\n                label: 'Baked shadow type',\n                type: 'dropdown',\n                children: [['Basic', BasicShadowMap], ['PCF', PCFShadowMap], ['PCFSoft', PCFSoftShadowMap], ['VSM', VSMShadowMap]].map((v) => ({label: v[0].toString(), value: v[1]})),\n                property: ()=>[this._shadowBaker, 'shadowMapType'],\n            },\n            {\n                type: 'folder',\n                label: 'Randomized Light',\n                hidden: ()=> !this._shadowBaker,\n                limitedUi: true,\n                children: [\n                    {\n                        type: 'color',\n                        label: 'Color',\n                        property: ()=>[this._shadowBaker?.light, 'color'],\n                    },\n                    // {\n                    //     type: 'slider',\n                    //     label: 'Intensity',\n                    //     bounds: [0, 100],\n                    //     property: ()=>[this._shadowBaker?.light, 'intensity'],\n                    // },\n                    // {\n                    //     type: 'checkbox',\n                    //     label: 'Shadow Enabled',\n                    //     property: ()=>[this._shadowBaker?.light?.shadowParams, 'enabled'],\n                    //     onChange: [this._shadowBaker?.light?.updateShadowParams, this.autoResetShadows],\n                    // },\n                    {\n                        type: 'slider',\n                        bounds: [0.0, 1],\n                        property: ()=>[this._shadowBaker?.light?.randomParams, 'focus'],\n                        onChange: this.autoResetShadows,\n                    },\n                    {\n                        type: 'slider',\n                        bounds: [0.0, 1],\n                        property: ()=>[this._shadowBaker?.light?.randomParams, 'spread'],\n                        onChange: this.autoResetShadows,\n                        limitedUi: true,\n                    },\n                    {\n                        type: 'slider',\n                        bounds: [0.01, 60],\n                        property: ()=>[this._shadowBaker?.light?.randomParams, 'distanceScale'],\n                        onChange: [this._shadowBaker?.light?.updateShadowParams, this.autoResetShadows],\n                    },\n                    {\n                        type: 'vec3',\n                        bounds: [-1, 1],\n                        property: ()=>[this._shadowBaker?.light?.randomParams, 'direction'],\n                        onChange: this.autoResetShadows,\n                        limitedUi: true,\n                    },\n                    {\n                        type: 'vec3',\n                        bounds: [-1, 1],\n                        property: ()=>[this._shadowBaker?.light?.randomParams, 'normalDirection'],\n                        onChange: this.autoResetShadows,\n                        limitedUi: true,\n                    },\n                    {\n                        type: 'slider',\n                        bounds: [0.01, 10],\n                        property: ()=>[this._shadowBaker?.light?.shadowParams, 'radius'],\n                        onChange: [this._shadowBaker?.light?.updateShadowParams, this.autoResetShadows],\n                    },\n                    {\n                        type: 'input',\n                        property: ()=>[this._shadowBaker?.light?.shadowParams, 'frustumSize'],\n                        hidden: ()=> this.autoFrustumSize,\n                        onChange: [this._shadowBaker?.light?.updateShadowParams, this.autoResetShadows],\n                    },\n                    {\n                        type: 'slider',\n                        bounds: [-0.1, 0.1],\n                        property: ()=>[this._shadowBaker?.light?.shadowParams, 'bias'],\n                        onChange: [this._shadowBaker?.light?.updateShadowParams, this.autoResetShadows],\n                    },\n                ],\n            },\n        ]\n    }\n\n    @bindToValue({key: 'groundReflection'})\n        planarReflections: boolean\n}\n\n/**\n * @deprecated - use {@link AdvancedGroundPlugin} instead\n */\nexport const GroundPlugin = AdvancedGroundPlugin\n","import {\n    AViewerPluginSync,\n    ISceneEventMap,\n    Object3D,\n    onChange, ProgressivePlugin,\n    serialize,\n    ThreeViewer,\n    uiButton,\n    uiDropdown,\n    uiFolderContainer,\n    uiInput,\n    uiSlider,\n    uiToggle\n} from \"threepipe\"\n\n@uiFolderContainer('Watch Hands Time')\nexport class WatchHandsPlugin extends AViewerPluginSync {\n    static readonly PluginType = 'WatchHandsPlugin'\n\n    @uiToggle()\n    @serialize()\n    enabled = true\n\n    dependencies = []\n\n    @uiDropdown(undefined, ['x', 'y', 'z'].map(label=>({label})))\n    @serialize()\n    axis: 'x'|'y'|'z' = 'y'\n\n    @uiToggle()\n    @serialize()\n    invertAxis = false\n\n    @uiToggle()\n    @serialize()\n    analog = true\n\n    @uiSlider(undefined, [0, 12], 0.001)\n    @serialize()\n    hourOffset = 0\n\n    @uiSlider(undefined, [0, 60], 0.001)\n    @serialize()\n    minuteOffset = 0\n\n    @uiSlider(undefined, [0, 60], 0.001)\n    @serialize()\n    secondOffset = 0\n\n    @uiInput()\n    @serialize()\n    hour = '.*hour.*'\n    @uiInput()\n    @serialize()\n    minute = '.*minute.*'\n    @uiInput()\n    @serialize()\n    second = '.*second.*'\n\n    @uiToggle()\n    @onChange('refresh')\n    @serialize()\n    regex = true\n\n    hands: {\n        type: 'hour' | 'minute' | 'second'\n        object: Object3D\n    }[] = []\n\n    onAdded(viewer: ThreeViewer): void {\n        super.onAdded(viewer)\n        viewer.scene.addEventListener('addSceneObject', this._addSceneObject)\n        viewer.addEventListener('preFrame', this._preFrame)\n    }\n    onRemove(viewer: ThreeViewer): void {\n        viewer.scene.removeEventListener('addSceneObject', this._addSceneObject)\n        viewer.removeEventListener('preFrame', this._preFrame)\n        super.onRemove(viewer)\n    }\n\n    private _lastEnabled = true\n    private _preFrame = () => {\n        if (!this.enabled) {\n            if (this._lastEnabled) {\n                this._lastEnabled = false\n                if (!this.hands.length) return\n                for (const h of this.hands) {\n                    h.object.rotation.fromArray(h.object.userData.initRotation)\n                    h.object.updateMatrixWorld()\n                }\n                this._viewer?.renderManager.resetShadows()\n                this._viewer?.setDirty()\n            }\n            return\n        }\n        this._lastEnabled = true\n        if (!this.hands.length) return\n\n        const d = this._viewer?.getPlugin<ProgressivePlugin>('ProgressivePlugin')?.postFrameConvergedRecordingDelta()\n        // if (d && d > 0) delta = d\n        if (d === 0) return // not converged yet.\n        // if d < 0: not recording, do nothing\n\n        // viewer.addEventListener('preFrame', () => {\n\n        // hand_hour - y 0-2*PI\n        // hand_minute - y 0-2*PI\n        // hand_second - y 3*PI-PI\n        const time = new Date()\n        const invert = this.invertAxis ? -1 : 1\n        const secondHandRotation = invert * (time.getSeconds() + (this.analog ? time.getMilliseconds() / 1000 : 0) - this.secondOffset) * (Math.PI * 2) / 60\n        const minuteHandRotation = invert * (time.getMinutes() - this.minuteOffset) * (Math.PI * 2) / 60 + secondHandRotation / 60\n        const hourHandRotation = invert * (time.getHours() - this.hourOffset) * (Math.PI * 2) / 12 + minuteHandRotation / 12\n\n        if (this.hands.find(h=>h.type === 'second' && Math.abs(secondHandRotation - h.object.rotation[this.axis]) > 0.001)) {\n            for (const hand of this.hands) {\n                if (hand.type === 'second') {\n                    hand.object.rotation[this.axis] = secondHandRotation\n                }\n                if (hand.type === 'minute') {\n                    hand.object.rotation[this.axis] = minuteHandRotation\n                }\n                if (hand.type === 'hour') {\n                    hand.object.rotation[this.axis] = hourHandRotation\n                }\n            }\n            this._viewer?.renderManager.resetShadows()\n            this._viewer?.setDirty()\n        }\n        // })\n    }\n\n    private _addSceneObject = async(e: ISceneEventMap['addSceneObject']): Promise<void> => {\n        if (!e.object) return\n        this.refresh()\n    }\n\n    @uiButton()\n    refresh() {\n        this.hands = []\n        this._viewer?.scene.modelRoot.traverse(o=>{\n            let isChild = false\n            o.traverseAncestors(oa=>{\n                if (isChild) return\n                if (this.hands.find(h=>h.object === oa)) isChild = true\n            })\n            if (isChild) return\n            if (o.name.match(this.regex ? new RegExp(this.hour) : this.hour)) {\n                if (!o.userData.initRotation) o.userData.initRotation = o.rotation.toArray()\n                this.hands.push({type: 'hour', object: o})\n            }\n            if (o.name.match(this.regex ? new RegExp(this.minute) : this.minute)) {\n                if (!o.userData.initRotation) o.userData.initRotation = o.rotation.toArray()\n                this.hands.push({type: 'minute', object: o})\n            }\n            if (o.name.match(this.regex ? new RegExp(this.second) : this.second)) {\n                if (!o.userData.initRotation) o.userData.initRotation = o.rotation.toArray()\n                this.hands.push({type: 'second', object: o})\n            }\n        })\n    }\n}\n","import {VelocityBufferPlugin} from './buffer/VelocityBufferPlugin'\nimport {BloomPlugin} from './postprocessing/BloomPlugin'\nimport {DepthOfFieldPlugin} from './postprocessing/DepthOfFieldPlugin'\nimport {SSContactShadowsPlugin} from './postprocessing/SSContactShadowsPlugin'\nimport {SSReflectionPlugin} from './postprocessing/SSReflectionPlugin'\nimport {TemporalAAPlugin} from './postprocessing/TemporalAAPlugin'\nimport {OutlinePlugin} from \"./postprocessing/OutlinePlugin\";\nimport {SSGIPlugin} from \"./postprocessing/SSGIPlugin\";\nimport {AnisotropyPlugin} from \"./extras/AnisotropyPlugin\";\nimport {AdvancedGroundPlugin} from \"./extras/AdvancedGroundPlugin\";\nimport {WatchHandsPlugin} from \"./extras/WatchHandsPlugin\";\n\nexport {TemporalAAPlugin, TemporalAAPluginPass} from './postprocessing/TemporalAAPlugin'\nexport {VelocityBufferPlugin, SSVelocityMaterial} from './buffer/VelocityBufferPlugin'\nexport type {VelocityBufferPluginPass, VelocityBufferPluginTarget} from './buffer/VelocityBufferPlugin'\nexport {BloomPlugin, BloomPluginPass} from './postprocessing/BloomPlugin'\nexport {SSReflectionPlugin, SSReflectionPluginPass, type SSReflectionPluginTarget} from './postprocessing/SSReflectionPlugin'\nexport {SSGIPlugin, SSGIPluginPass, type SSGIPluginTarget} from './postprocessing/SSGIPlugin'\nexport {SSContactShadowsPlugin} from './postprocessing/SSContactShadowsPlugin'\nexport {DepthOfFieldPlugin, DepthOfFieldPluginPass} from './postprocessing/DepthOfFieldPlugin'\nexport {OutlinePlugin, OutlineRenderPass, type OutlinePluginPass, type OutlinePluginTarget} from './postprocessing/OutlinePlugin'\nexport {AnisotropyPlugin, anisotropyGLTFExtension} from \"./extras/AnisotropyPlugin\";\nexport {AdvancedGroundPlugin} from \"./extras/AdvancedGroundPlugin\";\nexport {WatchHandsPlugin} from \"./extras/WatchHandsPlugin\";\n\nexport const webgiPlugins = [\n    TemporalAAPlugin,\n    VelocityBufferPlugin,\n    BloomPlugin,\n    SSReflectionPlugin,\n    SSContactShadowsPlugin,\n    DepthOfFieldPlugin,\n    OutlinePlugin,\n    SSGIPlugin,\n    AnisotropyPlugin,\n    AdvancedGroundPlugin,\n    WatchHandsPlugin,\n]\n"],"names":["shadersUtils2","computeScreenSpaceVelocity","getWorldPositionFromViewZ","temporalAA","ssReflection","calculateGI","__inited","getShaders","Object","assign","RenderManager","ShaderChunk","_TemporalAAPlugin","PipelinePassPlugin","constructor","enabled","super","this","passId","_stableNoise","_gbufferUnpackExtension","_gbufferUnpackExtensionChanged","_pass","_viewer","Error","newExtension","renderManager","gbufferUnpackExtension","material","unregisterMaterialExtensions","registerMaterialExtensions","console","warn","dependencies","GBufferPlugin","ProgressivePlugin","uiConfig","type","label","onChange","setDirty","bind","children","generateUiConfig","stableNoise","v","_createPass","gbufferTarget","applyOnBackground","msaa","TemporalAAPluginPass","getPlugin","target","onAdded","viewer","addEventListener","onSizeUpdate","onRemove","removeEventListener","_beforeRender","scene","camera","pass","frame","frameCount","taaEnabled","renderCamera","mainCamera","cam","updateMatrixWorld","updateShaderProperties","updateCameraProperties","PluginType","OldPluginType","TemporalAAPlugin","__decorateClass","uiToggle","prototype","unwrapContents","ExtendedShaderPass","pid","vertexShader","CopyShader","fragmentShader","uniforms","currentRT","value","previousRT","previousRTSize","Vector2","cameraNearFar","lastProjectionViewMatrix","Matrix4","currentProjectionViewMatrix","projection","inverseViewMatrix","jitterSample","firstFrame","defines","QUALITY","UNJITTER","BACKGROUND_TAA","before","after","required","feedBack","debugVelocity","property","filter","c","clear","needsSwap","render","renderer","writeBuffer","readBuffer","deltaTime","maskActive","getOrCall","texture","copy","multiplyMatrices","projectionMatrix","matrixWorldInverse","matrixWorld","setSize","width","height","serialize","uniform","uiVector","matDefineBool","VelocityBufferPlugin","bufferType","UnsignedByteType","_attachToTaa","SSVelocityMaterial","unpackExtension","shaderExtender","shader","isDisabled","shaderReplaceString","computeCacheKey","extraUniforms","tVelocity","extraDefines","HAS_VELOCITY_BUFFER","priority","isCompatible","_createTarget","recreate","_disposeTarget","createTarget","depthBuffer","samples","generateMipmaps","colorSpace","LinearSRGBColorSpace","name","disposeTarget","userData","isGBufferMaterial","GBufferRenderPass","arguments","_firstCall","mat","overrideMaterial","multiply","Color","preprocessMaterial","m","disabled","forPlugin","taa","uiImage","readOnly","uiFolderContainer","ShaderMaterial","alphaMap","alphaTest","alphaMapTransform","Matrix3","blending","NoBlending","extraUniformsToUpload","modelMatrixPrevious","identity","_previousWorldMatrices","onBeforeRender","_r","_s","_c","_geometry","object","group","prevMatrix","uuid","clone","Array","isArray","x","USE_ALPHAMAP","needsUpdate","ALPHA_I_RGBA_PACKING","side","DoubleSide","_BloomPlugin","_a","materialExtension","uiConfigMaterialExtension","_getUiConfig","_onPluginAdd","e","plugin","gbuffer","registerGBufferUpdater","updateGBufferFlags","BloomPluginPass","Math","min","maxHDRIntensity","materialManager","registerMaterialExtension","unregisterGBufferUpdater","unregisterMaterialExtension","data","enable","pluginsDisabled","w","updateBit","AddBloomData","params","ud","config","uiRefresh","BloomPlugin","maxIntensity","PASS_STEP","MAX_INTENSITY","tSource","tDiffuse","opacity","tDiffuseSize","weight","prefilter","Vector4","threshold","softThreshold","intensity","backgroundBloom","bloomIterations","_currentIterations","radius","power","bloomDebug","_weights","_updateWeights","_thresholdsUpdated","y","z","source","sizeMultiplier","textures","currentDestination","getTempTarget","HalfFloatType","push","currentSource","ci","i","iter","max","modifiedWeight","oldAutoClear","autoClear","transparent","AdditiveBlending","releaseTempTarget","delta","f","oneMinusF","pow","uiSlider","onChange2","_DepthOfFieldPlugin","enableEdit","_focalPointHit","Vector3","crossFadeTime","_focalPointHitTime","computeCocMaterial","expandCocMaterial","PickingPlugin","_onObjectHit","_onPluginRemove","_tempVec","_frameFadeTime","setFocalPoint","p","fade","showGizmo","startTransition","now","getFocalPoint","intersects","intersect","point","time","selectedObject","FrameFadePlugin","DepthOfFieldPluginPass","dofBlurMaterial","getWorldPosition","subVectors","focalDepthRange","length","getWorldDirection","dot","normalize","crossAlpha","abs","projectedPoint","project","addScalar","divideScalar","crossCenter","set","uniformsNeedUpdate","DepthOfFieldPlugin","dofBlurMaterialPoisson","ExtendedShaderMaterial","colorTexture","colorTextureSize","direction","blurRadius","shaderUtils","defaultVertex","poissonDiskSamples","DOF_MODE","blurTexture","cocTexture","cocTextureSize","nearFarBlurScale","crossRadius","crossColor","error","halfPars","minFilter","NearestFilter","magFilter","format","RGBAFormat","cocRt","renderTargetBlurTemp","blit","renderTargetBlurTemp2","bindToValue","obj","key","ssrtShader","SSContactShadowsPlugin","AViewerPluginSync","_uniforms","sscsRadius","sscsIntensity","sscsTolerance","cameraPositionWorld","sceneBoundingRadius","tolerance","_defines","PERSPECTIVE_CAMERA","onlySSCSDebug","stepCount","_material","_renderer","SSCS_ENABLED","lsS","glsl","shadowChunk","shadowmap_pars_fragment","replace","lights_fragment_begin","onObjectRender","_","screenSpaceRendering","sscsDisabled","updateMaterialDefines","material1","isPhysicalMaterial","updaters","setGBufferUnpackExtension","assetManager","materials","BaseGroundPlugin","extension","propKey","matDefine","samplePointHelpers","SSReflectionPlugin","inlineShaderRayTrace","SSAAPlugin","_viewerListeners","preRender","postRender","SSReflectionPluginPass","vbp","_1","_2","progressive","ssrTarget","fromJSON","meta","passes","ssr","hideOnEmpty","SSR_STEP_COUNT","SSR_RAY_COUNT","SSR_RAY_BLEND_MAX","SSR_LOW_QUALITY_FRAMES","SSR_INLINE","SSR_MASK_FRONT_RAYS","tLastThis","tLastFrame","screenSize","currentFrameCount","boost","objectRadius","autoRadius","maskFrontFactor","ssrRoughnessFactor","ssrSplitX","roughnessFactor","rayCount","rayBlendMax","lowQualityFrames","maskFrontRays","split","tSSReflMap","ssrPower","ssrIntensity","ssrMaskFrontFactor","ssrBoost","SSREFL_ENABLED","prepend","_object","ssreflDisabled","ssreflNonPhysical","SSR_NON_PHYSICAL","parsFragmentSnippet","getTexelDecoding","values","map","join","tNormalDepth","HAS_GBUFFER","beforeRender","tags","that","hidden","OutlinePlugin","AScreenPassExtensionPlugin","outlineIntensity","outlineThickness","highlightTransparency","outlineColor","enableHighlight","dpr","outlineBuffer","DEBUG_OUTLINE","enableDynamicSelection","color","thickness","debugOutline","highlightSelectedMaterials","highlightMaterialSameNames","transparency","_shaderPatch","_pickingWidgetDisabled","_getSelectedObject","picking","getSelectedObject","names","mats","Set","mats1","findMaterialsByName","forEach","add","objects","getSelectedObjects","renderScale","mouseInOutAnimationEnabled","_state","selected","includes","widgetEnabled","onDirty","registerPass","pickingPlugin","_animationCallBack","_startTransparencyAnimation","document","canvas","unregisterPass","dispose","isOutlinePluginMaterial","OutlineRenderPass","from","to","duration","animateTarget","onComplete","uiColor","RenderPass","_getSelectedObjectOrMaterial","isOutlineRenderPass","t","getRenderTarget","activeCubeFace","getActiveCubeFace","activeMipLevel","getActiveMipmapLevel","_renderSelectedObject","setRenderTarget","getClearColor","setClearColor","objs","flatMap","o","isTexture","appliedObjects","isMaterial","isBufferGeometry","appliedMeshes","o1","traverse","layers","mask","transmissionRenderTarget","renderWithModes","shadowMapRender","backgroundRender","opaqueRender","transparentRender","transmissionRender","mainRenderPass","disable","BilateralFilterPass","sourceAccessor","bilDirection","B_SRC_ACCESSOR","smoothEnabled","edgeSharpness","_readBuffer","image","SSGIPlugin","SSGIPluginPass","ssrtgi","ssao","rtgiTarget","giEnabled","RTAO_STEP_COUNT","bias","falloff","ssrtaoSplitX","renderWithCamera","tSSGIMap","ssaoPower","ssgiIntensity","SSGI_ENABLED","SSRTAO_ENABLED","ssrtaoDisabled","ssaoDisabled","tex","bilateralPass","ssgiDisabled","AnisotropyPlugin","anisotropyFactor","anisotropyNoise","anisotropyDirection","anisotropyDirectionMap","anisotropy2MapUvTransform","_isAnisotropic","rotMap","_anisotropyDirectionMap","bsdfs","append","replaceAll","lights_physical_pars_fragment","anisotropyBsdf","normal_fragment_begin","lights_fragment_maps","USE_ANISOTROPY_BRDF","USE_UV","vertexTangents","isMesh","geometry","attributes","tangent","_anisotropyFactor","_anisotropyNoise","_anisotropyDirection","updateMatrix","matrix","ANISOTROPY_ENABLED","ANISOTROPY_TEX_MODE","_anisotropyDirectionMode","getUiConfig","enableAnisotropy","state","ev","dialog","alert","bounds","makeSamplerUi","onMaterialUpdate","__appliedMeshes","tryComputeTangents","onRegister","onAddToMesh","mesh","find","m1","factor","noise","directionMode","meshes","possible","position","normal","uv","computeTangents","index","registerGltfExtension","anisotropyGLTFExtension","unregisterGltfExtension","makeAnisotropic","ANISOTROPY_GLTF_EXTENSION","GLTFMaterialsAnisotropyExtensionImport","parser","extendMaterialParams","materialIndex","materialParams","materialDef","json","extensions","Promise","resolve","pending","anisotropyNoiseFactor","anisotropyDirectionMode","anisotropyTextureMode","anisotropyRotation","assignTexture","then","SRGBColorSpace","all","afterRoot","result","geom","import","export","writeMaterial","isMeshStandardMaterial","extensionDef","checkEmptyMap","anisotropyDirectionMapDef","processTexture","applyTextureTransform","extensionsUsed","_Reflector2","Mesh2","renderTarget","clipBias","isReflector2","reflectorModePhysical","reflectionTargetNeedsUpdate","transparentReflectionBackground","tRefDiffuse","tRefDiffuseSize","refTextureMatrix","ls","parsVertexSnippet","__lastTransparent","__setDirty","_renderTarget","reflectorPlane","Plane","reflectorWorldPosition","cameraWorldPosition","rotationMatrix","lookAtPosition","clipPlane","view","q","textureMatrix","virtualCamera","PerspectiveCamera","thisRenderTarget","_getRenderTarget","viewOffset","clearViewOffset","setFromMatrixPosition","extractRotation","applyMatrix4","reflect","negate","up","lookAt","far","near","setFromNormalAndCoplanarPoint","constant","sign","elements","multiplyScalar","visible","currentRenderTarget","currentXrEnabled","xr","currentShadowAutoUpdate","shadowMap","autoUpdate","buffers","depth","setMask","sceneBackground","background","renderBackground","flipX","setViewOffset","fullWidth","fullHeight","offsetX","offsetY","viewport","MathUtils","isPowerOfTwo","_updateExtension","Reflector2","isReflector","_xfnv1a","imul","charCodeAt","defineProperty","enumerable","configurable","writable","a","next","b","d","r","s","sfc32","mulberry32","xoshiro128ss","str","prng","generator","_initializeGenerator","wrap","random","RandomizedDirectionalLight","DirectionalLight2","shadow","_shadowParams","normalBias","frustumSize","_randomParams","focus","spread","distanceScale","minDistanceScale","normalDirection","isRandomizedDirectionalLight","shadowParams","randomParams","updateShadowParams","keys","castShadow","mapSize","refreshShadowCamNearFar","right","left","top","bottom","updateProjectionMatrix","matrixWorldNeedsUpdate","randomizePosition","seed","rand","Rand","toString","rnd","PI","asin","dir","cos","sin","v2","kk","getSample","sqrt","cd","dist","toJSON","_internal","copiedData","copyObject3DUserData","Serialization","Serialize","toArray","ThreeSerialization","fromArray","Deserialize","extent","o2","crossVectors","oneminus","FSShadowMaterial","ShadowMaterial","typeSlug","assetType","lastFrameTexture","materialObject","onBeforeCompile","customProgramCacheKey","copyProps","options","dispatchEvent","_ShadowMapBaker","SimpleEventDispatcher","_lightLayer","_frameNumber","maxFrameNumber","smoothShadow","shadowMapType","BasicShadowMap","groundMapMode","alphaVignette","alphaVignetteAxis","shadowAutoUpdate","_bakeCounter","maxBakeCount","Infinity","transitionOpacity","aomap_fragment","map_fragment","alphamap_fragment","capabilities","isWebGL2","gMapMode","light","disableAll","_light","addObject","addToRoot","_shadowMat","toneMapped","depthWrite","depthTest","premultipliedAlpha","_shadowBlurMat","ShaderMaterial2","step","size","attachedMesh","_attachedMesh","cleanupMaterial","_updateMaterial","_target","reset","_groundMapModeChanged","_alphaVignetteChanged","frameNumber","autoUpdateShadow","updateShadow","bakeCount","progress","customSize","NoColorSpace","shadowMapNeedsUpdate","shadowMapAutoUpdate","sceneLightLayer","Layers","isLight","__gp_layers","sceneRender","camLayers","lastThisTarget","lastThisTargetColorSpace","currentMaterial","currentFrustumCulled","frustumCulled","currentRt","_applySmoothFilter","modelObject","lightObject","isNull","aoMap","shadowReadBuffer","shadowWriteBuffer","ShadowMapBaker","_AdvancedGroundPlugin","_b","bakedShadows","groundReflection","physicalReflections","autoFrustumSize","autoBakeShadows","autoResetShadows","_shadowBaker","_onSceneUpdate","generatedUi","matUI","_extraUiConfig","shadowBaker","_refresh3","refresh","bakeShadows","_createMesh","reflector","LinearMipmapLinearFilter","LinearFilter","_createMaterial","superOnBeforeRender","getPluginByType","_postFrame","_preRender","_mesh","_removeMaterial","groundMatExtension","reflectorMatExtension","ext","event","isWidgetRoot","geometryChanged","ref","_refreshTransform","baker","fs","_refreshMaterial","stepSize","transmission","limitedUi","PCFShadowMap","PCFSoftShadowMap","VSMShadowMap","AdvancedGroundPlugin","WatchHandsPlugin","axis","invertAxis","analog","hourOffset","minuteOffset","secondOffset","hour","minute","second","regex","hands","_lastEnabled","_preFrame","h","rotation","initRotation","resetShadows","postFrameConvergedRecordingDelta","Date","invert","secondHandRotation","getSeconds","getMilliseconds","minuteHandRotation","getMinutes","hourHandRotation","getHours","hand","_addSceneObject","async","modelRoot","isChild","traverseAncestors","oa","match","RegExp","uiDropdown","uiInput","uiButton","webgiPlugins"],"mappings":"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","x_google_ignoreList":[30]}