@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
38 lines (37 loc) • 2.67 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import{create as e}from"../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{create as t}from"../../../core/libs/gl-matrix-2/factories/vec4f64.js";import{earth as r}from"../../../geometry/support/Ellipsoid.js";import{Float2PassUniform as a}from"../webgl-engine/core/shaderModules/Float2PassUniform.js";import{Float4PassUniform as s}from"../webgl-engine/core/shaderModules/Float4PassUniform.js";import{glsl as i}from"../webgl-engine/core/shaderModules/glsl.js";import{NoParameters as o}from"../../webgl/NoParameters.js";class c extends o{constructor(){super(...arguments),this.radii=e(),this.heightParameters=t()}}function n(e){e.uniforms.add(new a("radii",(e=>e.radii)),new s("heightParameters",(e=>e.heightParameters))),e.constants.add("scaleHeight","float",r.scaleHeight*r.atmosphereHeight),e.code.add(i`float chapmanApproximation(float thickness, float height, float cosZenith) {
float c = sqrt(thickness + height);
float cExpH = c * exp(-height);
if (cosZenith >= 0.0) {
return cExpH / (c * cosZenith + 1.0);
} else {
float x0 = sqrt(1.0 - cosZenith * cosZenith) * (thickness + height);
float c0 = sqrt(x0);
return 2.0 * c0 * exp(thickness - x0) - cExpH / (1.0 - c * cosZenith);
}
}`),e.code.add(i`float getOpticalDepth(vec3 position, vec3 dir, float h) {
return scaleHeight * chapmanApproximation(radii[0] / scaleHeight, h, dot(normalize(position), dir));
}`),e.code.add(i`vec4 planetIntersect(vec3 cameraPos, vec3 rayDir) {
float reducedPlanetRadius = radii[0] - 20000.0;
float rayPlanetDistance = heightParameters[1] - reducedPlanetRadius * reducedPlanetRadius;
vec2 rayPlanetIntersect = sphereIntersect(cameraPos, rayDir, rayPlanetDistance);
vec2 rayAtmosphereIntersect = sphereIntersect(cameraPos, rayDir, heightParameters[2]);
bool hitsAtmosphere = (rayAtmosphereIntersect.x <= rayAtmosphereIntersect.y) && rayAtmosphereIntersect.x > 0.0;
bool insideAtmosphere = heightParameters[0] < radii[1];
if (!(hitsAtmosphere || insideAtmosphere)) {
return vec4(1.0, 0.0, 0.0, 0.0);
}
bool hitsPlanet = (rayPlanetIntersect.x <= rayPlanetIntersect.y) && rayPlanetIntersect.x > 0.0;
float start = insideAtmosphere ? 0.0 : rayAtmosphereIntersect.x;
if (heightParameters[0] < reducedPlanetRadius) {
if (dot(rayDir, normalize(cameraPos)) < -0.025) {
return vec4(1.0, 0.0, 0.0, 0.0);
}
start = rayPlanetIntersect.y;
}
float end = hitsPlanet ? rayPlanetIntersect.x : rayAtmosphereIntersect.y;
return vec4(0.0, hitsPlanet ? 1.0 : 0.0, start, end);
}`)}export{n as ChapmanApproximation,c as ChapmanApproximationParameters};