@takram/three-atmosphere
Version:
A Three.js and R3F implementation of Precomputed Atmospheric Scattering
1,384 lines (1,305 loc) • 156 kB
JavaScript
import { BlendFunction as Jt, Effect as Qt, EffectAttribute as en, Pass as tn, Selection as nn, RenderPass as rn, DepthCopyPass as Ze, ClearPass as an, DepthMaskMaterial as on, DepthTestStrategy as sn, ShaderPass as cn } from "postprocessing";
import { Vector3 as p, Color as ae, Uniform as d, Camera as St, Vector2 as oe, Matrix4 as D, RawShaderMaterial as vt, Quaternion as un, HalfFloatType as k, MeshBasicMaterial as ln, DepthTexture as dn, UnsignedIntType as hn, WebGLRenderTarget as Et, RedFormat as mn, RGBADepthPacking as X0, LessEqualDepth as fn, BasicDepthPacking as gn, Matrix3 as w0, Mesh as pn, PlaneGeometry as Tn, Scene as Sn, FloatType as _e, GLSL3 as He, CustomBlending as vn, NoBlending as En, AddEquation as Je, OneFactor as Y0, RGBAFormat as Rt, LinearFilter as D0, ClampToEdgeWrapping as U0, NoColorSpace as _t, WebGL3DRenderTarget as Rn, Loader as _n, Data3DTexture as ge, DataTexture as Qe, LightProbe as xn, BufferGeometry as Mn, InterleavedBuffer as et, InterleavedBufferAttribute as pe, Sphere as An, DirectionalLight as wn } from "three";
import { radians as xt, Ellipsoid as F0, define as w, defineInt as yn, unrollLoops as Cn, resolveIncludes as W, Geodetic as Dn, saturate as In, remap as Pn, reinterpretType as be, clamp as tt, isTypedArray as nt, Float16Array as Mt, isFloatLinearSupported as At, EXR3DTextureLoader as Te, EXRTextureLoader as rt, DataTextureLoader as O0, parseFloat16Array as L0 } from "@takram/three-geospatial";
import { vogelDisk as Nn, interleavedGradientNoise as On, cascadedShadowMaps as Ln, raySphereIntersection as wt, transform as Hn, math as bn, packing as Un, depth as yt } from "@takram/three-geospatial/shaders";
import { M as ee, j as h0, T as m0, g as Ue, d as Ge, e as Fe, f as ze, b as f0, I as g0, k as ke, l as Gn, S as s0, c as c0, h as u0, r as it } from "./shared2.js";
import { c as Ve, a as K, _ as $, b as S0 } from "./shared3.js";
const Fn = /* @__PURE__ */ new p(0.2126, 0.7152, 0.0722), zn = [
"solarIrradiance",
"sunAngularRadius",
"bottomRadius",
"topRadius",
"rayleighDensity",
"rayleighScattering",
"mieDensity",
"mieScattering",
"mieExtinction",
"miePhaseFunctionG",
"absorptionDensity",
"absorptionExtinction",
"groundAlbedo",
"muSMin",
"skyRadianceToLuminance",
"sunRadianceToLuminance"
];
function kn(n, e) {
if (e != null)
for (const t of zn) {
const r = e[t];
r != null && (n[t] instanceof p ? n[t].copy(r) : n[t] = r);
}
}
class v0 {
constructor(e, t, r, i, a) {
this.width = e, this.expTerm = t, this.expScale = r, this.linearTerm = i, this.constantTerm = a;
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
toUniform() {
return new d({
width: this.width,
exp_term: this.expTerm,
exp_scale: this.expScale,
linear_term: this.linearTerm,
constant_term: this.constantTerm
});
}
}
const ie = class ie {
constructor(e) {
this.solarIrradiance = new p(1.474, 1.8504, 1.91198), this.sunAngularRadius = 4675e-6, this.bottomRadius = 636e4, this.topRadius = 642e4, this.rayleighDensity = [
new v0(0, 0, 0, 0, 0),
new v0(0, 1, -0.125, 0, 0)
], this.rayleighScattering = new p(5802e-6, 0.013558, 0.0331), this.mieDensity = [
new v0(0, 0, 0, 0, 0),
new v0(0, 1, -0.833333, 0, 0)
], this.mieScattering = new p(3996e-6, 3996e-6, 3996e-6), this.mieExtinction = new p(444e-5, 444e-5, 444e-5), this.miePhaseFunctionG = 0.8, this.absorptionDensity = [
new v0(25, 0, 0, 1 / 15, -2 / 3),
new v0(0, 0, 0, -1 / 15, 8 / 3)
], this.absorptionExtinction = new p(65e-5, 1881e-6, 85e-6), this.groundAlbedo = new ae().setScalar(0.1), this.muSMin = Math.cos(xt(120)), this.sunRadianceToLuminance = new p(98242.786222, 69954.398112, 66475.012354), this.skyRadianceToLuminance = new p(114974.916437, 71305.954816, 65310.548555), this.sunRadianceToRelativeLuminance = new p(), this.skyRadianceToRelativeLuminance = new p(), kn(this, e);
const t = Fn.dot(this.sunRadianceToLuminance);
this.sunRadianceToRelativeLuminance.copy(this.sunRadianceToLuminance).divideScalar(t), this.skyRadianceToRelativeLuminance.copy(this.skyRadianceToLuminance).divideScalar(t);
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
toUniform() {
return new d({
solar_irradiance: this.solarIrradiance,
sun_angular_radius: this.sunAngularRadius,
bottom_radius: this.bottomRadius * ee,
top_radius: this.topRadius * ee,
rayleigh_density: {
layers: this.rayleighDensity.map((e) => e.toUniform().value)
},
rayleigh_scattering: this.rayleighScattering,
mie_density: {
layers: this.mieDensity.map((e) => e.toUniform().value)
},
mie_scattering: this.mieScattering,
mie_extinction: this.mieExtinction,
mie_phase_function_g: this.miePhaseFunctionG,
absorption_density: {
layers: this.absorptionDensity.map((e) => e.toUniform().value)
},
absorption_extinction: this.absorptionExtinction,
ground_albedo: this.groundAlbedo,
mu_s_min: this.muSMin
});
}
};
ie.DEFAULT = /* @__PURE__ */ new ie();
let n0 = ie;
const Vn = `precision highp sampler2DArray;
#include "core/depth"
#include "core/math"
#include "core/packing"
#include "core/transform"
#ifdef HAS_SHADOW
#include "core/raySphereIntersection"
#include "core/cascadedShadowMaps"
#include "core/interleavedGradientNoise"
#include "core/vogelDisk"
#endif // HAS_SHADOW
#include "bruneton/definitions"
uniform AtmosphereParameters ATMOSPHERE;
uniform vec3 SUN_SPECTRAL_RADIANCE_TO_LUMINANCE;
uniform vec3 SKY_SPECTRAL_RADIANCE_TO_LUMINANCE;
uniform sampler2D transmittance_texture;
uniform sampler3D scattering_texture;
uniform sampler2D irradiance_texture;
uniform sampler3D single_mie_scattering_texture;
uniform sampler3D higher_order_scattering_texture;
#include "bruneton/common"
#include "bruneton/runtime"
uniform sampler2D normalBuffer;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 inverseProjectionMatrix;
uniform mat4 inverseViewMatrix;
uniform float bottomRadius;
uniform mat4 worldToECEFMatrix;
uniform float geometricErrorCorrectionAmount;
uniform vec3 sunDirection;
uniform float cosSunAngularRadius;
uniform vec3 moonDirection;
uniform float moonAngularRadius;
uniform float lunarRadianceScale;
uniform float albedoScale;
#include "sky"
#ifdef HAS_LIGHTING_MASK
uniform sampler2D lightingMaskBuffer;
#endif // HAS_LIGHTING_MASK
// prettier-ignore
#define LIGHTING_MASK_CHANNEL_ LIGHTING_MASK_CHANNEL
#ifdef HAS_OVERLAY
uniform sampler2D overlayBuffer;
#endif // HAS_OVERLAY
#ifdef HAS_SHADOW
uniform sampler2DArray shadowBuffer;
uniform vec2 shadowIntervals[SHADOW_CASCADE_COUNT];
uniform mat4 shadowMatrices[SHADOW_CASCADE_COUNT];
uniform mat4 inverseShadowMatrices[SHADOW_CASCADE_COUNT];
uniform float shadowFar;
uniform float shadowTopHeight;
uniform float shadowRadius;
uniform sampler3D stbnTexture;
uniform int frame;
#endif // HAS_SHADOW
#ifdef HAS_SHADOW_LENGTH
uniform sampler2D shadowLengthBuffer;
#endif // HAS_SHADOW_LENGTH
varying vec3 vCameraPosition;
varying vec3 vRayDirection;
varying vec3 vGeometryAltitudeCorrection;
varying vec3 vEllipsoidRadiiSquared;
vec3 readNormal(const vec2 uv, out bool degenerate) {
vec3 normal = texture(normalBuffer, uv).xyz;
degenerate = normal == vec3(0.0);
#ifdef OCT_ENCODED_NORMAL
return unpackVec2ToNormal(normal.xy);
#else // OCT_ENCODED_NORMAL
return 2.0 * normal - 1.0;
#endif // OCT_ENCODED_NORMAL
}
void correctGeometricError(inout vec3 positionECEF, inout vec3 normalECEF) {
// TODO: The error is pronounced at the edge of the ellipsoid due to the
// large difference between the sphere position and the unprojected position
// at the current fragment. Calculating the sphere position from the fragment
// UV may resolve this.
// Correct way is slerp, but this will be small-angle interpolation anyways.
vec3 sphereNormal = normalize(positionECEF / vEllipsoidRadiiSquared);
vec3 spherePosition = ATMOSPHERE.bottom_radius * sphereNormal;
normalECEF = mix(normalECEF, sphereNormal, geometricErrorCorrectionAmount);
positionECEF = mix(positionECEF, spherePosition, geometricErrorCorrectionAmount);
}
#if defined(SUN_LIGHT) || defined(SKY_LIGHT)
vec3 getSunSkyIrradiance(
const vec3 positionECEF,
const vec3 normal,
const vec3 inputColor,
const float sunTransmittance
) {
// Assume lambertian BRDF. If both SUN_LIGHT and SKY_LIGHT are not defined,
// regard the inputColor as radiance at the texel.
vec3 diffuse = inputColor * albedoScale * RECIPROCAL_PI;
vec3 skyIrradiance;
vec3 sunIrradiance = GetSunAndSkyIrradiance(positionECEF, normal, sunDirection, skyIrradiance);
#ifdef HAS_SHADOW
sunIrradiance *= sunTransmittance;
#endif // HAS_SHADOW
#if defined(SUN_LIGHT) && defined(SKY_LIGHT)
return diffuse * (sunIrradiance + skyIrradiance);
#elif defined(SUN_LIGHT)
return diffuse * sunIrradiance;
#elif defined(SKY_LIGHT)
return diffuse * skyIrradiance;
#endif // defined(SUN_LIGHT) && defined(SKY_LIGHT)
}
#endif // defined(SUN_LIGHT) || defined(SKY_LIGHT)
#if defined(TRANSMITTANCE) || defined(INSCATTER)
void applyTransmittanceInscatter(const vec3 positionECEF, float shadowLength, inout vec3 radiance) {
vec3 transmittance;
vec3 inscatter = GetSkyRadianceToPoint(
vCameraPosition,
positionECEF,
shadowLength,
sunDirection,
transmittance
);
#ifdef TRANSMITTANCE
radiance = radiance * transmittance;
#endif // TRANSMITTANCE
#ifdef INSCATTER
radiance = radiance + inscatter;
#endif // INSCATTER
}
#endif // defined(TRANSMITTANCE) || defined(INSCATTER)
#ifdef HAS_SHADOW
float getSTBN() {
ivec3 size = textureSize(stbnTexture, 0);
vec3 scale = 1.0 / vec3(size);
return texture(stbnTexture, vec3(gl_FragCoord.xy, float(frame % size.z)) * scale).r;
}
vec2 getShadowUv(const vec3 worldPosition, const int cascadeIndex) {
vec4 clip = shadowMatrices[cascadeIndex] * vec4(worldPosition, 1.0);
clip /= clip.w;
return clip.xy * 0.5 + 0.5;
}
float getDistanceToShadowTop(const vec3 positionECEF) {
// Distance to the top of the shadows along the sun direction, which matches
// the ray origin of BSM.
return raySphereSecondIntersection(
positionECEF / METER_TO_LENGTH_UNIT, // TODO: Make units consistent
sunDirection,
vec3(0.0),
bottomRadius + shadowTopHeight
);
}
float readShadowOpticalDepth(const vec2 uv, const float distanceToTop, const int cascadeIndex) {
// r: frontDepth, g: meanExtinction, b: maxOpticalDepth, a: maxOpticalDepthTail
vec4 shadow = texture(shadowBuffer, vec3(uv, float(cascadeIndex)));
// Omit adding maxOpticalDepthTail to avoid pronounced aliasing. Ground
// shadow will be attenuated by inscatter anyways.
return min(shadow.b, shadow.g * max(0.0, distanceToTop - shadow.r));
}
float sampleShadowOpticalDepthPCF(
const vec3 worldPosition,
const float distanceToTop,
const float radius,
const int cascadeIndex
) {
vec2 uv = getShadowUv(worldPosition, cascadeIndex);
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
return 0.0;
}
vec2 texelSize = vec2(1.0) / vec2(textureSize(shadowBuffer, 0).xy);
float sum = 0.0;
vec2 offset;
#pragma unroll_loop_start
for (int i = 0; i < 16; ++i) {
#if UNROLLED_LOOP_INDEX < SHADOW_SAMPLE_COUNT
offset = vogelDisk(
UNROLLED_LOOP_INDEX,
SHADOW_SAMPLE_COUNT,
interleavedGradientNoise(gl_FragCoord.xy) * PI2
);
sum += readShadowOpticalDepth(uv + offset * radius * texelSize, distanceToTop, cascadeIndex);
#endif // UNROLLED_LOOP_INDEX < SHADOW_SAMPLE_COUNT
}
#pragma unroll_loop_end
return sum / float(SHADOW_SAMPLE_COUNT);
}
float sampleShadowOpticalDepth(
const vec3 worldPosition,
const vec3 positionECEF,
const float radius,
const float jitter
) {
float distanceToTop = getDistanceToShadowTop(positionECEF);
if (distanceToTop <= 0.0) {
return 0.0;
}
int cascadeIndex = getFadedCascadeIndex(
viewMatrix,
worldPosition,
shadowIntervals,
cameraNear,
shadowFar,
jitter
);
return cascadeIndex >= 0
? sampleShadowOpticalDepthPCF(worldPosition, distanceToTop, radius, cascadeIndex)
: 0.0;
}
float getShadowRadius(const vec3 worldPosition) {
vec4 clip = shadowMatrices[0] * vec4(worldPosition, 1.0);
clip /= clip.w;
// Offset by 1px in each direction in shadow's clip coordinates.
vec2 shadowSize = vec2(textureSize(shadowBuffer, 0));
vec3 offset = vec3(2.0 / shadowSize, 0.0);
vec4 clipX = clip + offset.xzzz;
vec4 clipY = clip + offset.zyzz;
// Convert back to world space.
vec4 worldX = inverseShadowMatrices[0] * clipX;
vec4 worldY = inverseShadowMatrices[0] * clipY;
// Project into the main camera's clip space.
mat4 viewProjectionMatrix = projectionMatrix * viewMatrix;
vec4 projected = viewProjectionMatrix * vec4(worldPosition, 1.0);
vec4 projectedX = viewProjectionMatrix * worldX;
vec4 projectedY = viewProjectionMatrix * worldY;
projected /= projected.w;
projectedX /= projectedX.w;
projectedY /= projectedY.w;
// Take the mean of pixel sizes.
vec2 center = (projected.xy * 0.5 + 0.5) * resolution;
vec2 offsetX = (projectedX.xy * 0.5 + 0.5) * resolution;
vec2 offsetY = (projectedY.xy * 0.5 + 0.5) * resolution;
float size = max(length(offsetX - center), length(offsetY - center));
return remapClamped(size, 10.0, 50.0, 0.0, shadowRadius);
}
#endif // HAS_SHADOW
void mainImage(const vec4 inputColor, const vec2 uv, out vec4 outputColor) {
#if defined(HAS_LIGHTING_MASK) && defined(DEBUG_SHOW_LIGHTING_MASK)
outputColor.rgb = vec3(texture(lightingMaskBuffer, uv).LIGHTING_MASK_CHANNEL_);
outputColor.a = 1.0;
return;
#endif // defined(HAS_LIGHTING_MASK) && defined(DEBUG_SHOW_LIGHTING_MASK)
float shadowLength = 0.0;
#ifdef HAS_SHADOW_LENGTH
shadowLength = texture(shadowLengthBuffer, uv).r;
#endif // HAS_SHADOW_LENGTH
#ifdef HAS_OVERLAY
vec4 overlay = texture(overlayBuffer, uv);
if (overlay.a == 1.0) {
outputColor = overlay;
return;
}
#endif // HAS_OVERLAY
vec3 rayDirection = normalize(vRayDirection);
vec3 dRDdx = dFdx(rayDirection);
vec3 dRDdy = dFdy(rayDirection);
float fragmentAngle = length(dRDdx + dRDdy) / length(rayDirection);
float depth = readDepthValue(depthBuffer, uv);
if (depth >= 1.0 - 1e-8) {
#ifdef SKY
outputColor.rgb = getSkyRadiance(
vCameraPosition,
rayDirection,
shadowLength,
sunDirection,
moonDirection,
moonAngularRadius,
lunarRadianceScale,
fragmentAngle
);
outputColor.a = 1.0;
#else // SKY
outputColor = inputColor;
#endif // SKY
#ifdef HAS_OVERLAY
outputColor.rgb = outputColor.rgb * (1.0 - overlay.a) + overlay.rgb;
#endif // HAS_OVERLAY
return;
}
depth = reverseLogDepth(depth, cameraNear, cameraFar);
// Reconstruct position and normal in world space.
vec3 viewPosition = screenToView(
uv,
depth,
getViewZ(depth),
projectionMatrix,
inverseProjectionMatrix
);
vec3 worldPosition = (inverseViewMatrix * vec4(viewPosition, 1.0)).xyz;
vec3 positionECEF = (worldToECEFMatrix * vec4(worldPosition, 1.0)).xyz;
positionECEF = positionECEF * METER_TO_LENGTH_UNIT + vGeometryAltitudeCorrection;
vec3 viewNormal;
bool degenerateNormal = false;
#ifdef RECONSTRUCT_NORMAL
vec3 dVPdx = dFdx(viewPosition);
vec3 dVPdy = dFdy(viewPosition);
viewNormal = normalize(cross(dVPdx, dVPdy));
#elif defined(HAS_NORMALS)
viewNormal = readNormal(uv, degenerateNormal);
#endif // defined(HAS_NORMALS)
#if defined(RECONSTRUCT_NORMAL) || defined(HAS_NORMALS)
vec3 worldNormal = (inverseViewMatrix * vec4(viewNormal, 0.0)).xyz;
vec3 normalECEF = (worldToECEFMatrix * vec4(worldNormal, 0.0)).xyz;
#else // defined(RECONSTRUCT_NORMAL) || defined(HAS_NORMALS)
vec3 normalECEF = normalize(positionECEF);
#endif // defined(RECONSTRUCT_NORMAL) || defined(HAS_NORMALS)
#ifdef CORRECT_GEOMETRIC_ERROR
correctGeometricError(positionECEF, normalECEF);
#endif // CORRECT_GEOMETRIC_ERROR
#ifdef HAS_SHADOW
float stbn = getSTBN();
float radius = getShadowRadius(worldPosition);
float opticalDepth = sampleShadowOpticalDepth(worldPosition, positionECEF, radius, stbn);
float sunTransmittance = exp(-opticalDepth);
#else // HAS_SHADOW
float sunTransmittance = 1.0;
#endif // HAS_SHADOW
vec3 radiance;
#if defined(SUN_LIGHT) || defined(SKY_LIGHT)
// WORKAROUND: When both post-process lighting and sky options are enabled,
// stars have degenerate normals. We use this to disable irradiance, which is
// irrelevant for them.
if (!degenerateNormal) {
radiance = getSunSkyIrradiance(positionECEF, normalECEF, inputColor.rgb, sunTransmittance);
} else {
radiance = inputColor.rgb;
}
#ifdef HAS_LIGHTING_MASK
float lightingMask = texture(lightingMaskBuffer, uv).LIGHTING_MASK_CHANNEL_;
radiance = mix(inputColor.rgb, radiance, lightingMask);
#endif // HAS_LIGHTING_MASK
#else // defined(SUN_LIGHT) || defined(SKY_LIGHT)
radiance = inputColor.rgb;
#endif // defined(SUN_LIGHT) || defined(SKY_LIGHT)
#if defined(TRANSMITTANCE) || defined(INSCATTER)
applyTransmittanceInscatter(positionECEF, shadowLength, radiance);
#endif // defined(TRANSMITTANCE) || defined(INSCATTER)
outputColor = vec4(radiance, inputColor.a);
#ifdef HAS_OVERLAY
outputColor.rgb = outputColor.rgb * (1.0 - overlay.a) + overlay.rgb;
#endif // HAS_OVERLAY
}
`, Bn = `uniform mat4 inverseViewMatrix;
uniform mat4 inverseProjectionMatrix;
uniform vec3 cameraPosition;
uniform mat4 worldToECEFMatrix;
uniform vec3 altitudeCorrection;
uniform float geometricErrorCorrectionAmount;
uniform vec3 ellipsoidRadii;
varying vec3 vCameraPosition;
varying vec3 vRayDirection;
varying vec3 vGeometryAltitudeCorrection;
varying vec3 vEllipsoidRadiiSquared;
void getCameraRay(out vec3 origin, out vec3 direction) {
bool isPerspective = inverseProjectionMatrix[2][3] != 0.0; // 4th entry in the 3rd column
if (isPerspective) {
// Calculate the camera ray for a perspective camera.
vec4 viewPosition = inverseProjectionMatrix * vec4(position, 1.0);
vec4 worldDirection = inverseViewMatrix * vec4(viewPosition.xyz, 0.0);
origin = cameraPosition;
direction = worldDirection.xyz;
} else {
// Unprojected points to calculate direction.
vec4 nearPoint = inverseProjectionMatrix * vec4(position.xy, -1.0, 1.0);
vec4 farPoint = inverseProjectionMatrix * vec4(position.xy, -0.9, 1.0);
nearPoint /= nearPoint.w;
farPoint /= farPoint.w;
// Calculate world values.
vec4 worldDirection = inverseViewMatrix * vec4(farPoint.xyz - nearPoint.xyz, 0.0);
vec4 worldOrigin = inverseViewMatrix * nearPoint;
// Outputs
direction = worldDirection.xyz;
origin = worldOrigin.xyz;
}
}
void mainSupport() {
vec3 direction, origin;
getCameraRay(origin, direction);
vec3 cameraPositionECEF = (worldToECEFMatrix * vec4(origin, 1.0)).xyz;
vCameraPosition = (cameraPositionECEF + altitudeCorrection) * METER_TO_LENGTH_UNIT;
vRayDirection = (worldToECEFMatrix * vec4(direction, 0.0)).xyz;
vGeometryAltitudeCorrection = altitudeCorrection * METER_TO_LENGTH_UNIT;
// Gradually turn off the altitude correction on geometries as the geometric
// error correction takes effect, because that on the ideal sphere will be
// over corrected.
// See: https://github.com/takram-design-engineering/three-geospatial/pull/23#issuecomment-2542914656
#ifdef CORRECT_GEOMETRIC_ERROR
vGeometryAltitudeCorrection *= 1.0 - geometricErrorCorrectionAmount;
#endif // CORRECT_GEOMETRIC_ERROR
vec3 radii = ellipsoidRadii * METER_TO_LENGTH_UNIT;
vEllipsoidRadiiSquared = radii * radii;
}
`, Ct = `vec3 getLunarRadiance(const float moonAngularRadius) {
// Not a physical number but the order of 10^-6 relative to the sun may fit.
vec3 radiance =
ATMOSPHERE.solar_irradiance *
0.000002 /
(PI * moonAngularRadius * moonAngularRadius) *
SUN_SPECTRAL_RADIANCE_TO_LUMINANCE;
return radiance;
}
float intersectSphere(const vec3 ray, const vec3 point, const float radius) {
vec3 P = -point;
float PoR = dot(P, ray);
float D = dot(P, P) - radius * radius;
return -PoR - sqrt(PoR * PoR - D);
}
float orenNayarDiffuse(const vec3 L, const vec3 V, const vec3 N) {
float NoL = dot(N, L);
float NoV = dot(N, V);
float s = dot(L, V) - NoL * NoV;
float t = mix(1.0, max(NoL, NoV), step(0.0, s));
return max(0.0, NoL) * (0.62406015 + 0.41284404 * s / t);
}
vec3 getSkyRadiance(
const vec3 cameraPosition,
const vec3 rayDirection,
const float shadowLength,
const vec3 sunDirection,
const vec3 moonDirection,
const float moonAngularRadius,
const float lunarRadianceScale,
const float fragmentAngle
) {
vec3 transmittance;
vec3 radiance = GetSkyRadiance(
cameraPosition,
rayDirection,
shadowLength,
sunDirection,
transmittance
);
// Rendering celestial objects without perspective doesn't make sense.
#ifdef PERSPECTIVE_CAMERA
#ifdef SUN
float viewDotSun = dot(rayDirection, sunDirection);
if (viewDotSun > cosSunAngularRadius) {
float angle = acos(clamp(viewDotSun, -1.0, 1.0));
float antialias = smoothstep(
ATMOSPHERE.sun_angular_radius,
ATMOSPHERE.sun_angular_radius - fragmentAngle,
angle
);
radiance += transmittance * GetSolarRadiance() * antialias;
}
#endif // SUN
#ifdef MOON
float intersection = intersectSphere(rayDirection, moonDirection, moonAngularRadius);
if (intersection > 0.0) {
vec3 normal = normalize(moonDirection - rayDirection * intersection);
float diffuse = orenNayarDiffuse(-sunDirection, rayDirection, normal);
float viewDotMoon = dot(rayDirection, moonDirection);
float angle = acos(clamp(viewDotMoon, -1.0, 1.0));
float antialias = smoothstep(moonAngularRadius, moonAngularRadius - fragmentAngle, angle);
radiance +=
transmittance *
getLunarRadiance(moonAngularRadius) *
lunarRadianceScale *
diffuse *
antialias;
}
#endif // MOON
#endif // PERSPECTIVE_CAMERA
return radiance;
}
`;
var Wn = Object.defineProperty, L = (n, e, t, r) => {
for (var i = void 0, a = n.length - 1, o; a >= 0; a--)
(o = n[a]) && (i = o(e, t, i) || i);
return i && Wn(e, t, i), i;
};
const jn = /* @__PURE__ */ new p(), Xn = /* @__PURE__ */ new p(), Yn = /* @__PURE__ */ new Dn(), Kn = {
blendFunction: Jt.NORMAL,
octEncodedNormal: !1,
reconstructNormal: !1,
ellipsoid: F0.WGS84,
correctAltitude: !0,
correctGeometricError: !0,
sunLight: !1,
skyLight: !1,
transmittance: !0,
inscatter: !0,
albedoScale: 1,
sky: !1,
sun: !0,
moon: !0,
moonAngularRadius: 45e-4,
// ≈ 15.5 arcminutes
lunarRadianceScale: 1,
ground: !0
};
class H extends Qt {
constructor(e = new St(), t, r = n0.DEFAULT) {
const {
blendFunction: i,
normalBuffer: a = null,
octEncodedNormal: o,
reconstructNormal: c,
irradianceTexture: s = null,
scatteringTexture: l = null,
transmittanceTexture: h = null,
singleMieScatteringTexture: m = null,
higherOrderScatteringTexture: f = null,
ellipsoid: v,
correctAltitude: T,
correctGeometricError: E,
sunDirection: x,
sunLight: y,
skyLight: I,
transmittance: N,
inscatter: b,
albedoScale: U,
sky: z,
sun: F,
moon: q,
moonDirection: Z,
moonAngularRadius: i0,
lunarRadianceScale: a0,
ground: J
} = { ...Kn, ...t };
super(
"AerialPerspectiveEffect",
Cn(
W(Vn, {
core: {
depth: yt,
packing: Un,
math: bn,
transform: Hn,
raySphereIntersection: wt,
cascadedShadowMaps: Ln,
interleavedGradientNoise: On,
vogelDisk: Nn
},
bruneton: {
common: $,
definitions: K,
runtime: Ve
},
sky: Ct
})
),
{
blendFunction: i,
vertexShader: Bn,
attributes: en.DEPTH,
// prettier-ignore
uniforms: new Map(
Object.entries({
normalBuffer: new d(a),
projectionMatrix: new d(new D()),
viewMatrix: new d(new D()),
inverseProjectionMatrix: new d(new D()),
inverseViewMatrix: new d(new D()),
cameraPosition: new d(new p()),
bottomRadius: new d(r.bottomRadius),
ellipsoidRadii: new d(new p()),
worldToECEFMatrix: new d(new D()),
altitudeCorrection: new d(new p()),
geometricErrorCorrectionAmount: new d(0),
sunDirection: new d(x?.clone() ?? new p()),
cosSunAngularRadius: new d(r.sunAngularRadius),
albedoScale: new d(U),
moonDirection: new d(Z?.clone() ?? new p()),
moonAngularRadius: new d(i0),
lunarRadianceScale: new d(a0),
// Composition and shadow
overlayBuffer: new d(null),
shadowBuffer: new d(null),
shadowMapSize: new d(new oe()),
shadowIntervals: new d([]),
shadowMatrices: new d([]),
inverseShadowMatrices: new d([]),
shadowFar: new d(0),
shadowTopHeight: new d(0),
shadowRadius: new d(3),
stbnTexture: new d(null),
frame: new d(0),
shadowLengthBuffer: new d(null),
// Lighting mask
lightingMaskBuffer: new d(null),
// Uniforms for atmosphere functions
ATMOSPHERE: r.toUniform(),
SUN_SPECTRAL_RADIANCE_TO_LUMINANCE: new d(r.sunRadianceToRelativeLuminance),
SKY_SPECTRAL_RADIANCE_TO_LUMINANCE: new d(r.skyRadianceToRelativeLuminance),
irradiance_texture: new d(s),
scattering_texture: new d(l),
transmittance_texture: new d(h),
single_mie_scattering_texture: new d(null),
higher_order_scattering_texture: new d(null)
})
),
// prettier-ignore
defines: /* @__PURE__ */ new Map([
["TRANSMITTANCE_TEXTURE_WIDTH", h0.toFixed(0)],
["TRANSMITTANCE_TEXTURE_HEIGHT", m0.toFixed(0)],
["SCATTERING_TEXTURE_R_SIZE", Ue.toFixed(0)],
["SCATTERING_TEXTURE_MU_SIZE", Ge.toFixed(0)],
["SCATTERING_TEXTURE_MU_S_SIZE", Fe.toFixed(0)],
["SCATTERING_TEXTURE_NU_SIZE", ze.toFixed(0)],
["IRRADIANCE_TEXTURE_WIDTH", f0.toFixed(0)],
["IRRADIANCE_TEXTURE_HEIGHT", g0.toFixed(0)],
["METER_TO_LENGTH_UNIT", ee.toFixed(7)]
])
}
), this.camera = e, this.atmosphere = r, this.overlay = null, this.shadow = null, this.shadowLength = null, this.lightingMask = null, this.hasNormals = !1, this.combinedScatteringTextures = !1, this.hasHigherOrderScatteringTexture = !1, this.shadowSampleCount = 8, this.octEncodedNormal = o, this.reconstructNormal = c, this.singleMieScatteringTexture = m, this.higherOrderScatteringTexture = f, this.ellipsoid = v, this.correctAltitude = T, this.correctGeometricError = E, this.sunLight = y, this.skyLight = I, this.transmittance = N, this.inscatter = b, this.sky = z, this.sun = F, this.moon = q, this.ground = J;
}
get mainCamera() {
return this.camera;
}
set mainCamera(e) {
this.camera = e;
}
copyCameraSettings(e) {
const {
projectionMatrix: t,
matrixWorldInverse: r,
projectionMatrixInverse: i,
matrixWorld: a
} = e, o = this.uniforms;
o.get("projectionMatrix").value.copy(t), o.get("viewMatrix").value.copy(r), o.get("inverseProjectionMatrix").value.copy(i), o.get("inverseViewMatrix").value.copy(a);
const c = e.getWorldPosition(
o.get("cameraPosition").value
), s = o.get("worldToECEFMatrix").value, l = jn.copy(c).applyMatrix4(s);
try {
const m = Yn.setFromECEF(l).height, f = Xn.set(0, this.ellipsoid.maximumRadius, -Math.max(0, m)).applyMatrix4(t);
o.get("geometricErrorCorrectionAmount").value = In(
Pn(f.y, 41.5, 13.8, 0, 1)
);
} catch {
return;
}
const h = o.get("altitudeCorrection");
this.correctAltitude ? ke(
l,
this.atmosphere.bottomRadius,
this.ellipsoid,
h.value
) : h.value.setScalar(0);
}
updateOverlay() {
let e = !1;
const { uniforms: t, defines: r, overlay: i } = this, a = r.has("HAS_OVERLAY"), o = i != null;
return o !== a && (o ? r.set("HAS_OVERLAY", "1") : (r.delete("HAS_OVERLAY"), t.get("overlayBuffer").value = null), e = !0), o && (t.get("overlayBuffer").value = i.map), e;
}
updateShadow() {
let e = !1;
const { uniforms: t, defines: r, shadow: i } = this, a = r.has("HAS_SHADOW"), o = i != null;
if (o !== a && (o ? r.set("HAS_SHADOW", "1") : (r.delete("HAS_SHADOW"), t.get("shadowBuffer").value = null), e = !0), o) {
const c = r.get("SHADOW_CASCADE_COUNT"), s = `${i.cascadeCount}`;
c !== s && (r.set("SHADOW_CASCADE_COUNT", i.cascadeCount.toFixed(0)), e = !0), t.get("shadowBuffer").value = i.map, t.get("shadowMapSize").value = i.mapSize, t.get("shadowIntervals").value = i.intervals, t.get("shadowMatrices").value = i.matrices, t.get("inverseShadowMatrices").value = i.inverseMatrices, t.get("shadowFar").value = i.far, t.get("shadowTopHeight").value = i.topHeight;
}
return e;
}
updateShadowLength() {
let e = !1;
const { uniforms: t, defines: r, shadowLength: i } = this, a = r.has("HAS_SHADOW_LENGTH"), o = i != null;
return o !== a && (o ? r.set("HAS_SHADOW_LENGTH", "1") : (r.delete("HAS_SHADOW_LENGTH"), t.get("shadowLengthBuffer").value = null), e = !0), o && (t.get("shadowLengthBuffer").value = i.map), e;
}
updateLightingMask() {
let e = !1;
const { uniforms: t, defines: r, lightingMask: i } = this, a = r.has("HAS_LIGHTING_MASK"), o = i != null;
if (o !== a && (o ? r.set("HAS_LIGHTING_MASK", "1") : (r.delete("HAS_LIGHTING_MASK"), t.get("lightingMaskBuffer").value = null), e = !0), o) {
t.get("lightingMaskBuffer").value = i.map;
const c = r.get("LIGHTING_MASK_CHANNEL"), s = i.channel;
s !== c && (/^[rgba]$/.test(s) ? (r.set("LIGHTING_MASK_CHANNEL", s), e = !0) : console.error(`Expression validation failed: ${s}`));
}
return e;
}
update(e, t, r) {
this.copyCameraSettings(this.camera);
let i = !1;
i ||= this.updateOverlay(), i ||= this.updateShadow(), i ||= this.updateShadowLength(), i ||= this.updateLightingMask(), i && this.setChanged(), ++this.uniforms.get("frame").value;
}
get normalBuffer() {
return this.uniforms.get("normalBuffer").value;
}
set normalBuffer(e) {
this.uniforms.get("normalBuffer").value = e, this.hasNormals = e != null;
}
get irradianceTexture() {
return this.uniforms.get("irradiance_texture").value;
}
set irradianceTexture(e) {
this.uniforms.get("irradiance_texture").value = e;
}
get scatteringTexture() {
return this.uniforms.get("scattering_texture").value;
}
set scatteringTexture(e) {
this.uniforms.get("scattering_texture").value = e;
}
get transmittanceTexture() {
return this.uniforms.get("transmittance_texture").value;
}
set transmittanceTexture(e) {
this.uniforms.get("transmittance_texture").value = e;
}
get singleMieScatteringTexture() {
return this.uniforms.get("single_mie_scattering_texture").value;
}
set singleMieScatteringTexture(e) {
this.uniforms.get("single_mie_scattering_texture").value = e, this.combinedScatteringTextures = e == null;
}
get higherOrderScatteringTexture() {
return this.uniforms.get("higher_order_scattering_texture").value;
}
set higherOrderScatteringTexture(e) {
this.uniforms.get("higher_order_scattering_texture").value = e, this.hasHigherOrderScatteringTexture = e != null;
}
get ellipsoid() {
return this._ellipsoid;
}
set ellipsoid(e) {
this._ellipsoid = e, this.uniforms.get("ellipsoidRadii").value.copy(e.radii);
}
get worldToECEFMatrix() {
return this.uniforms.get("worldToECEFMatrix").value;
}
get sunDirection() {
return this.uniforms.get("sunDirection").value;
}
get sunAngularRadius() {
return this.uniforms.get("ATMOSPHERE").value.sun_angular_radius;
}
set sunAngularRadius(e) {
this.uniforms.get("ATMOSPHERE").value.sun_angular_radius = e, this.uniforms.get("cosSunAngularRadius").value = Math.cos(e);
}
get albedoScale() {
return this.uniforms.get("albedoScale").value;
}
set albedoScale(e) {
this.uniforms.get("albedoScale").value = e;
}
get moonDirection() {
return this.uniforms.get("moonDirection").value;
}
get moonAngularRadius() {
return this.uniforms.get("moonAngularRadius").value;
}
set moonAngularRadius(e) {
this.uniforms.get("moonAngularRadius").value = e;
}
get lunarRadianceScale() {
return this.uniforms.get("lunarRadianceScale").value;
}
set lunarRadianceScale(e) {
this.uniforms.get("lunarRadianceScale").value = e;
}
get stbnTexture() {
return this.uniforms.get("stbnTexture").value;
}
set stbnTexture(e) {
this.uniforms.get("stbnTexture").value = e;
}
get shadowRadius() {
return this.uniforms.get("shadowRadius").value;
}
set shadowRadius(e) {
this.uniforms.get("shadowRadius").value = e;
}
}
L([
w("OCT_ENCODED_NORMAL")
], H.prototype, "octEncodedNormal");
L([
w("RECONSTRUCT_NORMAL")
], H.prototype, "reconstructNormal");
L([
w("HAS_NORMALS")
], H.prototype, "hasNormals");
L([
w("COMBINED_SCATTERING_TEXTURES")
], H.prototype, "combinedScatteringTextures");
L([
w("HAS_HIGHER_ORDER_SCATTERING_TEXTURE")
], H.prototype, "hasHigherOrderScatteringTexture");
L([
w("CORRECT_GEOMETRIC_ERROR")
], H.prototype, "correctGeometricError");
L([
w("SUN_LIGHT")
], H.prototype, "sunLight");
L([
w("SKY_LIGHT")
], H.prototype, "skyLight");
L([
w("TRANSMITTANCE")
], H.prototype, "transmittance");
L([
w("INSCATTER")
], H.prototype, "inscatter");
L([
w("SKY")
], H.prototype, "sky");
L([
w("SUN")
], H.prototype, "sun");
L([
w("MOON")
], H.prototype, "moon");
L([
w("GROUND")
], H.prototype, "ground");
L([
yn("SHADOW_SAMPLE_COUNT", { min: 1, max: 16 })
], H.prototype, "shadowSampleCount");
var $n = Object.defineProperty, Dt = (n, e, t, r) => {
for (var i = void 0, a = n.length - 1, o; a >= 0; a--)
(o = n[a]) && (i = o(e, t, i) || i);
return i && $n(e, t, i), i;
};
const qn = /* @__PURE__ */ new p();
function Zn(n, e) {
let t = "", r = "";
for (let i = 1; i < e; ++i)
t += `layout(location = ${i}) out float renderTarget${i};
`, r += `renderTarget${i} = 0.0;
`;
return n.replace("#include <mrt_layout>", t).replace("#include <mrt_output>", r);
}
const Be = {
ellipsoid: F0.WGS84,
correctAltitude: !0,
renderTargetCount: 1
};
class se extends vt {
constructor(e, t = n0.DEFAULT) {
const {
irradianceTexture: r = null,
scatteringTexture: i = null,
transmittanceTexture: a = null,
singleMieScatteringTexture: o = null,
higherOrderScatteringTexture: c = null,
ellipsoid: s,
correctAltitude: l,
sunDirection: h,
sunAngularRadius: m,
renderTargetCount: f,
...v
} = { ...Be, ...e };
super({
toneMapped: !1,
depthWrite: !1,
depthTest: !1,
...v,
// prettier-ignore
uniforms: {
cameraPosition: new d(new p()),
worldToECEFMatrix: new d(new D()),
altitudeCorrection: new d(new p()),
sunDirection: new d(h?.clone() ?? new p()),
cosSunAngularRadius: new d(t.sunAngularRadius),
// Uniforms for atmosphere functions
ATMOSPHERE: t.toUniform(),
SUN_SPECTRAL_RADIANCE_TO_LUMINANCE: new d(t.sunRadianceToRelativeLuminance),
SKY_SPECTRAL_RADIANCE_TO_LUMINANCE: new d(t.skyRadianceToRelativeLuminance),
irradiance_texture: new d(r),
scattering_texture: new d(i),
transmittance_texture: new d(a),
single_mie_scattering_texture: new d(null),
higher_order_scattering_texture: new d(null),
...v.uniforms
},
defines: {
PI: `${Math.PI}`,
TRANSMITTANCE_TEXTURE_WIDTH: h0.toFixed(0),
TRANSMITTANCE_TEXTURE_HEIGHT: m0.toFixed(0),
SCATTERING_TEXTURE_R_SIZE: Ue.toFixed(0),
SCATTERING_TEXTURE_MU_SIZE: Ge.toFixed(0),
SCATTERING_TEXTURE_MU_S_SIZE: Fe.toFixed(0),
SCATTERING_TEXTURE_NU_SIZE: ze.toFixed(0),
IRRADIANCE_TEXTURE_WIDTH: f0.toFixed(0),
IRRADIANCE_TEXTURE_HEIGHT: g0.toFixed(0),
METER_TO_LENGTH_UNIT: ee.toFixed(7),
...v.defines
}
}), this.atmosphere = t, this.combinedScatteringTextures = !1, this.hasHigherOrderScatteringTexture = !1, this.singleMieScatteringTexture = o, this.higherOrderScatteringTexture = c, this.ellipsoid = s, this.correctAltitude = l, m != null && (this.sunAngularRadius = m), this.renderTargetCount = f;
}
copyCameraSettings(e) {
const t = this.uniforms, r = e.getWorldPosition(
t.cameraPosition.value
), i = qn.copy(r).applyMatrix4(t.worldToECEFMatrix.value), a = t.altitudeCorrection.value;
this.correctAltitude ? ke(
i,
this.atmosphere.bottomRadius,
this.ellipsoid,
a
) : a.setScalar(0);
}
onBeforeCompile(e, t) {
e.fragmentShader = Zn(
e.fragmentShader,
this.renderTargetCount
);
}
onBeforeRender(e, t, r, i, a, o) {
this.copyCameraSettings(r);
}
get irradianceTexture() {
return this.uniforms.irradiance_texture.value;
}
set irradianceTexture(e) {
this.uniforms.irradiance_texture.value = e;
}
get scatteringTexture() {
return this.uniforms.scattering_texture.value;
}
set scatteringTexture(e) {
this.uniforms.scattering_texture.value = e;
}
get transmittanceTexture() {
return this.uniforms.transmittance_texture.value;
}
set transmittanceTexture(e) {
this.uniforms.transmittance_texture.value = e;
}
get singleMieScatteringTexture() {
return this.uniforms.single_mie_scattering_texture.value;
}
set singleMieScatteringTexture(e) {
this.uniforms.single_mie_scattering_texture.value = e, this.combinedScatteringTextures = e == null;
}
get higherOrderScatteringTexture() {
return this.uniforms.higher_order_scattering_texture.value;
}
set higherOrderScatteringTexture(e) {
this.uniforms.higher_order_scattering_texture.value = e, this.hasHigherOrderScatteringTexture = e != null;
}
get worldToECEFMatrix() {
return this.uniforms.worldToECEFMatrix.value;
}
get sunDirection() {
return this.uniforms.sunDirection.value;
}
get sunAngularRadius() {
return this.uniforms.ATMOSPHERE.value.sun_angular_radius;
}
set sunAngularRadius(e) {
this.uniforms.ATMOSPHERE.value.sun_angular_radius = e, this.uniforms.cosSunAngularRadius.value = Math.cos(e);
}
/** @package */
get renderTargetCount() {
return this._renderTargetCount;
}
/** @package */
set renderTargetCount(e) {
e !== this.renderTargetCount && (this._renderTargetCount = e, this.needsUpdate = !0);
}
}
Dt([
w("COMBINED_SCATTERING_TEXTURES")
], se.prototype, "combinedScatteringTextures");
Dt([
w("HAS_HIGHER_ORDER_SCATTERING_TEXTURE")
], se.prototype, "hasHigherOrderScatteringTexture");
/**
@preserve
Astronomy library for JavaScript (browser and Node.js).
https://github.com/cosinekitty/astronomy
MIT License
Copyright (c) 2019-2023 Don Cross <cosinekitty@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/**
* @fileoverview Astronomy calculation library for browser scripting and Node.js.
* @author Don Cross <cosinekitty@gmail.com>
* @license MIT
*/
const Jn = 173.1446326846693, It = 14959787069098932e-8, g = 0.017453292519943295, at = 57.29577951308232, Qn = 365.24217, ot = /* @__PURE__ */ new Date("2000-01-01T12:00:00Z"), X = 2 * Math.PI, e0 = 3600 * (180 / Math.PI), x0 = 484813681109536e-20, er = 10800 * 60, tr = 2 * er, nr = 6378.1366, rr = nr / It, ir = 81.30056, We = 2959122082855911e-19, xe = 2825345909524226e-22, Me = 8459715185680659e-23, Ae = 1292024916781969e-23, we = 1524358900784276e-23;
function l0(n) {
if (!Number.isFinite(n))
throw console.trace(), `Value is not a finite number: ${n}`;
return n;
}
function E0(n) {
return n - Math.floor(n);
}
var S;
(function(n) {
n.Sun = "Sun", n.Moon = "Moon", n.Mercury = "Mercury", n.Venus = "Venus", n.Earth = "Earth", n.Mars = "Mars", n.Jupiter = "Jupiter", n.Saturn = "Saturn", n.Uranus = "Uranus", n.Neptune = "Neptune", n.Pluto = "Pluto", n.SSB = "SSB", n.EMB = "EMB", n.Star1 = "Star1", n.Star2 = "Star2", n.Star3 = "Star3", n.Star4 = "Star4", n.Star5 = "Star5", n.Star6 = "Star6", n.Star7 = "Star7", n.Star8 = "Star8";
})(S || (S = {}));
const ar = [
S.Star1,
S.Star2,
S.Star3,
S.Star4,
S.Star5,
S.Star6,
S.Star7,
S.Star8
], or = [
{ ra: 0, dec: 0, dist: 0 },
{ ra: 0, dec: 0, dist: 0 },
{ ra: 0, dec: 0, dist: 0 },
{ ra: 0, dec: 0, dist: 0 },
{ ra: 0, dec: 0, dist: 0 },
{ ra: 0, dec: 0, dist: 0 },
{ ra: 0, dec: 0, dist: 0 },
{ ra: 0, dec: 0, dist: 0 }
];
function sr(n) {
const e = ar.indexOf(n);
return e >= 0 ? or[e] : null;
}
function Pt(n) {
const e = sr(n);
return e && e.dist > 0 ? e : null;
}
var V;
(function(n) {
n[n.From2000 = 0] = "From2000", n[n.Into2000 = 1] = "Into2000";
})(V || (V = {}));
const M0 = {
Mercury: [
[
[
[4.40250710144, 0, 0],
[0.40989414977, 1.48302034195, 26087.9031415742],
[0.050462942, 4.47785489551, 52175.8062831484],
[0.00855346844, 1.16520322459, 78263.70942472259],
[0.00165590362, 4.11969163423, 104351.61256629678],
[34561897e-11, 0.77930768443, 130439.51570787099],
[7583476e-11, 3.71348404924, 156527.41884944518]
],
[
[26087.90313685529, 0, 0],
[0.01131199811, 6.21874197797, 26087.9031415742],
[0.00292242298, 3.04449355541, 52175.8062831484],
[75775081e-11, 6.08568821653, 78263.70942472259],
[19676525e-11, 2.80965111777, 104351.61256629678]
]
],
[
[
[0.11737528961, 1.98357498767, 26087.9031415742],
[0.02388076996, 5.03738959686, 52175.8062831484],
[0.01222839532, 3.14159265359, 0],
[0.0054325181, 1.79644363964, 78263.70942472259],
[0.0012977877, 4.83232503958, 104351.61256629678],
[31866927e-11, 1.58088495658, 130439.51570787099],
[7963301e-11, 4.60972126127, 156527.41884944518]
],
[
[0.00274646065, 3.95008450011, 26087.9031415742],
[99737713e-11, 3.14159265359, 0]
]
],
[
[
[0.39528271651, 0, 0],
[0.07834131818, 6.19233722598, 26087.9031415742],
[0.00795525558, 2.95989690104, 52175.8062831484],
[0.00121281764, 6.01064153797, 78263.70942472259],
[21921969e-11, 2.77820093972, 104351.61256629678],
[4354065e-11, 5.82894543774, 130439.51570787099]
],
[
[0.0021734774, 4.65617158665, 26087.9031415742],
[44141826e-11, 1.42385544001, 52175.8062831484]
]
]
],
Venus: [
[
[
[3.17614666774, 0, 0],
[0.01353968419, 5.59313319619, 10213.285546211],
[89891645e-11, 5.30650047764, 20426.571092422],
[5477194e-11, 4.41630661466, 7860.4193924392],
[3455741e-11, 2.6996444782, 11790.6290886588],
[2372061e-11, 2.99377542079, 3930.2096962196],
[1317168e-11, 5.18668228402, 26.2983197998],
[1664146e-11, 4.25018630147, 1577.3435424478],
[1438387e-11, 4.15745084182, 9683.5945811164],
[1200521e-11, 6.15357116043, 30639.856638633]
],
[
[10213.28554621638, 0, 0],
[95617813e-11, 2.4640651111, 10213.285546211],
[7787201e-11, 0.6247848222, 20426.571092422]
]
],
[
[
[0.05923638472, 0.26702775812, 10213.285546211],
[40107978e-11, 1.14737178112, 20426.571092422],
[32814918e-11, 3.14159265359, 0]
],
[
[0.00287821243, 1.88964962838, 10213.285546211]
]
],
[
[
[0.72334820891, 0, 0],
[0.00489824182, 4.02151831717, 10213.285546211],
[1658058e-11, 4.90206728031, 20426.571092422],
[1378043e-11, 1.12846591367, 11790.6290886588],
[1632096e-11, 2.84548795207, 7860.4193924392],
[498395e-11, 2.58682193892, 9683.5945811164],
[221985e-11, 2.01346696541, 19367.1891622328],
[237454e-11, 2.55136053886, 15720.8387848784]
],
[
[34551041e-11, 0.89198706276, 10213.285546211]
]
]
],
Earth: [
[
[
[1.75347045673, 0, 0],
[0.03341656453, 4.66925680415, 6283.0758499914],
[34894275e-11, 4.62610242189, 12566.1516999828],
[3417572e-11, 2.82886579754, 3.523118349],
[3497056e-11, 2.74411783405, 5753.3848848968],
[3135899e-11, 3.62767041756, 77713.7714681205],
[2676218e-11, 4.41808345438, 7860.4193924392],
[2342691e-11, 6.13516214446, 3930.2096962196],
[1273165e-11, 2.03709657878, 529.6909650946],
[1324294e-11, 0.74246341673, 11506.7697697936],
[901854e-11, 2.04505446477, 26.2983197998],
[1199167e-11, 1.10962946234, 1577.3435424478],
[857223e-11, 3.50849152283, 398.1490034082],
[779786e-11, 1.17882681962, 5223.6939198022],
[99025e-10, 5.23268072088, 5884.9268465832],
[753141e-11, 2.53339052847, 5507.5532386674],
[505267e-11, 4.58292599973, 18849.2275499742],
[492392e-11, 4.20505711826, 775.522611324],
[356672e-11, 2.91954114478, 0.0673103028],
[284125e-11, 1.89869240932, 796.2980068164],
[242879e-11, 0.34481445893, 5486.777843175],
[317087e-11, 5.84901948512, 11790.6290886588],
[271112e-11, 0.31486255375, 10977.078804699],
[206217e-11, 4.80646631478, 2544.3144198834],
[205478e-11, 1.86953770281, 5573.1428014331],
[202318e-11, 2.45767790232, 6069.7767545534],
[126225e-11, 1.08295459501, 20.7753954924],
[155516e-11, 0.83306084617, 213.299095438]
],
[
[6283.0758499914, 0, 0],
[0.00206058863, 2.67823455808, 6283.0758499914],
[4303419e-11, 2.63512233481, 12566.1516999828]
],
[
[8721859e-11, 1.07253635559, 6283.0758499914]
]
],
[
[],
[
[0.00227777722, 3.4137662053, 6283.0758499914],
[3805678e-11, 3.37063423795, 12566.1516999828]
]
],
[
[
[1.00013988784, 0, 0],
[0.01670699632, 3.09846350258, 6283.0758499914],
[13956024e-11, 3.05524609456, 12566.1516999828],
[308372e-10, 5.19846674381, 77713.7714681205],
[1628463e-11, 1.17387558054, 5753.3848848968],
[1575572e-11, 2.84685214877, 7860.4193924392],
[924799e-11, 5.45292236722, 11506.7697697936],
[542439e-11, 4.56409151453, 3930.2096962196],
[47211e-10, 3.66100022149, 5884.9268465832],
[85831e-11, 1.27079125277, 161000.6857376741],
[57056e-11, 2.01374292245, 83996.84731811189],
[55736e-11, 5.2415979917, 71430.69561812909],
[174844e-11, 3.01193636733, 18849.2275499742],
[243181e-11, 4.2734953079, 11790.6290886588]
],
[
[0.00103018607, 1.10748968172, 6283.0758499914],
[1721238e-11, 1.06442300386, 12566.1516999828]
],
[
[4359385e-11, 5.78455133808, 6283.0758499914]
]
]
],
Mars: [
[
[
[6.20347711581, 0, 0],
[0.18656368093, 5.0503710027, 3340.6124266998],
[0.01108216816, 5.40099836344, 6681.2248533996],
[91798406e-11, 5.75478744667, 10021.8372800994],
[27744987e-11, 5.97049513147, 3.523118349],
[10610235e-11, 2.93958560338, 2281.2304965106],
[12315897e-11, 0.84956094002, 2810.9214616052],
[8926784e-11, 4.15697846427, 0.0172536522],
[8715691e-11, 6.11005153139, 13362.4497067992],
[6797556e-11, 0.36462229657, 398.1490034082],
[7774872e-11, 3.33968761376, 5621.8429232104],
[3575078e-11, 1.6618650571, 2544.3144198834],
[4161108e-11, 0.22814971327, 2942.4634232916],
[3075252e-11, 0.85696614132, 191.4482661116],
[2628117e-11, 0.64806124465, 3337.0893083508],
[2937546e-11, 6.07893711402, 0.0673103028],
[2389414e-11, 5.03896442664, 796.2980068164],
[2579844e-11, 0.02996736156, 3344.1355450488],
[1528141e-11, 1.14979301996, 6151.533888305],
[1798806e-11, 0.65634057445, 529.6909650946],
[1264357e-11, 3.62275122593, 5092.1519581158],
[1286228e-11, 3.06796065034, 2146.1654164752],
[1546404e-11, 2.91579701718, 1751.539531416],