| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 | float interpolateByDistance(vec4 nearFarScalar, float distance){    float startDistance = nearFarScalar.x;    float startValue = nearFarScalar.y;    float endDistance = nearFarScalar.z;    float endValue = nearFarScalar.w;    float t = clamp((distance - startDistance) / (endDistance - startDistance), 0.0, 1.0);    return mix(startValue, endValue, t);}vec3 getLightDirection(vec3 positionWC){    float lightEnum = u_radiiAndDynamicAtmosphereColor.z;    vec3 lightDirection =        positionWC * float(lightEnum == 0.0) +        czm_lightDirectionWC * float(lightEnum == 1.0) +        czm_sunDirectionWC * float(lightEnum == 2.0);    return normalize(lightDirection);}void computeAtmosphereScattering(vec3 positionWC, vec3 lightDirection, out vec3 rayleighColor, out vec3 mieColor, out float opacity, out float underTranslucentGlobe){    float ellipsoidRadiiDifference = czm_ellipsoidRadii.x - czm_ellipsoidRadii.z;    // Adjustment to the atmosphere radius applied based on the camera height.    float distanceAdjustMin = czm_ellipsoidRadii.x / 4.0;    float distanceAdjustMax = czm_ellipsoidRadii.x;    float distanceAdjustModifier = ellipsoidRadiiDifference / 2.0;    float distanceAdjust = distanceAdjustModifier * clamp((czm_eyeHeight - distanceAdjustMin) / (distanceAdjustMax - distanceAdjustMin), 0.0, 1.0);    // Since atmosphere scattering assumes the atmosphere is a spherical shell, we compute an inner radius of the atmosphere best fit     // for the position on the ellipsoid.    float radiusAdjust = (ellipsoidRadiiDifference / 4.0) + distanceAdjust;    float atmosphereInnerRadius = (length(czm_viewerPositionWC) - czm_eyeHeight) - radiusAdjust;    // Setup the primary ray: from the camera position to the vertex position.    vec3 cameraToPositionWC = positionWC - czm_viewerPositionWC;    vec3 cameraToPositionWCDirection = normalize(cameraToPositionWC);    czm_ray primaryRay = czm_ray(czm_viewerPositionWC, cameraToPositionWCDirection);    underTranslucentGlobe = 0.0;    // Brighten the sky atmosphere under the Earth's atmosphere when translucency is enabled.    #if defined(GLOBE_TRANSLUCENT)        // Check for intersection with the inner radius of the atmopshere.        czm_raySegment primaryRayEarthIntersect = czm_raySphereIntersectionInterval(primaryRay, vec3(0.0), atmosphereInnerRadius + radiusAdjust);        if (primaryRayEarthIntersect.start > 0.0 && primaryRayEarthIntersect.stop > 0.0) {                        // Compute position on globe.            vec3 direction = normalize(positionWC);            czm_ray ellipsoidRay = czm_ray(positionWC, -direction);            czm_raySegment ellipsoidIntersection = czm_rayEllipsoidIntersectionInterval(ellipsoidRay, vec3(0.0), czm_ellipsoidInverseRadii);            vec3 onEarth = positionWC - (direction * ellipsoidIntersection.start);            // Control the color using the camera angle.            float angle = dot(normalize(czm_viewerPositionWC), normalize(onEarth));            // Control the opacity using the distance from Earth.            opacity = interpolateByDistance(vec4(0.0, 1.0, czm_ellipsoidRadii.x, 0.0), length(czm_viewerPositionWC - onEarth));            vec3 horizonColor = vec3(0.1, 0.2, 0.3);            vec3 nearColor = vec3(0.0);            rayleighColor = mix(nearColor, horizonColor, exp(-angle) * opacity);                        // Set the traslucent flag to avoid alpha adjustment in computeFinalColor funciton.            underTranslucentGlobe = 1.0;            return;        }    #endif    computeScattering(        primaryRay,        length(cameraToPositionWC),        lightDirection,        atmosphereInnerRadius,        rayleighColor,        mieColor,        opacity    );    // Alter the opacity based on how close the viewer is to the ground.    // (0.0 = At edge of atmosphere, 1.0 = On ground)    float cameraHeight = czm_eyeHeight + atmosphereInnerRadius;    float atmosphereOuterRadius = atmosphereInnerRadius + ATMOSPHERE_THICKNESS;    opacity = clamp((atmosphereOuterRadius - cameraHeight) / (atmosphereOuterRadius - atmosphereInnerRadius), 0.0, 1.0);    // Alter alpha based on time of day (0.0 = night , 1.0 = day)    float nightAlpha = (u_radiiAndDynamicAtmosphereColor.z != 0.0) ? clamp(dot(normalize(positionWC), lightDirection), 0.0, 1.0) : 1.0;    opacity *= pow(nightAlpha, 0.5);}
 |