UNPKG

@arcgis/core

Version:

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

50 lines (49 loc) 5.17 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.19/LICENSE.txt */ import{fromValues as o}from"../../../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{earth as t}from"../../../../../../geometry/support/Ellipsoid.js";import{cloudsHeight as a}from"../../../../environment/weather.js";import{addMainLightDirection as r,addMainLightIntensity as e}from"../shading/MainLighting.glsl.js";import{LookupCloudsFromTextureArray as i}from"./LookupCloudsFromTextureArray.glsl.js";import{BooleanBindUniform as c}from"../../shaderModules/BooleanBindUniform.js";import{Float3BindUniform as n}from"../../shaderModules/Float3BindUniform.js";import{FloatBindUniform as d}from"../../shaderModules/FloatBindUniform.js";import{glsl as l}from"../../shaderModules/glsl.js";import{Matrix4BindUniform as s}from"../../shaderModules/Matrix4BindUniform.js";import{Texture2DArrayBindUniform as u}from"../../shaderModules/Texture2DArrayBindUniform.js";function m(t){const a=t.fragment;a.constants.add("radiusCloudsSquared","float",C).code.add(l`vec3 intersectWithCloudLayer(vec3 dir, vec3 cameraPosition, vec3 spherePos) { float B = 2.0 * dot(cameraPosition, dir); float C = dot(cameraPosition, cameraPosition) - radiusCloudsSquared; float det = B * B - 4.0 * C; float pointIntDist = max(0.0, 0.5 *(-B + sqrt(det))); return (cameraPosition + dir * pointIntDist) - spherePos; }`),a.uniforms.add(new d("radiusCurvatureCorrection",({clouds:o})=>o.parallax.radiusCurvatureCorrection)).code.add(l`vec3 correctForPlanetCurvature(vec3 dir) { dir.z = dir.z * (1.0 - radiusCurvatureCorrection) + radiusCurvatureCorrection; return dir; }`),a.code.add(l`vec3 rotateDirectionToAnchorPoint(mat4 rotMat, vec3 inVec) { return (rotMat * vec4(inVec, 0.0)).xyz; }`),r(a),e(a),a.constants.add("RIM_COLOR","vec3",o(.28,.175,.035)),a.constants.add("sunsetTransitionFactor","float",.3),a.constants.add("rimScattering","float",140),a.constants.add("backlightFactor","float",.2),a.constants.add("backlightScattering","float",10),a.constants.add("backlightTransition","float",.3),a.code.add(l`vec3 calculateCloudColor(vec3 cameraPosition, vec3 worldSpaceRay, vec4 clouds) { float upDotLight = dot(cameraPosition, mainLightDirection); float dirDotLight = max(dot(worldSpaceRay, mainLightDirection), 0.0); float sunsetTransition = clamp(pow(max(upDotLight, 0.0), sunsetTransitionFactor), 0.0, 1.0); vec3 ambientLight = calculateAmbientIrradiance(cameraPosition, 0.0); vec3 combinedLight = clamp((mainLightIntensity + ambientLight )/PI, vec3(0.0), vec3(1.0)); vec3 baseCloudColor = pow(combinedLight * pow(clouds.xyz, vec3(GAMMA)), vec3(INV_GAMMA)); float scatteringMod = max(clouds.a < 0.5 ? clouds.a / 0.5 : - clouds.a / 0.5 + 2.0, 0.0); float rimLightIntensity = 0.5 + 0.5 * pow(max(upDotLight, 0.0), 0.35); vec3 directSunScattering = RIM_COLOR * rimLightIntensity * (pow(dirDotLight, rimScattering)) * scatteringMod; float additionalLight = backlightFactor * pow(dirDotLight, backlightScattering) * (1. - pow(sunsetTransition, backlightTransition)) ; return vec3(baseCloudColor * (1.0 + additionalLight) + directSunScattering); }`),t.include(i),a.uniforms.add(new c("readChannelsRG",o=>0===o.clouds.readChannels),new u("cubeMap",o=>o.clouds.data?.cubeMap?.colorTexture)).code.add(l`vec4 sampleCloud(vec3 rayDir, bool readOtherChannel) { vec4 s = lookupCloudsFromTextureArray(cubeMap, rayDir); bool readRG = readChannelsRG ^^ readOtherChannel; s = readRG ? vec4(vec3(s.r), s.g) : vec4(vec3(s.b), s.a); return length(s) == 0.0 ? vec4(s.rgb, 1.0) : s; }`),a.uniforms.add(new n("anchorPoint",o=>o.clouds.parallax.anchorPoint),new n("anchorPointNew",o=>o.clouds.parallaxNew.anchorPoint),new s("rotationClouds",o=>o.clouds.parallax.transform),new s("rotationCloudsNew",o=>o.clouds.parallaxNew.transform),new d("cloudsOpacity",o=>o.clouds.opacity),new d("fadeFactor",o=>o.clouds.fadeFactor),new c("crossFade",o=>3===o.clouds.fadeState)).code.add(l`vec4 renderClouds(vec3 worldRay, vec3 cameraPosition) { vec3 intersectionPoint = intersectWithCloudLayer(worldRay, cameraPosition, anchorPoint); vec3 worldRayRotated = rotateDirectionToAnchorPoint(rotationClouds, normalize(intersectionPoint)); vec3 worldRayRotatedCorrected = correctForPlanetCurvature(worldRayRotated); vec4 cloudData = sampleCloud(worldRayRotatedCorrected, crossFade); vec3 cameraPositionN = normalize(cameraPosition); vec4 cloudColor = vec4(calculateCloudColor(cameraPositionN, worldRay, cloudData), cloudData.a); if(crossFade) { intersectionPoint = intersectWithCloudLayer(worldRay, cameraPosition, anchorPointNew); worldRayRotated = rotateDirectionToAnchorPoint(rotationCloudsNew, normalize(intersectionPoint)); worldRayRotatedCorrected = correctForPlanetCurvature(worldRayRotated); cloudData = sampleCloud(worldRayRotatedCorrected, false); vec4 cloudColorNew = vec4(calculateCloudColor(cameraPositionN, worldRay, cloudData), cloudData.a); cloudColor = mix(cloudColor, cloudColorNew, fadeFactor); } float totalTransmittance = length(cloudColor.rgb) == 0.0 ? 1.0 : clamp(cloudColor.a * cloudsOpacity + (1.0 - cloudsOpacity), 0.0 , 1.0); return vec4(cloudColor.rgb, totalTransmittance); }`)}const C=(t.radius+a)**2;export{m as CloudsParallaxShading};