Custom Gis Application with Arcgis Javascript API with modern layouting
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

224 lines
12 KiB

// All material copyright Esri, All Rights Reserved, unless otherwise specified.
// See https://js.arcgis.com/4.30/esri/copyright.txt for details.
//>>built
define("exports ../core/libs/gl-matrix-2/math/mat4 ../core/libs/gl-matrix-2/factories/mat4f64 ../core/libs/gl-matrix-2/factories/vec3f64 ../views/3d/environment/atmosphereUtils ../views/3d/webgl-engine/core/shaderLibrary/attributes/TextureCoordinateAttribute.glsl ../views/3d/webgl-engine/core/shaderLibrary/output/ReadDepth.glsl ../views/3d/webgl-engine/core/shaderLibrary/shading/Gamma.glsl ../views/3d/webgl-engine/core/shaderLibrary/shading/MainLighting.glsl ../views/3d/webgl-engine/core/shaderModules/Float2PassUniform ../views/3d/webgl-engine/core/shaderModules/Float3PassUniform ../views/3d/webgl-engine/core/shaderModules/Float4PassUniform ../views/3d/webgl-engine/core/shaderModules/FloatPassUniform ../views/3d/webgl-engine/core/shaderModules/interfaces ../views/3d/webgl-engine/core/shaderModules/Matrix4PassUniform ../views/3d/webgl-engine/core/shaderModules/ShaderBuilder ../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform ../views/3d/webgl-engine/lib/VertexAttribute".split(" "),
function(h,w,k,l,p,q,x,y,z,A,r,B,m,a,t,C,D,E){function u(c){const e=new C.ShaderBuilder;e.attributes.add(E.VertexAttribute.POSITION,"vec2");e.include(q.TextureCoordinateAttribute,{textureCoordinateType:q.TextureCoordinateAttributeType.Default});e.varyings.add("worldRay","vec3");e.varyings.add("eyeDir","vec3");const {vertex:v,fragment:d}=e;v.uniforms.add(new t.Matrix4PassUniform("inverseProjectionMatrix",(b,g)=>g.camera.inverseProjectionMatrix),new t.Matrix4PassUniform("inverseViewMatrix",(b,g)=>w.invertOrIdentity(F,
g.camera.viewMatrix)));v.code.add(a.glsl`void main(void) {
vec3 posViewNear = (inverseProjectionMatrix * vec4(position, -1, 1)).xyz;
eyeDir = posViewNear;
worldRay = (inverseViewMatrix * vec4(posViewNear, 0)).xyz;
forwardTextureCoordinates();
gl_Position = vec4(position, 1, 1);
}`);d.uniforms.add(new r.Float3PassUniform("backgroundColor",b=>b.backgroundColor),new A.Float2PassUniform("radii",b=>b.radii),new r.Float3PassUniform("cameraPosition",(b,g)=>g.camera.eye),new B.Float4PassUniform("heightParameters",b=>b.heightParameters),new m.FloatPassUniform("innerFadeDistance",b=>b.innerFadeDistance),new m.FloatPassUniform("altitudeFade",b=>b.altitudeFade),new D.Texture2DPassUniform("depthTexture",b=>b.depthTexture),new m.FloatPassUniform("hazeStrength",b=>b.hazeStrength));d.constants.add("betaRayleigh",
"vec3",f);d.constants.add("betaCombined","vec3",G);d.constants.add("betaMie","float",3.996E-6);d.constants.add("scaleHeight","float",p.rayLeighScaleHeight*p.atmosphereHeight);z.addMainLightDirection(d);e.include(y.Gamma);c.haze&&d.include(x.ReadDepth);d.code.add(a.glsl`vec2 sphereIntersect(vec3 start, vec3 dir, float radius, bool planet) {
float a = dot(dir, dir);
float b = 2.0 * dot(dir, start);
float c = planet ? heightParameters[1] - radius * radius : heightParameters[2];
float d = (b * b) - 4.0 * a * c;
if (d < 0.0) {
return vec2(1e5, -1e5);
}
return vec2((-b - sqrt(d)) / (2.0 * a), (-b + sqrt(d)) / (2.0 * a));
}`);d.code.add(a.glsl`float chapmanApproximation(float X, float h, float cosZenith) {
float c = sqrt(X + h);
float cExpH = c * exp(-h);
if (cosZenith >= 0.0) {
return cExpH / (c * cosZenith + 1.0);
} else {
float x0 = sqrt(1.0 - cosZenith * cosZenith) * (X + h);
float c0 = sqrt(x0);
return 2.0 * c0 * exp(X - x0) - cExpH / (1.0 - c * cosZenith);
}
}`);d.code.add(a.glsl`float getOpticalDepth(vec3 position, vec3 dir, float h) {
return scaleHeight * chapmanApproximation(radii[0] / scaleHeight, h, dot(normalize(position), dir));
}`);d.code.add(a.glsl`
const int STEPS = 6;
vec3 getAtmosphereColour(vec3 cameraPos, vec3 rayDir, vec3 lightDir, float terrainDepth) {
float reducedPlanetRadius = radii[0] - 20000.0;
vec2 rayPlanetIntersect = sphereIntersect(cameraPos, rayDir, reducedPlanetRadius, true);
vec2 rayAtmosphereIntersect = sphereIntersect(cameraPos, rayDir, radii[1], false);
bool hitsAtmosphere = (rayAtmosphereIntersect.x <= rayAtmosphereIntersect.y) && rayAtmosphereIntersect.x > 0.0;
bool insideAtmosphere = heightParameters[0] < radii[1];
if (!(hitsAtmosphere || insideAtmosphere)) {
return vec3(0);
}
bool hitsPlanet = (rayPlanetIntersect.x <= rayPlanetIntersect.y) && rayPlanetIntersect.x > 0.0;
float start = insideAtmosphere ? 0.0 : rayAtmosphereIntersect.x;
if (heightParameters[0] < reducedPlanetRadius) {
// Long light rays from the night side of the planet lead to numerical instability
// Do not render the atmosphere in such cases
if (dot(rayDir, normalize(cameraPos)) < -0.025) {
return vec3(0);
}
start = rayPlanetIntersect.y;
}
float end = hitsPlanet ? rayPlanetIntersect.x : rayAtmosphereIntersect.y;
float maxEnd = end;
${c.haze?a.glsl`if (terrainDepth != -1.0) { end = terrainDepth; }`:""}
vec3 samplePoint = cameraPos + rayDir * end;
float multiplier = hitsPlanet ? -1.0 : 1.0;
vec3 scattering = vec3(0);
float scaleFract = (length(samplePoint) - radii[0]) / scaleHeight;
float lastOpticalDepth = getOpticalDepth(samplePoint, rayDir, scaleFract);
float stepSize = (end - start) / float(STEPS);
for (int i = 0; i < STEPS; i++) {
samplePoint -= stepSize * rayDir;
scaleFract = (length(samplePoint) - radii[0]) / scaleHeight;
float opticalDepth = multiplier * getOpticalDepth(samplePoint, rayDir * multiplier, scaleFract);
if (i > 0) {
scattering *= ${c.haze?"":a.glsl`mix(2.5, 1.0, clamp((length(cameraPos) - radii[0]) / 50e3, 0.0, 1.0)) * `} exp(-(mix(betaCombined, betaRayleigh, 0.5) + betaMie) * max(0.0, (opticalDepth - lastOpticalDepth)));
}
if (dot(normalize(samplePoint), lightDir) > -0.3) {
float scale = exp(-scaleFract);
float lightDepth = getOpticalDepth(samplePoint, lightDir, scaleFract);
scattering += scale * exp(-(betaCombined + betaMie) * lightDepth);
${c.haze?"":a.glsl`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.haze?a.glsl`return 3.0 * scattering * stepSize * phaseRayleigh * betaRayleigh;`:a.glsl`
const float g = 0.8;
const float gg = g * g;
float phaseMie = end == maxEnd ? 0.1193662 * ((1.0 - gg) * mumu) / (pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg)) : 0.0;
phaseMie = clamp(phaseMie, 0.0, 128.0);
return 3.0 * scattering * stepSize * (phaseRayleigh * betaRayleigh + 0.025 * phaseMie * betaMie);`}
}
${c.haze?"":a.glsl`
vec4 applyUndergroundAtmosphere(vec3 rayDir, vec3 lightDirection, vec4 fragColor) {
vec2 rayPlanetIntersect = sphereIntersect(cameraPosition, rayDir, radii[0], true);
if (!((rayPlanetIntersect.x <= rayPlanetIntersect.y) && rayPlanetIntersect.y > 0.0)) {
return fragColor;
}
float lightAngle = dot(lightDirection, normalize(cameraPosition + rayDir * max(0.0, rayPlanetIntersect.x)));
vec4 surfaceColor = vec4(vec3(max(0.0, (smoothstep(-1.0, 0.8, 2.0 * lightAngle)))), 1.0 - altitudeFade);
float relDist = (rayPlanetIntersect.y - max(0.0, rayPlanetIntersect.x)) / innerFadeDistance;
if (relDist > 1.0) {
return surfaceColor;
}
return mix(fragColor, surfaceColor, smoothstep(0.0, 1.0, relDist * relDist));
}
float getGlow(float dist, float radius, float intensity) {
return pow(radius / max(dist, 1e-6), intensity);
}
vec3 getSun(vec3 cameraPos, vec3 rayDir, vec3 lightDir){
// Get the amount of atmosphere between camera and the Sun along the view ray
float scaleFract = (length(cameraPos) - radii[0]) / scaleHeight;
float sunOpticalDepth = getOpticalDepth(cameraPos, rayDir, max(scaleFract, 0.0));
// Find the amount of light that remains after travelling through the atmosphere from the Sun along the view ray
// This will make the colour of the Sun reddish on the horizon and white from space
vec3 sunTransmittance = exp(-(mix(betaCombined, betaRayleigh, 0.5)) * max(0.0, sunOpticalDepth));
// Alignment of light direction and view ray
float mu = clamp(dot(rayDir, lightDir), 0.0, 1.0);
// Draw the Sun as a bright disc
float sunDisc = 256.0 * smoothstep(0.0, 128.0, clamp(getGlow(1.0 - mu, 3e-5, 3.0), 0.0, 128.0));
return normalize(sunTransmittance) * sunDisc;
}`}
${c.haze&&c.reduced?a.glsl`
float getDepth(vec2 uv){
return linearDepthFromTexture(depthTexture, uv);
}
float textureBilinear(vec2 uv) {
// Information about the high-resolution depth texture
vec2 depthTextureSize = vec2(textureSize(depthTexture, 0));
vec2 texelSize = 1.0 / depthTextureSize;
// The uv inside the upper right pixel - of the tile of 4 pixels -
// that the atmosphere uv maps to in the depth texture
vec2 depthUV = (uv * depthTextureSize) - vec2(0.5);
// Relative distance of the uv coordinates inside the depth texture pixel
vec2 f = fract(depthUV);
// Snap to the centre of the depth texture pixel
vec2 snapUV = (floor(depthUV) + vec2(0.5)) / depthTextureSize;
// Read the depth texture pixel and its three neighbours
float d0 = getDepth(snapUV);
float d1 = getDepth(snapUV + vec2(texelSize.x, 0.0));
float d2 = getDepth(snapUV + vec2(0.0, texelSize.y));
float d3 = getDepth(snapUV + texelSize);
// Return the bilinearly interpolated value of the neighbouring pixels based
// on the sample position in the depth texture pixel
return mix(mix(d0, d1, f.x), mix(d2, d3, f.x), f.y);
}
`:""}
vec3 tonemapACES(vec3 x) {
return clamp((x * (2.51 * x + 0.03)) / (x * (2.43 * x + 0.59) + 0.14), 0.0, 1.0);
}
void main() {
vec3 rayDir = normalize(worldRay);
float terrainDepth = -1.0;
${c.haze?a.glsl`
float depthSample = texture(depthTexture, vuv0).r;
if (depthSample != 1.0) {
vec3 cameraSpaceRay = normalize(eyeDir);
cameraSpaceRay /= cameraSpaceRay.z;
${c.reduced?a.glsl`cameraSpaceRay *= -textureBilinear(vuv0);`:a.glsl`cameraSpaceRay *= -linearDepthFromTexture(depthTexture, vuv0);`}
terrainDepth = max(0.0, length(cameraSpaceRay));
}else{
discard;
}
`:a.glsl`${c.reduced?"":a.glsl`
float depthSample = texture(depthTexture, vuv0).r;
if (depthSample != 1.0) {
fragColor = vec4(0);
return;
}`}`}
${c.haze?a.glsl`
vec3 col = vec3(0);
float fadeOut = smoothstep(-10000.0, -15000.0, heightParameters[0] - radii[0]);
if(depthSample != 1.0){
col = (1.0 - fadeOut) * hazeStrength * getAtmosphereColour(cameraPosition, rayDir, mainLightDirection, terrainDepth);
}
// Alpha is ignored for haze blending
float alpha = 1.0;
`:a.glsl`
vec3 col = linearizeGamma(backgroundColor);
col += getAtmosphereColour(cameraPosition, rayDir, mainLightDirection, terrainDepth);
col += getSun(cameraPosition, rayDir, mainLightDirection);
float alpha = smoothstep(0.0, mix(0.15, 0.01, heightParameters[3]), length(col));`}
col = tonemapACES(col);
fragColor = delinearizeGamma(vec4(col, alpha));
${c.haze?"":a.glsl`fragColor = applyUndergroundAtmosphere(rayDir, mainLightDirection, fragColor);`}
}
`);return e}const f=l.fromValues(parseFloat(Number(5.802E-6).toFixed(6)),parseFloat(Number(1.3558E-5).toFixed(6)),parseFloat(Number(3.31E-5).toFixed(6))),n=l.fromValues(3*parseFloat(Number(6.5E-7).toFixed(6)),3*parseFloat(Number(1.881E-6).toFixed(6)),3*parseFloat(Number(8.5E-8).toFixed(6))),G=l.fromValues(parseFloat(Number(f[0]+n[0]).toFixed(6)),parseFloat(Number(f[1]+n[1]).toFixed(6)),parseFloat(Number(f[2]+n[2]).toFixed(6))),F=k.create();k=Object.freeze(Object.defineProperty({__proto__:null,betaRayleigh:f,
build:u},Symbol.toStringTag,{value:"Module"}));h.ChapmanAtmosphere=k;h.betaRayleigh=f;h.build=u});