@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
50 lines (42 loc) • 2.83 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{betaRayleigh as e,betaCombined as a,betaMie as t}from"./atmosphereUtils.js";import{ChapmanApproximation as i}from"./ChapmanApproximation.glsl.js";import{Float3BindUniform as l}from"../webgl-engine/core/shaderModules/Float3BindUniform.js";import{If as r,glsl as o}from"../webgl-engine/core/shaderModules/glsl.js";function s(s,c){s.include(i);const p=6;s.uniforms.add(new l("cameraPosition",(e=>e.camera.eye))),s.constants.add("betaRayleigh","vec3",e),s.constants.add("betaCombined","vec3",a),s.constants.add("betaMie","float",t),s.code.add(o`
vec3 raymarchAtmosphere(vec3 cameraPos, vec3 rayDir, vec3 lightDir, float terrainDepth) {
vec4 ray = planetIntersect(cameraPos, rayDir);
if(ray.x == 1.0) {
return vec3(0);
}
${r(c,"if (terrainDepth != -1.0) { ray.w = terrainDepth; }")}
vec3 samplePoint = cameraPos + rayDir * ray.w;
float multiplier = ray.y == 1.0 ? -1.0 : 1.0;
vec3 scattering = vec3(0);
float scaleFract = (length(samplePoint) - radii[0]) / scaleHeight;
float lastOpticalDepth = getOpticalDepth(samplePoint, rayDir, scaleFract);
float stepSize = (ray.w - ray.z) / ${o.float(p)};
for (int i = 0; i < ${o.int(p)}; i++) {
samplePoint -= stepSize * rayDir;
scaleFract = (length(samplePoint) - radii[0]) / scaleHeight;
float opticalDepth = multiplier * getOpticalDepth(samplePoint, rayDir * multiplier, scaleFract);
if (i > 0) {
scattering *= exp(-(mix(betaCombined, betaRayleigh, 0.5) + betaMie) * max(0.0, (opticalDepth - lastOpticalDepth)));
${r(!c,"scattering *= mix(2.5, 1.0, clamp((length(cameraPos) - radii[0]) / 50e3, 0.0, 1.0))")};
}
if (dot(normalize(samplePoint), lightDir) > -0.3) {
float scale = exp(-scaleFract);
float lightDepth = getOpticalDepth(samplePoint, lightDir, scaleFract);
scattering += scale * exp(-(betaCombined + betaMie) * lightDepth);
${r(!c,"scattering += scale * exp(-(0.25 * betaCombined ) * lightDepth);")}
}
lastOpticalDepth = opticalDepth;
}
float mu = dot(rayDir, lightDir);
float mumu = 1.0 + mu * mu;
float phaseRayleigh = 0.0596831 * mumu;
${c?"return 3.0 * scattering * stepSize * phaseRayleigh * betaRayleigh;":o`const float g = 0.8;
const float gg = g * g;
float phaseMie = 0.1193662 * ((1.0 - gg) * mumu) / (pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg));
phaseMie = clamp(phaseMie, 0.0, 128.0);
return 3.0 * scattering * stepSize * (phaseRayleigh * betaRayleigh + 0.025 * phaseMie * betaMie);`}
}`)}export{s as ChapmanRaymarching};