UNPKG

@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
/* 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};