UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

34 lines (33 loc) 3.04 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{clamp as e}from"../../../core/mathUtils.js";import{create as t}from"../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{squaredLength as r}from"../../../core/libs/gl-matrix-2/math/vec3.js";import{earth as s}from"../../../geometry/support/Ellipsoid.js";import{Float2PassUniform as a}from"../webgl-engine/core/shaderModules/Float2PassUniform.js";import{Float3BindUniform as i}from"../webgl-engine/core/shaderModules/Float3BindUniform.js";import{FloatsPassUniform as o}from"../webgl-engine/core/shaderModules/FloatsPassUniform.js";import{glsl as n}from"../webgl-engine/core/shaderModules/glsl.js";import{SphereIntersect as c}from"../webgl-engine/shaders/SphereIntersect.glsl.js";import{NoParameters as h}from"../../webgl/NoParameters.js";class l extends h{constructor(){super(...arguments),this.radii=t()}}function m(e){e.code.add(n`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.constants.add("scaleHeight","float",s.scaleHeight*s.atmosphereHeight).uniforms.add(new a("radii",e=>e.radii)).code.add(n`float getOpticalDepth(vec3 position, vec3 dir, float h) { return scaleHeight * chapmanApproximation(radii[0] / scaleHeight, h, dot(normalize(position), dir)); }`),e.include(c),e.constants.add("planetRadiusReduction","float",p).uniforms.add(new o("heightParameters",5,(e,t)=>d(t,e)),new i("cameraPosition",e=>e.camera.eye)).code.add(n`vec4 planetIntersect(vec3 rayDir) { float rayPlanetDistanceReduced = heightParameters[4]; vec2 rayPlanetIntersect = sphereIntersect(cameraPosition, rayDir, rayPlanetDistanceReduced); vec2 rayAtmosphereIntersect = sphereIntersect(cameraPosition, rayDir, heightParameters[1]); 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] < radii[0] - planetRadiusReduction) { if (dot(rayDir, normalize(cameraPosition)) < -0.01) { 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); }`)}function d({camera:t},{radii:a}){const i=r(t.eye),o=Math.sqrt(i);return f[0]=o,f[1]=i-a[1]**2,f[2]=e((o-a[0])/s.atmosphereHeight,0,1),f[3]=i-a[0]**2,f[4]=i-(a[0]-p)**2,f}const p=2e4,f=new Array;export{m as ChapmanApproximation,l as ChapmanApproximationPassParameters,d as getHeightParameters};