UNPKG

@takram/three-atmosphere

Version:
1,523 lines (1,522 loc) 116 kB
import { struct as ut, uint as Q, uvec2 as Mt, ivec2 as ue, float as P, vec3 as E, uniform as O, clamp as cs, sqrt as _, max as ot, smoothstep as Ae, floor as de, vec4 as w, div as us, mul as pt, PI as Fe, add as Ct, bool as _t, If as D, min as Rt, exp as he, vec2 as U, Loop as wt, mix as ct, step as Un, cos as It, sin as Vt, mrt as we, screenCoordinate as at, acos as qs, Fn as Y, texture as Gt, texture3D as Ee, globalId as st, Return as fe, textureStore as kt, workgroupArray as fs, workgroupBarrier as vs, uvec3 as In, positionView as Pn, PI2 as Bn, fwidth as Zs, equirectUV as On, dFdx as Ns, dFdy as bs, log as Wn, instancedBufferAttribute as We, screenSize as $s, screenUV as kn, pow as Gn, uv as se, nodeProxy as Hs, positionGeometry as ds, remapClamp as qn, normalWorld as Zn, positionWorld as $n, cameraViewMatrix as Hn, int as Es, and as Xs, Break as Ms, uniformTexture as Xn, uvec4 as Rs, uniformArray as zs, instanceIndex as Ls, pmremTexture as Kn } from "three/tsl"; import { Vector3 as nt, RenderTarget as Ht, RGBAFormat as Bt, LinearFilter as X, NoColorSpace as De, RenderTarget3D as Qn, Vector2 as zt, Texture as Yn, FloatType as ls, HalfFloatType as Xt, Data3DTexture as _n, Sprite as jn, InstancedBufferAttribute as ke, AdditiveBlending as Jn, DirectionalLight as Ks, Matrix3 as to, RGFormat as ms, Box2 as eo, Matrix4 as Qs, Vector4 as so, PerspectiveCamera as no, Points as oo, BufferGeometry as io, BufferAttribute as ao, Mesh as ro, WebGLCubeRenderTarget as co, CubeCamera as uo } from "three"; import { reinterpretType as hs, radians as Ys, isFloatLinearSupported as lo, Geodetic as mo, Ellipsoid as ho, ArrayBufferLoader as po, floorPowerOfTwo as go, QuadGeometry as xo } from "@takram/three-geospatial"; import { l as rt, r as Vs, k as So, a as yo } from "./shared2.js"; import { QuadMesh as Kt, NodeMaterial as vt, StorageTexture as To, Storage3DTexture as Co, RendererUtils as Ot, Node as wo, NodeUpdateType as gt, TempNode as Qt, PointsNodeMaterial as _s, RenderTarget as fo, AnalyticLightNode as vo, LinearFilter as As } from "three/webgpu"; import { FnLayout as k, FnVar as W, stbn as No, outputTexture as ft, outputTexture3D as Ge, isWebGPU as bo, cameraNear as Eo, cameraFar as js, projectionMatrix as Js, equirectToDirectionWorld as Mo, inverseProjectionMatrix as Me, inverseViewMatrix as re, rayEllipsoidIntersection as Ro, depthToViewZ as zo, screenToPositionView as Lo, Node as ne, raySpheresIntersections as Vo, textureGather as tn, bvecNot as le, bvecAnd as jt, OnBeforeFrameUpdate as Jt } from "@takram/three-geospatial/webgpu"; import { hash as ps } from "three/src/nodes/core/NodeUtils.js"; const H = "float", Ao = "float", q = "float", Fs = "float", Fo = "float", en = "float", Do = "vec3", qt = "vec3", Pt = "vec3", sn = "vec3", At = "vec3", nn = "vec3", Ds = "vec3", Re = /* @__PURE__ */ ut( { width: H, expTerm: q, expScale: Fs, linearTerm: Fs, constantTerm: q }, "DensityProfileLayer" ), te = /* @__PURE__ */ ut( { layer0: Re.layout.name, layer1: Re.layout.name }, "DensityProfile" ), os = { worldToUnit: q, solarIrradiance: Pt, sunAngularRadius: Ao, bottomRadius: H, topRadius: H, rayleighDensity: te.layout.name, rayleighScattering: At, mieDensity: te.layout.name, mieScattering: At, mieExtinction: At, miePhaseFunctionG: q, absorptionDensity: te.layout.name, absorptionExtinction: At, groundAlbedo: qt, minCosLight: q, sunRadianceToLuminance: qt, skyRadianceToLuminance: qt, luminanceScale: q, transmittanceTextureSize: "uvec2", irradianceTextureSize: "uvec2", multipleScatteringTextureSize: "uvec2", scatteringTextureRadiusSize: "uint", scatteringTextureCosViewSize: "uint", scatteringTextureCosLightSize: "uint", scatteringTextureCosViewLightSize: "uint" }, J = /* @__PURE__ */ ut( os, "AtmosphereParameters" ); function Us(n, t) { const { width: e, expTerm: s, expScale: o, linearTerm: i, constantTerm: a } = n; return Re({ // @ts-expect-error Object-style parameter is supported width: P(e * t), expTerm: P(s), expScale: P(o / t), linearTerm: P(i / t), constantTerm: P(a) }); } function qe(n, t) { return te({ // @ts-expect-error Object-style parameter is supported layer0: Us(n.layers[0], t), layer1: Us(n.layers[1], t) }); } const Is = Symbol("DESTRUCTIBLE"); function j(n) { if (hs(n), n[Is] === !0) return n; for (const t in os) Object.hasOwn(os, t) && (n[t] = n.get(t)); return n[Is] = !0, n; } class gs { constructor(t) { this.parameters = t; const { worldToUnit: e, solarIrradiance: s, sunAngularRadius: o, bottomRadius: i, topRadius: a, rayleighDensity: r, rayleighScattering: u, mieDensity: c, mieScattering: d, mieExtinction: l, miePhaseFunctionG: h, absorptionDensity: m, absorptionExtinction: p, groundAlbedo: y, minCosLight: g, sunRadianceToLuminance: S, skyRadianceToLuminance: x, luminanceScale: T, transmittanceTextureSize: C, irradianceTextureSize: f, multipleScatteringTextureSize: M, scatteringTextureRadiusSize: N, scatteringTextureCosViewSize: b, scatteringTextureCosLightSize: A, scatteringTextureCosViewLightSize: z } = t; this.parametersNode = j( J({ // @ts-expect-error Object-style parameter is supported worldToUnit: P(e), solarIrradiance: E(s), sunAngularRadius: P(o), bottomRadius: P(i * e), topRadius: P(a * e), rayleighDensity: qe(r, e), rayleighScattering: E( u.x / e, u.y / e, u.z / e ), mieDensity: qe(c, e), mieScattering: E( d.x / e, d.y / e, d.z / e ), mieExtinction: E( l.x / e, l.y / e, l.z / e ), miePhaseFunctionG: P(h), absorptionDensity: qe(m, e), absorptionExtinction: E( p.x / e, p.y / e, p.z / e ), groundAlbedo: E(y), minCosLight: P(g), sunRadianceToLuminance: E(S), skyRadianceToLuminance: E(x), luminanceScale: P(T), transmittanceTextureSize: ue(C), irradianceTextureSize: ue(f), multipleScatteringTextureSize: Mt(M), scatteringTextureRadiusSize: Q(N), scatteringTextureCosViewSize: Q(b), scatteringTextureCosLightSize: Q(A), scatteringTextureCosViewLightSize: Q( z ) }).toConst("atmosphereParameters") ); } // eslint-disable-next-line @typescript-eslint/class-methods-use-this dispose() { } } function Nt(n) { if (typeof n.context.getAtmosphere != "function") throw new Error("getAtmosphere() was not found in the builder context."); const t = n.context.getAtmosphere(); if (!(t instanceof gs)) throw new Error( "getAtmosphere() must return an instanceof AtmosphereContextBase." ); return t; } class on extends gs { constructor(t, e) { super(t), this.lambdas = O(new nt(680, 550, 440)), this.luminanceFromRadiance = O("mat3"), this.textureType = e; } } class an { setup(t, e) { this.parameters = t, this.textureType = e; } // eslint-disable-next-line @typescript-eslint/class-methods-use-this dispose() { } } const Tt = /* @__PURE__ */ k({ name: "clampCosine", type: q, inputs: [{ name: "cosine", type: q }] })(([n]) => cs(n, -1, 1)), rn = /* @__PURE__ */ k({ name: "clampDistance", type: q, inputs: [{ name: "cosine", type: q }] })(([n]) => ot(n, 0)), pe = /* @__PURE__ */ k({ name: "clampRadius", type: H, inputs: [ { name: "parameters", type: J }, { name: "radius", type: H } ] })(([n, t]) => { const { topRadius: e, bottomRadius: s } = j(n); return cs(t, s, e); }), Ut = /* @__PURE__ */ k({ name: "sqrtSafe", type: q, inputs: [{ name: "area", type: Fo }] })(([n]) => _(ot(n, 0))), ee = /* @__PURE__ */ k({ name: "distanceToTopAtmosphereBoundary", type: H, inputs: [ { name: "parameters", type: J }, { name: "radius", type: H }, { name: "cosView", type: q } ] })(([n, t, e]) => { const { topRadius: s } = j(n), o = t.pow2().mul(e.pow2().sub(1)).add(s.pow2()); return rn(t.negate().mul(e).add(Ut(o))); }), Uo = /* @__PURE__ */ k({ name: "distanceToBottomAtmosphereBoundary", type: H, inputs: [ { name: "parameters", type: J }, { name: "radius", type: H }, { name: "cosView", type: q } ] })(([n, t, e]) => { const { bottomRadius: s } = j(n), o = t.pow2().mul(e.pow2().sub(1)).add(s.pow2()); return rn(t.negate().mul(e).sub(Ut(o))); }), cn = /* @__PURE__ */ k({ name: "distanceToNearestAtmosphereBoundary", type: H, inputs: [ { name: "parameters", type: J }, { name: "radius", type: H }, { name: "cosView", type: q }, { name: "intersectsGround", type: "bool" } ] })(([n, t, e, s]) => s.select( Uo(n, t, e), ee(n, t, e) )), xs = /* @__PURE__ */ k({ name: "rayIntersectsGround", type: "bool", inputs: [ { name: "parameters", type: J }, { name: "radius", type: H }, { name: "cosView", type: q } ] })(([n, t, e]) => { const { bottomRadius: s } = j(n); return e.lessThan(0).and( t.pow2().mul(e.pow2().sub(1)).add(s.pow2()).greaterThanEqual(0) ); }), Ft = /* @__PURE__ */ k({ name: "getTextureCoordFromUnitRange", type: "float", inputs: [ { name: "unit", type: "float" }, { name: "textureSize", type: "float" } ] })(([n, t]) => us(0.5, t).add( n.mul(t.reciprocal().oneMinus()) )), Io = /* @__PURE__ */ k({ name: "getTransmittanceTextureUV", type: "vec2", inputs: [ { name: "parameters", type: J }, { name: "radius", type: H }, { name: "cosView", type: q } ] })(([n, t, e]) => { const { topRadius: s, bottomRadius: o, transmittanceTextureSize: i } = j(n), a = _(s.pow2().sub(o.pow2())).toConst(), r = Ut( t.pow2().sub(o.pow2()) ).toConst(), u = ee( n, t, e ), c = s.sub(t).toConst(), d = r.add(a), l = u.remap(c, d), h = r.div(a); return U( Ft(l, i.x), Ft(h, i.y) ); }), Yt = /* @__PURE__ */ W( (n, t, e) => (s) => { const o = Nt(s), { parametersNode: i } = o, a = Io(i, t, e); return n.sample(a).rgb; } ), Ne = /* @__PURE__ */ W( (n, t, e, s, o) => (i) => { const a = Nt(i), { parametersNode: r } = a, u = pe( r, _( s.pow2().add(pt(2, t, e, s)).add(t.pow2()) ) ).toConst(), c = Tt( t.mul(e).add(s).div(u) ).toConst(), d = E(0).toVar(); return D(o, () => { d.assign( Yt( n, u, c.negate() ).div( Yt( n, t, e.negate() ) ).min(1) ); }).Else(() => { d.assign( Yt( n, t, e ).div( Yt( n, u, c ) ).min(1) ); }), d; } ), $t = /* @__PURE__ */ W( (n, t, e) => (s) => { const o = Nt(s), { parametersNode: i } = o, { sunAngularRadius: a, bottomRadius: r } = i, u = r.div(t).toConst(), c = _(ot(u.pow2().oneMinus(), 0)).negate(); return Yt( n, t, e ).mul( Ae( u.negate().mul(a), u.mul(a), e.sub(c) ) ); } ), ge = /* @__PURE__ */ k({ name: "rayleighPhaseFunction", type: en, inputs: [{ name: "cosViewLight", type: q }] })(([n]) => us(3, pt(16, Fe)).mul(n.pow2().add(1))), Ue = /* @__PURE__ */ k({ name: "miePhaseFunction", type: en, inputs: [ { name: "g", type: q }, { name: "cosViewLight", type: q } ] })(([n, t]) => us(3, Fe.mul(8)).mul(n.pow2().oneMinus()).div(n.pow2().add(2)).mul(t.pow2().add(1)).div(n.pow2().sub(n.mul(2).mul(t)).add(1).pow(1.5))), un = /* @__PURE__ */ k({ name: "getScatteringTextureCoord", type: "vec4", inputs: [ { name: "parameters", type: J }, { name: "radius", type: H }, { name: "cosView", type: q }, { name: "cosLight", type: q }, { name: "cosViewLight", type: q }, { name: "intersectsGround", type: "bool" } ] })(([ n, t, e, s, o, i ]) => { const { topRadius: a, bottomRadius: r, minCosLight: u, scatteringTextureRadiusSize: c, scatteringTextureCosViewSize: d, scatteringTextureCosLightSize: l } = j(n), h = _(a.pow2().sub(r.pow2())).toConst(), m = Ut( t.pow2().sub(r.pow2()) ).toConst(), p = Ft( m.div(h), c ), y = t.mul(e).toConst(), g = y.pow2().sub(t.pow2()).add(r.pow2()).toConst(), S = P(0).toVar(); D(i, () => { const z = y.negate().sub(Ut(g)), L = t.sub(r).toConst(), R = m; S.assign( Ft( R.equal(L).select(0, z.remap(L, R)), d.div(2) ).oneMinus().mul(0.5) ); }).Else(() => { const z = y.negate().add(Ut(g.add(h.pow2()))), L = a.sub(t).toConst(), R = m.add(h); S.assign( Ft( z.remap(L, R), d.div(2) ).add(1).mul(0.5) ); }); const x = a.sub(r).toConst(), T = h, f = ee(n, r, s).remap(x, T).toConst(), N = ee( n, r, u ).remap(x, T), b = Ft( ot(f.div(N).oneMinus(), 0).div(f.add(1)), l ), A = o.add(1).mul(0.5); return w(A, b, S, p); }), ze = /* @__PURE__ */ W( (n, t, e, s, o, i) => (a) => { const r = Nt(a), { parametersNode: u } = r, { scatteringTextureCosViewLightSize: c } = u, d = un( u, t, e, s, o, i ).toConst(), l = d.x.mul(c.sub(1)).toConst(), h = de(l).toConst(), m = l.sub(h).toConst(), p = E( h.add(d.y).div(c), d.z, d.w ), y = E( h.add(1).add(d.y).div(c), d.z, d.w ); return n.sample(p).mul(m.oneMinus()).add(n.sample(y).mul(m)).rgb; } ), Po = /* @__PURE__ */ k({ name: "getIrradianceTextureUV", type: "vec2", inputs: [ { name: "parameters", type: J }, { name: "radius", type: H }, { name: "cosLight", type: q } ] })(([n, t, e]) => { const { topRadius: s, bottomRadius: o, irradianceTextureSize: i } = j(n), a = t.remap(o, s), r = e.mul(0.5).add(0.5); return U( Ft(r, i.x), Ft(a, i.y) ); }), Ss = /* @__PURE__ */ W( (n, t, e) => (s) => { const o = Nt(s), { parametersNode: i } = o, a = Po(i, t, e); return n.sample(a).rgb; } ), Ps = /* @__PURE__ */ k({ name: "getLayerDensity", type: q, inputs: [ { name: "layer", type: Re }, { name: "altitude", type: H } ] })(([n, t]) => { const e = n.get("expTerm"), s = n.get("expScale"), o = n.get("linearTerm"), i = n.get("constantTerm"); return e.mul(he(s.mul(t))).add(o.mul(t)).add(i).saturate(); }), be = /* @__PURE__ */ k({ name: "getProfileDensity", type: q, inputs: [ { name: "layer", type: te }, { name: "altitude", type: H } ] })(([n, t]) => t.lessThan(n.get("layer0").get("width")).select( Ps(n.get("layer0"), t), Ps(n.get("layer1"), t) )), Dt = /* @__PURE__ */ k({ name: "getUnitRangeFromTextureCoord", type: "float", inputs: [ { name: "coord", type: "float" }, { name: "textureSize", type: "float" } ] })(([n, t]) => { const e = t.reciprocal(); return n.sub(e.mul(0.5)).div(e.oneMinus()); }), Le = /* @__PURE__ */ ut( { radius: H, cosView: q, cosLight: q, cosViewLight: q, intersectsGround: "bool" }, "ScatteringParams" ), Bo = /* @__PURE__ */ k({ // BUG: Cannot access vector component inside struct in layout function // https://github.com/mrdoob/three.js/issues/33345 typeOnly: !0, name: "getParamsFromScatteringTextureCoord", type: Le, inputs: [ { name: "parameters", type: J }, { name: "coord", type: "vec4" } ] })(([n, t]) => { const { bottomRadius: e, topRadius: s, minCosLight: o, scatteringTextureRadiusSize: i, scatteringTextureCosViewSize: a, scatteringTextureCosLightSize: r } = j(n), u = _(s.pow2().sub(e.pow2())).toConst(), c = u.mul( Dt(t.w, i) ).toConst(), d = _(c.pow2().add(e.pow2())), l = P(0).toVar(), h = _t().toVar(); D(t.z.lessThan(0.5), () => { const M = d.sub(e).toConst(), N = c, b = M.add( N.sub(M).mul( Dt( t.z.mul(2).oneMinus(), a.div(2) ) ) ).toConst(); l.assign( b.equal(0).select( -1, Tt( c.pow2().add(b.pow2()).negate().div(pt(2, d, b)) ) ) ), h.assign(_t(!0)); }).Else(() => { const M = s.sub(d).toConst(), N = c.add(u), b = M.add( N.sub(M).mul( Dt( t.z.mul(2).sub(1), a.div(2) ) ) ).toConst(); l.assign( b.equal(0).select( 1, Tt( u.pow2().sub(c.pow2()).sub(b.pow2()).div(pt(2, d, b)) ) ) ), h.assign(_t(!1)); }); const m = Dt( t.y, r ).toConst(), p = s.sub(e).toConst(), y = u, S = ee( n, e, o ).remap(p, y).toConst(), x = S.sub(m.mul(S)).div(m.mul(S).add(1)), T = p.add(Rt(x, S).mul(y.sub(p))).toConst(), C = T.equal(0).select( 1, Tt( u.pow2().sub(T.pow2()).div(pt(2, e, T)) ) ), f = Tt(t.x.mul(2).sub(1)); return Le( d, l, C, f, h ); }), Oo = /* @__PURE__ */ k({ // BUG: Cannot access vector component inside struct in layout function // https://github.com/mrdoob/three.js/issues/33345 typeOnly: !0, name: "getParamsFromScatteringTextureFragCoord", type: Le, inputs: [ { name: "parameters", type: J }, { name: "fragCoord", type: "vec3" } ] })(([n, t]) => { const { scatteringTextureRadiusSize: e, scatteringTextureCosViewSize: s, scatteringTextureCosLightSize: o, scatteringTextureCosViewLightSize: i } = j(n), a = de( t.x.div(o) ), r = t.x.mod(o), u = w( i.sub(1), o, s, e ), c = w( a, r, t.y, t.z ).div(u), d = Bo( n, c ).toConst(), l = d.get("radius"), h = d.get("cosView"), m = d.get("cosLight"), p = d.get("cosViewLight").toVar(), y = d.get("intersectsGround"), g = _( h.pow2().oneMinus().mul(m.pow2().oneMinus()) ).toConst(); return p.assign( cs( p, h.mul(m).sub(g), h.mul(m).add(g) ) ), Le( l, h, m, p, y ); }), dn = /* @__PURE__ */ k({ name: "getExtrapolatedSingleMieScattering", type: Pt, inputs: [ { name: "scattering", type: "vec4" }, { name: "rayleighScattering", type: "vec3" }, { name: "mieScattering", type: "vec3" } ] })(([n, t, e]) => { const s = E(0).toVar(); return D(n.r.greaterThanEqual(1e-5), () => { s.assign( n.rgb.mul(n.a).div(n.r).mul(t.r.div(e.r)).mul(e.div(t)) ); }), s; }), Wo = /* @__PURE__ */ ut( { scattering: Pt, singleMieScattering: Pt }, "CombinedScattering" ), Zt = /* @__PURE__ */ W( (n, t, e, s, o, i, a, r) => (u) => { const c = Nt(u), { rayleighScattering: d, mieScattering: l, scatteringTextureCosViewLightSize: h } = j(n), m = un( n, s, o, i, a, r ).toConst(), p = m.x.mul(h.sub(1)).toConst(), y = de(p).toConst(), g = p.sub(y).toConst(), S = E( y.add(m.y).div(h), m.z, m.w ).toConst(), x = E( y.add(1).add(m.y).div(h), m.z, m.w ).toConst(), T = E(0).toVar(), C = E(0).toVar(); if (c.parameters.combinedScatteringTextures) { const f = Ct( t.sample(S).mul(g.oneMinus()), t.sample(x).mul(g) ).toConst(); T.assign(f.rgb), C.assign( dn( f, d, l ) ); } else T.assign( Ct( t.sample(S).mul(g.oneMinus()), t.sample(x).mul(g) ).rgb ), C.assign( Ct( e.sample(S).mul(g.oneMinus()), e.sample(x).mul(g) ).rgb ); return Wo(T, C); } ), xe = /* @__PURE__ */ ut( { radiance: sn, transmittance: qt }, "RadianceTransfer" ), ko = /* @__PURE__ */ k({ name: "getSubUVFromTextureUnit", type: "vec2", inputs: [ { name: "unit", type: "vec2" }, { name: "textureSize", type: "vec2" } ] })(([n, t]) => n.add(P(0.5).div(t)).mul(t.div(t.add(1)))), ln = /* @__PURE__ */ k({ name: "getTextureUnitFromSubUV", type: "vec2", inputs: [ { name: "subUV", type: "vec2" }, { name: "textureSize", type: "vec2" } ] })(([n, t]) => n.sub(P(0.5).div(t)).mul(t.div(t.sub(1)))), Bs = /* @__PURE__ */ ut( { rayleighScattering: At, mieScattering: At, scattering: At, extinction: At }, "AtmosphereMedium" ), ys = /* @__PURE__ */ k({ name: "sampleAtmosphereMedium", type: Bs, inputs: [ { name: "parameters", type: J }, { name: "altitude", type: H } ] })(([n, t]) => { const e = j(n), s = be(e.rayleighDensity, t), o = be(e.mieDensity, t), i = be(e.absorptionDensity, t), a = s.mul(e.rayleighScattering), r = a, u = o.mul(e.mieScattering), c = o.mul(e.mieExtinction), d = i.mul(e.absorptionExtinction), l = Ct(a, u), h = Ct(r, c, d); return Bs( a, u, l, h ); }), Go = /* @__PURE__ */ ut( { multipleScattering: sn, transferFactor: qt }, "MultipleScattering" ), mn = /* @__PURE__ */ W( (n, t, e, s, o, i) => { const { solarIrradiance: a, bottomRadius: r, groundAlbedo: u } = j(n), c = xs( n, e, s ).toConst(), d = cn( n, e, s, c ).toConst(), l = E(0).toVar(), h = E(0).toVar(), m = E(1).toVar(), p = P(0).toVar(), y = 20; return wt({ type: "float", start: 0, end: y }, ({ i: g }) => { const S = d.mul(g.add(0.3)).div(y).toConst(), x = S.sub(p).toConst(); p.assign(S); const T = pe( n, _( S.pow2().add(pt(2, e, s, S)).add(e.pow2()) ) ).toConst(), C = Tt( e.mul(o).add(S.mul(i)).div(T) ).toConst(), f = T.sub(r), M = ys(n, f).toConst(), N = M.get("scattering"), b = M.get("extinction"), A = b.mul(x).toConst(), z = he(A.negate()).toConst(), L = $t( t, T, C ).toConst(), R = N.sub(N.mul(z)).div(b).toConst(); h.addAssign(m.mul(R)); const V = L.mul(N.mul(1 / (4 * Math.PI))).toConst(), I = V.sub(V.mul(z)).div(b).toConst(); l.addAssign( m.mul(I) ), m.mulAssign(z); }), D(c, () => { const g = Tt( e.mul(o).add(d.mul(i)).div(r) ).toConst(), S = $t( t, r, g ).toConst(); l.addAssign( a.mul( S, m, g.saturate(), u, 1 / Math.PI ) ); }), Go( l, h ); } ), hn = /* @__PURE__ */ W( (n, t, e, s) => { const { topRadius: o, bottomRadius: i, multipleScatteringTextureSize: a } = j(n), r = ko( U( s.mul(0.5).add(0.5), e.sub(i).div(o.sub(i)) ).saturate(), a ); return t.sample(r).rgb; } ), qo = /* @__PURE__ */ ut( { scattering: Pt, singleMieScattering: Pt, higherOrderScattering: Do }, "Scattering" ), pn = /* @__PURE__ */ W( (n, t, e) => (s) => { const o = Nt(s), { parametersNode: i } = o, { solarIrradiance: a, bottomRadius: r } = i, u = Oo( i, e ).toConst(), c = u.get("radius"), d = u.get("cosView"), l = u.get("cosLight"), h = u.get("cosViewLight"), m = u.get("intersectsGround"), p = cn( i, c, d, m ).toConst(), S = ct( 14, 30, p.mul(1 / 100) ).toConst(), x = S.floor().toConst(), T = x.reciprocal().toConst(), C = p.mul(x).div(S).toConst(), f = ge(h).toConst(), M = E(0).toVar(), N = E(0).toVar(), b = E(0).toVar(), A = E(1).toVar(); return wt({ type: "float", start: 0, end: S }, ({ i: z }) => { const L = z.mul(T).toVar(), R = z.add(1).mul(T).toVar(); L.mulAssign(L), R.mulAssign(R), L.mulAssign(C), R.assign( R.greaterThan(1).select(p, C.mul(R)) ); const V = R.sub(L), I = L.add(V.mul(0.3)), F = pe( i, _( I.pow2().add(pt(2, c, d, I)).add(c.pow2()) ) ).toConst(), v = Tt( c.mul(l).add(I.mul(h)).div(F) ).toConst(), Z = F.sub(r), B = ys( i, Z ).toConst(), G = B.get("rayleighScattering"), $ = B.get("mieScattering"), dt = B.get("scattering"), tt = B.get("extinction"), xt = tt.mul(V), it = he(xt.negate()).toConst(), bt = $t( n, F, v ).toConst(), lt = hn( i, t, F, v ).mul(dt).toConst(); let et = bt.mul(G); o.parameters.higherOrderScatteringTexture || (et = et.add(lt.div(f))), et = a.mul(et).toConst(); const mt = et.sub(et.mul(it)).div(tt).toConst(); M.addAssign(A.mul(mt)); const St = a.mul(bt.mul($)).toConst(), Se = St.sub(St.mul(it)).div(tt).toConst(); N.addAssign(A.mul(Se)); const yt = a.mul(lt), ht = yt.sub(yt.mul(it)).div(tt).toConst(); b.addAssign(A.mul(ht)), A.mulAssign(it); }), qo(M, N, b); } ), Zo = /* @__PURE__ */ W( (n, t, e, s, o, i, a) => { const { lutNode: r, parametersNode: u, scatteringSampleCount: c } = n, d = r.getTextureNode("transmittance"), l = r.getTextureNode("multipleScattering"), { solarIrradiance: h, bottomRadius: m, miePhaseFunctionG: p } = u, y = ct( c.x, c.y, i.mul(1 / 100) ).toConst(), g = y.floor().toConst(), S = g.reciprocal().toConst(), x = i.mul(g).div(y).toConst(), T = Ue(p, o).toConst(), C = ge(o).toConst(), f = U( a.y, a.y.add(a.x) ).toConst(), M = E(0).toVar(), N = E(1).toVar(); return wt({ type: "float", start: 0, end: y }, ({ i: b }) => { const A = b.mul(S).toVar(), z = b.add(1).mul(S).toVar(); A.mulAssign(A), z.mulAssign(z), A.mulAssign(x), z.assign(z.greaterThan(1).select(i, x.mul(z))); const L = z.sub(A), R = A.add(L.mul(No)), V = pe( u, _( R.pow2().add(pt(2, t, e, R)).add(t.pow2()) ) ).toConst(), I = Tt( t.mul(s).add(R.mul(o)).div(V) ).toConst(), F = V.sub(m), v = ys(u, F).toConst(), Z = v.get("rayleighScattering"), B = v.get("mieScattering"), G = v.get("scattering"), $ = v.get("extinction"), dt = $.mul(L), tt = he(dt.negate()).toConst(), xt = $t( d, V, I ).toConst(), it = hn( u, l, V, I ).mul(G).toConst(), bt = Un( U(R, f.y), U(f.x, R) ).toConst(), lt = bt.x.add(bt.y).min(1).toConst(), et = Ct( Z.mul(C), B.mul(T) ); let mt; n.parameters.higherOrderScatteringTexture ? mt = h.mul( xt.mul(et).mul(lt).add(it) ).toConst() : mt = h.mul( xt.mul(et).add(it).mul(lt) ).toConst(); const St = mt.sub(mt.mul(tt)).div($).toConst(); M.addAssign(N.mul(St)), N.mulAssign(tt); }), xe(M, N); } ), Ze = /* @__PURE__ */ k({ name: "computeOpticalDepthToTopAtmosphereBoundary", type: H, inputs: [ { name: "parameters", type: J }, { name: "profile", type: te }, { name: "radius", type: H }, { name: "cosView", type: q } ] })(([n, t, e, s]) => { const { bottomRadius: o } = j(n), i = 500, a = ee(n, e, s).div(i).toConst(), r = P(0).toVar(); return wt({ start: 0, end: i, condition: "<=" }, ({ i: u }) => { const c = P(u).mul(a).toConst(), d = _( Ct(c.pow2(), pt(2, e, s, c), e.pow2()) ).toConst(), l = be(t, d.sub(o)), h = U(u).equal(U(0, i)).any().select(0.5, 1); r.addAssign(l.mul(h).mul(a)); }), r; }), $o = /* @__PURE__ */ k({ name: "computeTransmittanceToTopAtmosphereBoundary", type: qt, inputs: [ { name: "parameters", type: J }, { name: "radius", type: H }, { name: "cosView", type: q } ] })(([n, t, e]) => { const { rayleighDensity: s, rayleighScattering: o, mieDensity: i, mieExtinction: a, absorptionDensity: r, absorptionExtinction: u } = j(n), c = Ze( n, s, t, e ), d = Ze( n, i, t, e ), l = Ze( n, r, t, e ), h = Ct( o.mul(c), a.mul(d), u.mul(l) ).toConst(); return he(h.negate()); }), Ho = /* @__PURE__ */ k({ // BUG: Cannot access vector component inside struct in layout function // https://github.com/mrdoob/three.js/issues/33345 typeOnly: !0, name: "getParamsFromTransmittanceTextureUV", type: "vec2", inputs: [ { name: "parameters", type: J }, { name: "uv", type: "vec2" } ] })(([n, t]) => { const { topRadius: e, bottomRadius: s, transmittanceTextureSize: o } = j(n), i = Dt( t.x, o.x ), a = Dt( t.y, o.y ), r = _(e.pow2().sub(s.pow2())).toConst(), u = r.mul(a).toConst(), c = _(u.pow2().add(s.pow2())), d = e.sub(c).toConst(), l = u.add(r), h = d.add(i.mul(l.sub(d))).toConst(), m = h.equal(0).select( 1, r.pow2().sub(u.pow2()).sub(h.pow2()).div(pt(2, c, h)) ); return U(c, m); }), gn = /* @__PURE__ */ W( (n) => (t) => { const e = Nt(t), { parametersNode: s } = e, { transmittanceTextureSize: o } = s, i = Ho( s, n.div(o) ).toConst(), a = i.x, r = i.y; return $o( s, a, r ); } ), Xo = /* @__PURE__ */ k({ // BUG: Cannot access vector component inside struct in layout function // https://github.com/mrdoob/three.js/issues/33345 typeOnly: !0, name: "getParamsFromIrradianceTextureUV", type: "vec2", inputs: [ { name: "parameters", type: J }, { name: "uv", type: "vec2" } ] })(([n, t]) => { const { topRadius: e, bottomRadius: s, irradianceTextureSize: o } = j(n), i = Dt( t.x, o.x ), a = Dt(t.y, o.y), r = s.add(a.mul(e.sub(s))), u = Tt(i.mul(2).sub(1)); return U(r, u); }), xn = /* @__PURE__ */ W( (n, t, e) => (s) => { const o = Nt(s), { parametersNode: i } = o, { miePhaseFunctionG: a, irradianceTextureSize: r } = i, u = Xo( i, e.div(r) ).toConst(), c = u.x, d = u.y, l = 32, h = Math.PI / l, m = Math.PI / l, p = E(0).toVar(), y = E( _(d.pow2().oneMinus()), 0, d ).toConst(); return wt({ start: 0, end: l / 2, name: "j" }, ({ j: g }) => { const S = P(g).add(0.5).mul(m).toConst(); wt({ start: 0, end: l * 2 }, ({ i: x }) => { const T = P(x).add(0.5).mul(h).toConst(), C = E( It(T).mul(Vt(S)), Vt(T).mul(Vt(S)), It(S) ).toConst(), f = Vt(S).mul(m * h), M = C.dot(y), N = Zt( i, n, n, c, C.z, d, M, _t(!1) ); let b = E(0); o.parameters.higherOrderScatteringTexture && (b = ze( t, c, C.z, d, M, _t(!1) )); const A = N.get("scattering"), z = N.get( "singleMieScattering" ), L = ge(M), R = Ue(a, M); p.addAssign( A.mul(L).add(z.mul(R)).add(b).mul(C.z, f) ); }); }), p; } ); function $e(n) { const t = new Ht(1, 1, { depthBuffer: !1, format: Bt }), e = t.texture; return e.minFilter = X, e.magFilter = X, e.colorSpace = De, e.generateMipmaps = !1, e.name = n, t; } function He(n) { const t = new Qn(1, 1, 1, { depthBuffer: !1, format: Bt }), e = t.texture; return e.minFilter = X, e.magFilter = X, e.colorSpace = De, e.generateMipmaps = !1, e.name = n, t; } function Xe(n, t, e) { n.texture.type = t, n.setSize(e.x, e.y); } function Ke(n, t, e) { n.texture.type = t, n.setSize(e.x, e.y, e.z), n.texture.isArrayTexture = !1; } class Ko extends on { } class Qo extends an { constructor() { super(), this.mesh = new Kt(), this.layer = O(0), this.mesh.name = "AtmosphereLUTTexturesWebGL", this.transmittanceRT = $e("transmittance"), this.multipleScatteringRT = $e("multipleScattering"), this.scatteringRT = He("scattering"), this.singleMieScatteringRT = He("singleMieScattering"), this.higherOrderScatteringRT = He("higherOrderScattering"), this.irradianceRT = $e("irradiance"); } get(t) { return this[`${t}RT`].texture; } createContext() { return rt(this.parameters != null), rt(this.textureType != null), new Ko( this.parameters, this.textureType ); } renderToRenderTarget(t, e, s) { s != null && e.textures.push(...s.filter((o) => o != null)), t.setRenderTarget(e), this.mesh.render(t), e.textures.length = 1; } renderToRenderTarget3D(t, e, s, o) { o != null && e.textures.push(...o.filter((i) => i != null)); for (let i = 0; i < e.depth; ++i) s.value = i, t.setRenderTarget(e, i), this.mesh.render(t); e.textures.length = 1; } // eslint-disable-next-line @typescript-eslint/class-methods-use-this createMaterial(t) { const e = new vt(); return e.fragmentNode = t, e.needsUpdate = !0, e; } computeTransmittance(t, e) { this.transmittanceMaterial?.dispose(), this.transmittanceMaterial = this.createMaterial( // BUG: Context is not merged unless we wrap the node by OutputStructNode. we({ transmittance: gn(at).context({ getAtmosphere: () => e }) }) ), this.mesh.material = this.transmittanceMaterial, this.renderToRenderTarget(t, this.transmittanceRT); } computeMultipleScattering(t, e) { const { parameters: s, parametersNode: o } = e, i = 64, a = W((u) => { const c = P(u), d = c.mul(2 * Math.PI / ((1 + Math.sqrt(5)) / 2)), l = qs( c.add(0.5).mul(2 / i).oneMinus() ), h = It(l), m = Vt(l), p = It(d), y = Vt(d); return E(p.mul(m), y.mul(m), h); }), r = Y(() => { const u = U(s.multipleScatteringTextureSize), c = ln( at.div(u), u ).toConst(), { topRadius: d, bottomRadius: l } = o, h = c.x.mul(2).sub(1).toConst(), m = E( 0, _(h.pow2().oneMinus().saturate()), h ).toConst(), p = 0, y = l.add( c.y.add(p).saturate().mul(d.sub(l).sub(p)) ).toConst(), g = E(0).toVar(), S = E(0).toVar(); return wt({ start: 0, end: i }, ({ i: x }) => { const T = a(x).toConst(), C = T.z, f = T.dot(m).toConst(), M = mn( o, Gt(this.transmittanceRT.texture), y, C, h, f ).context({ getAtmosphere: () => e }).toConst(); g.addAssign( M.get("multipleScattering").div(i) ), S.addAssign( M.get("transferFactor").div(i) ); }), g.mul( S.oneMinus().reciprocal() ); }); this.multipleScatteringMaterial?.dispose(), this.multipleScatteringMaterial = this.createMaterial( // BUG: Context is not merged unless we wrap the node by // OutputStructNode. we({ multipleScattering: w(r(), 1) }) ), this.mesh.material = this.multipleScatteringMaterial, this.renderToRenderTarget(t, this.multipleScatteringRT); } computeScattering(t, e) { const { parameters: s } = e; this.scatteringMaterial?.dispose(), this.scatteringMaterial = this.createMaterial( (() => { const i = pn( Gt(this.transmittanceRT.texture), Gt(this.multipleScatteringRT.texture), E(at, this.layer.add(0.5)) ).context({ getAtmosphere: () => e }).toConst(), a = i.get("scattering"), r = i.get("singleMieScattering"), u = i.get("higherOrderScattering"), c = {}; return s.combinedScatteringTextures ? c.scattering = w(a, r.r) : (c.scattering = w(a, r.r), c.singleMieScattering = w(r, 1)), s.higherOrderScatteringTexture && (c.higherOrderScattering = w(u, 1)), we(c); })() ), this.mesh.material = this.scatteringMaterial; const o = []; s.combinedScatteringTextures || o.push(this.singleMieScatteringRT.texture), s.higherOrderScatteringTexture && o.push(this.higherOrderScatteringRT.texture), this.renderToRenderTarget3D( t, this.scatteringRT, this.layer, o ); } computeIrradiance(t, e) { this.irradianceMaterial?.dispose(), this.irradianceMaterial = this.createMaterial( // BUG: Context is not merged unless we wrap the node by OutputStructNode. we({ irradiance: xn( Ee(this.scatteringRT.texture), Ee(this.higherOrderScatteringRT.texture), at ).context({ getAtmosphere: () => e }) }) ), this.mesh.material = this.irradianceMaterial, this.renderToRenderTarget(t, this.irradianceRT); } setup(t, e) { Xe( this.transmittanceRT, e, t.transmittanceTextureSize ), Xe( this.multipleScatteringRT, e, t.multipleScatteringTextureSize ), Ke( this.scatteringRT, e, t.scatteringTextureSize ), t.combinedScatteringTextures || Ke( this.singleMieScatteringRT, e, t.scatteringTextureSize ), t.higherOrderScatteringTexture && Ke( this.higherOrderScatteringRT, e, t.scatteringTextureSize ), Xe( this.irradianceRT, e, t.irradianceTextureSize ), super.setup(t, e); } dispose() { this.transmittanceRT.dispose(), this.multipleScatteringRT.dispose(), this.scatteringRT.dispose(), this.irradianceRT.dispose(), this.transmittanceMaterial?.dispose(), this.multipleScatteringMaterial?.dispose(), this.scatteringMaterial?.dispose(), this.irradianceMaterial?.dispose(), this.mesh.geometry.dispose(), super.dispose(); } } function Qe(n) { const t = new To(1, 1); return t.minFilter = X, t.magFilter = X, t.colorSpace = De, t.generateMipmaps = !1, t.name = n, t; } function Ye(n) { const t = new Co(1, 1, 1); return t.minFilter = X, t.magFilter = X, t.colorSpace = De, t.generateMipmaps = !1, t.name = n, t; } function _e(n, t, e) { n.type = t, hs(n.image), n.image.width = e.x, n.image.height = e.y; } function je(n, t, e) { n.type = t, hs(n.image), n.image.width = e.x, n.image.height = e.y, n.image.depth = e.z; } class Yo extends on { } class _o extends an { constructor() { super(), this.transmittance = Qe("transmittance"), this.multipleScattering = Qe("multipleScattering"), this.scattering = Ye("scattering"), this.singleMieScattering = Ye("singleMieScattering"), this.higherOrderScattering = Ye("higherOrderScattering"), this.irradiance = Qe("irradiance"); } get(t) { return this[t]; } createContext() { return rt(this.parameters != null), rt(this.textureType != null), new Yo( this.parameters, this.textureType ); } computeTransmittance(t, e) { const { parameters: s } = e, { x: o, y: i } = s.transmittanceTextureSize; this.transmittanceNode?.dispose(), this.transmittanceNode = Y(() => { const a = Mt(o, i); D(st.xy.greaterThanEqual(a).any(), () => { fe(); }); const r = gn( U(st.xy).add(0.5) ); kt(this.transmittance, st.xy, r); })().context({ getAtmosphere: () => e }).computeKernel([8, 8, 1]).setName("transmittance"), t.compute(this.transmittanceNode, [ Math.ceil(o / 8), Math.ceil(i / 8), 1 ]); } computeMultipleScattering(t, e) { const { parameters: s, parametersNode: o } = e, { x: i, y: a } = s.multipleScatteringTextureSize, r = 64, u = W((c) => { const d = P(c), l = d.mul(2 * Math.PI / ((1 + Math.sqrt(5)) / 2)), h = qs( d.add(0.5).mul(2 / r).oneMinus() ), m = It(h), p = Vt(h), y = It(l), g = Vt(l); return E(y.mul(p), g.mul(p), m); }); this.multipleScatteringNode?.dispose(), this.multipleScatteringNode = Y(() => { const c = fs("vec3", r), d = fs("vec3", r), l = U(i, a).toConst(), h = U(st.xy).add(0.5), m = ln(h.div(l), l).toConst(), p = st.z, { topRadius: y, bottomRadius: g } = o, S = m.x.mul(2).sub(1).toConst(), x = E( 0, _(S.pow2().oneMinus().saturate()), S ).toConst(), T = 0, C = g.add( m.y.add(T).saturate().mul(y.sub(g).sub(T)) ).toConst(), f = u(p).toConst(), M = f.z, N = f.dot(x).toConst(), b = mn( o, Gt(this.transmittance), C, M, S, N ).toConst(); c.element(p).assign(b.get("multipleScattering").div(r)), d.element(p).assign(b.get("transferFactor").div(r)), vs(); for (let L = r >> 1; L > 0; L >>>= 1) { const R = Q(L); D(p.lessThan(R), () => { c.element(p).addAssign(c.element(p.add(R))), d.element(p).addAssign(d.element(p.add(R))); }), vs(); } D(p.greaterThan(0), () => { fe(); }); const A = c.element(Q(0)), z = d.element(Q(0)); kt( this.multipleScattering, st.xy, // This represents the amount of radiance scattered as if the integral // of scattered radiance over the sphere would be 1. // For a power-series, such integral is analytically: // sum_{n=0}^{n=+inf} = 1 + r + r^2 + r^3 + ... + r^n = 1 / (1 - r) w(A.mul(z.oneMinus().reciprocal()), 1) ); })().context({ getAtmosphere: () => e }).computeKernel([1, 1, r]).setName("multipleScattering"), t.compute(this.multipleScatteringNode, [i, a, 1]); } computeScattering(t, e) { const { parameters: s } = e, { x: o, y: i, z: a } = s.scatteringTextureSize; this.scatteringNode?.dispose(), this.scatteringNode = Y(() => { const r = In(o, i, a); D(st.greaterThanEqual(r).any(), () => { fe(); }); const u = pn( Gt(this.transmittance), Gt(this.multipleScattering), E(st).add(0.5) ).toConst(), c = u.get("scattering"), d = u.get("singleMieScattering"); if (s.combinedScatteringTextures ? kt( this.scattering, st, w(c, d.r) ) : (kt(this.scattering, st, w(c, 1)), kt( this.singleMieScattering, st, w(d, 1) )), s.higherOrderScatteringTexture) { const l = u.get("higherOrderScattering"); kt( this.higherOrderScattering, st, w(l, 1) ); } })().context({ getAtmosphere: () => e }).computeKernel([4, 4, 4]).setName("scattering"), t.compute(this.scatteringNode, [ Math.ceil(o / 4), Math.ceil(i / 4), Math.ceil(a / 4) ]); } computeIrradiance(t, e) { const { parameters: s } = e, { x: o, y: i } = s.irradianceTextureSize; this.irradianceNode?.dispose(), this.irradianceNode = Y(() => { const a = Mt(o, i); D(st.xy.greaterThanEqual(a).any(), () => { fe(); }); const r = xn( Ee(this.scattering), Ee(this.higherOrderScattering), U(st.xy).add(0.5) ); kt(this.irradiance, st.xy, r); })().context({ getAtmosphere: () => e }).computeKernel([8, 8, 1]).setName("irradiance"), t.compute(this.irradianceNode, [ Math.ceil(o / 8), Math.ceil(i / 8), 1 ]); } setup(t, e) { _e( this.transmittance, e, t.transmittanceTextureSize ), _e( this.multipleScattering, e, t.multipleScatteringTextureSize ), je( this.scattering, e, t.scatteringTextureSize ), t.combinedScatteringTextures || je( this.singleMieScattering, e, t.scatteringTextureSize ), t.higherOrderScatteringTexture && je( this.higherOrderScattering, e, t.scatteringTextureSize ), _e( this.irradiance, e, t.irradianceTextureSize ), super.setup(t, e); } dispose() { this.transmittance.dispose(), this.multipleScattering.dispose(), this.scattering.dispose(), this.singleMieScattering.dispose(), this.higherOrderScattering.dispose(), this.irradiance.dispose(), this.transmittanceNode?.dispose(), this.multipleScatteringNode?.dispose(), this.scatteringNode?.dispose(), this.irradianceNode?.dispose(), super.dispose(); } } class Lt { constructor(t = 0, e = 0, s = 0, o = 0, i = 0) { this.width = t, this.expTerm = e, this.expScale = s, this.linearTerm = o, this.constantTerm = i; } copy(t) { return this.width = t.width, this.expTerm = t.expTerm, this.expScale = t.expScale, this.linearTerm = t.linearTerm, this.constantTerm = t.constantTerm, this; } clone() { return new Lt().copy(this); } } class ce { constructor(t) { this.layers = t; } copy(t) { return this.layers = [t.layers[0].clone(), t.layers[1].clone()], this; } clone() { return new ce([this.layers[0].clone(), this.layers[1].clone()]); } } const jo = /* @__PURE__ */ new nt(0.2126, 0.7152, 0.0722); class Ie { constructor() { this.worldToUnit = 1e-3, this.solarIrradiance = new nt(1.474, 1.8504, 1.91198), this.sunAngularRadius = 4675e-6, this.bottomRadius = 636e4, this.topRadius = 642e4, this.rayleighDensity = new ce([ new Lt(), new Lt(0, 1, -1 / 8e3) ]), this.rayleighScattering = new nt(5802e-9, 13558e-9, 331e-7), this.mieDensity = new ce([ new Lt(), new Lt(0, 1, -1 / 1200) ]), this.mieScattering = new nt().setScalar(3996e-9), this.mieExtinction = new nt().setScalar(444e-8), this.miePhaseFunctionG = 0.8, this.absorptionDensity = new ce([ new Lt(25e3, 0, 0, 1 / 15e3, -2 / 3), new Lt(0, 0, 0, -1 / 15e3, 8 / 3) ]), this.absorptionExtinction = new nt(65e-8, 1881e-9, 85e-9), this.groundAlbedo = new nt().setScalar(0.3), this.minCosLight = Math.cos(Ys(120)), this.sunRadianceToLuminance = new nt(98242.786222, 69954.398112, 66475.012354), this.skyRadianceToLuminance = new nt(114974.91644, 71305.954816, 65310.548555), this.luminanceScale = 1 / jo.dot(this.sunRadianceToLuminance), this.combinedScatteringTextures = !0, this.higherOrderScatteringTexture = !0, this.transmittanceTextureSize = new zt(256, 64), this.irradianceTextureSize = new zt(64, 16), this.multipleScatteringTextureSize = new zt(64, 64), this.scatteringTextureRadiusSize = 32, this.scatteringTextureCosViewSize = 128, this.scatteringTextureCosLightSize = 32, this.scatteringTextureCosViewLightSize = 8, this.scatteringTextureSize = new nt(), this.update(); } copy(t) { return this.worldToUnit = t.worldToUnit, this.solarIrradiance.copy(t.solarIrradiance), this.sunAngularRadius = t.sunAngularRadius, this.bottomRadius = t.bottomRadius, this.topRadius = t.topRadius, this.rayleighDensity.copy(t.rayleighDensity), this.rayleighScattering.copy(t.rayleighScattering), this.mieDensity.copy(t.mieDensity), this.mieScattering.copy(t.mieScattering), this.mieExtinction.copy(t.mieExtinction), this.miePhaseFunctionG = t.miePhaseFunctionG, this.absorptionDensity.copy(t.absorptionDensity), this.absorptionExtinction.copy(t.absorptionExtinction), this.groundAlbedo.copy(t.groundAlbedo), this.minCosLight = t.minCosLight, this.sunRadianceToLuminance.copy(t.sunRadianceToLuminance), this.skyRadianceToLuminance.copy(t.skyRadianceToLuminance), this.luminanceScale = t.luminanceScale, this.combinedScatteringTextures = t.combinedScatteringTextures, this.transmittanceTextureSize.copy(t.transmittanceTextureSize), this.irradianceTextureSize.copy(t.irradianceTextureSize), this.multipleScatteringTextureSize.copy(t.multipleScatteringTextureSize), this.scatteringTextureRadiusSize = t.scatteringTextureRadiusSize, this.scatteringTextureCosViewSize = t.scatteringTextureCosViewSize, this.scatteringTextureCosLightSize = t.scatteringTextureCosLightSize, this.scatteringTextureCosViewLightSize = t.scatteringTextureCosViewLightSize, this.scatteringTextureSize.copy(t.scatteringTextureSize), this; } update() { return this.scatteringTextureSize.set( this.scatteringTextureCosViewLightSize * this.scatteringTextureCosLightSize, this.scatteringTextureCosViewSize, this.scatteringTextureRadiusSize ), this; } clone() { return new Ie().copy(this); } /** @deprecated Use minCosLight */ get minCosSun() { return this.minCosLight; } /** @deprecated Use minCosLight */ set minCosSun(t) { this.minCosLight = t; } /** @deprecated Use scatteringTextureCosLightSize */ get scatteringTextureCosSunSize() { return this.scatteringTextureCosLightSize; } /** @deprecated Use scatteringTextureCosLightSize */ set scatteringTextureCosSunSize(t) { this.scatteringTextureCosLightSize = t; } /** @deprecated Use scatteringTextureCosViewLightSize */ get scatteringTextureCosViewSunSize() { return this.scatteringTextureCosViewLightSize; } /** @deprecated Use scatteringTextureCosViewLightSize */ set scatteringTextureCosViewSunSize(t) { this.scatteringTextureCosViewLightSize = t; } /** @deprecated This option was removed. */ // eslint-disable-next-line @typescript-eslint/class-methods-use-this get transmittancePrecisionLog() { return !1; } /** @deprecated This option was removed. */ // eslint-disable-next-line @typescript-eslint/class-methods-use-this set transmittancePrecisionLog(t) { } } const { resetRendererState: Jo, restoreRendererState: ti } = Ot; async function ei(n) { const t = n[Symbol.iterator](); return await new Promise((e, s) => { const o = () => { try { const { value: i, done: a } = t.next(); a === !0 ? e(i) : Vs(o); } catch (i) { s(i instanceof Error ? i : new Error()); } }; Vs(o); }); } let Je; function ve(n, t) { return Je = Jo(n, Je), n.setClearColor(0, 0), n.autoClear = !1, t(), ti(n, Je), !0; } const ts = /* @__PURE__ */ new Yn(), es = /* @__PURE__ */ (() => { const n = new _n(new Uint8Array(4)); return n.format = Bt, n.needsUpdate = !0, n; })(), si = { type: "update" }; class ni extends wo { constructor(t = new Ie(), e) { super(null), this.textureNodes = { transmittance: ft(this, ts), multipleScattering: ft(this, ts), scattering: Ge(this, es), singleMieScattering: Ge(this, es), higherOrderScattering: Ge(this, es), irradiance: ft(this, ts) }, this.updating = !1, this.updateBeforeType = gt.FRAME, this.parameters = t, this.textureType = e; } static get type() { return "AtmosphereLUTNode"; } getTextureNode(t) { return this.textureNodes[t]; } dispatchUpdate() { this.dispatchEvent( // @ts-expect-error Cannot specify the events map si ); } *performCompute(t, e) { const { textures: s } = this; rt(s != null), yield ve(t, () => { s.computeTransmittance(t, e), this.dispatchUpdate(); }), yield ve(t, () => { s.computeMultipleScattering(t, e), this.dispatchUpdate();