123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- //#define SHOW_TILE_BOUNDARIES
- uniform vec4 u_initialColor;
- #if TEXTURE_UNITS > 0
- uniform sampler2D u_dayTextures[TEXTURE_UNITS];
- uniform vec4 u_dayTextureTranslationAndScale[TEXTURE_UNITS];
- #ifdef APPLY_ALPHA
- uniform float u_dayTextureAlpha[TEXTURE_UNITS];
- #endif
- #ifdef APPLY_BRIGHTNESS
- uniform float u_dayTextureBrightness[TEXTURE_UNITS];
- #endif
- #ifdef APPLY_CONTRAST
- uniform float u_dayTextureContrast[TEXTURE_UNITS];
- #endif
- #ifdef APPLY_HUE
- uniform float u_dayTextureHue[TEXTURE_UNITS];
- #endif
- #ifdef APPLY_SATURATION
- uniform float u_dayTextureSaturation[TEXTURE_UNITS];
- #endif
- #ifdef APPLY_GAMMA
- uniform float u_dayTextureOneOverGamma[TEXTURE_UNITS];
- #endif
- uniform vec4 u_dayTextureTexCoordsRectangle[TEXTURE_UNITS];
- #endif
- #ifdef SHOW_REFLECTIVE_OCEAN
- uniform sampler2D u_waterMask;
- uniform vec4 u_waterMaskTranslationAndScale;
- uniform float u_zoomedOutOceanSpecularIntensity;
- #endif
- #ifdef SHOW_OCEAN_WAVES
- uniform sampler2D u_oceanNormalMap;
- #endif
- #ifdef ENABLE_DAYNIGHT_SHADING
- uniform vec2 u_lightingFadeDistance;
- #endif
- varying vec3 v_positionMC;
- varying vec3 v_positionEC;
- varying vec2 v_textureCoordinates;
- varying vec3 v_normalMC;
- varying vec3 v_normalEC;
- vec4 sampleAndBlend(
- vec4 previousColor,
- sampler2D texture,
- vec2 tileTextureCoordinates,
- vec4 textureCoordinateRectangle,
- vec4 textureCoordinateTranslationAndScale,
- float textureAlpha,
- float textureBrightness,
- float textureContrast,
- float textureHue,
- float textureSaturation,
- float textureOneOverGamma)
- {
- // This crazy step stuff sets the alpha to 0.0 if this following condition is true:
- // tileTextureCoordinates.s < textureCoordinateRectangle.s ||
- // tileTextureCoordinates.s > textureCoordinateRectangle.p ||
- // tileTextureCoordinates.t < textureCoordinateRectangle.t ||
- // tileTextureCoordinates.t > textureCoordinateRectangle.q
- // In other words, the alpha is zero if the fragment is outside the rectangle
- // covered by this texture. Would an actual 'if' yield better performance?
- vec2 alphaMultiplier = step(textureCoordinateRectangle.st, tileTextureCoordinates);
- textureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;
-
- alphaMultiplier = step(vec2(0.0), textureCoordinateRectangle.pq - tileTextureCoordinates);
- textureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;
-
- vec2 translation = textureCoordinateTranslationAndScale.xy;
- vec2 scale = textureCoordinateTranslationAndScale.zw;
- vec2 textureCoordinates = tileTextureCoordinates * scale + translation;
- vec4 sample = texture2D(texture, textureCoordinates);
- vec3 color = sample.rgb;
- float alpha = sample.a;
-
- #ifdef APPLY_BRIGHTNESS
- color = mix(vec3(0.0), color, textureBrightness);
- #endif
- #ifdef APPLY_CONTRAST
- color = mix(vec3(0.5), color, textureContrast);
- #endif
- #ifdef APPLY_HUE
- color = czm_hue(color, textureHue);
- #endif
- #ifdef APPLY_SATURATION
- color = czm_saturation(color, textureSaturation);
- #endif
- #ifdef APPLY_GAMMA
- color = pow(color, vec3(textureOneOverGamma));
- #endif
- float sourceAlpha = alpha * textureAlpha;
- float outAlpha = mix(previousColor.a, 1.0, sourceAlpha);
- vec3 outColor = mix(previousColor.rgb * previousColor.a, color, sourceAlpha) / outAlpha;
- return vec4(outColor, outAlpha);
- }
- vec4 computeDayColor(vec4 initialColor, vec2 textureCoordinates);
- vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue);
- void main()
- {
- // The clamp below works around an apparent bug in Chrome Canary v23.0.1241.0
- // where the fragment shader sees textures coordinates < 0.0 and > 1.0 for the
- // fragments on the edges of tiles even though the vertex shader is outputting
- // coordinates strictly in the 0-1 range.
- vec4 color = computeDayColor(u_initialColor, clamp(v_textureCoordinates, 0.0, 1.0));
- #ifdef SHOW_TILE_BOUNDARIES
- if (v_textureCoordinates.x < (1.0/256.0) || v_textureCoordinates.x > (255.0/256.0) ||
- v_textureCoordinates.y < (1.0/256.0) || v_textureCoordinates.y > (255.0/256.0))
- {
- color = vec4(1.0, 0.0, 0.0, 1.0);
- }
- #endif
- #if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING)
- vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates
- vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes
- #elif defined(ENABLE_VERTEX_LIGHTING)
- vec3 normalMC = normalize(v_normalMC); // normalized surface normal in model coordinates
- vec3 normalEC = normalize(v_normalEC); // normalized surface normal in eye coordiantes
- #endif
- #ifdef SHOW_REFLECTIVE_OCEAN
- vec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy;
- vec2 waterMaskScale = u_waterMaskTranslationAndScale.zw;
- vec2 waterMaskTextureCoordinates = v_textureCoordinates * waterMaskScale + waterMaskTranslation;
- float mask = texture2D(u_waterMask, waterMaskTextureCoordinates).r;
- if (mask > 0.0)
- {
- mat3 enuToEye = czm_eastNorthUpToEyeCoordinates(v_positionMC, normalEC);
-
- vec2 ellipsoidTextureCoordinates = czm_ellipsoidWgs84TextureCoordinates(normalMC);
- vec2 ellipsoidFlippedTextureCoordinates = czm_ellipsoidWgs84TextureCoordinates(normalMC.zyx);
- vec2 textureCoordinates = mix(ellipsoidTextureCoordinates, ellipsoidFlippedTextureCoordinates, czm_morphTime * smoothstep(0.9, 0.95, normalMC.z));
- color = computeWaterColor(v_positionEC, textureCoordinates, enuToEye, color, mask);
- }
- #endif
- #ifdef ENABLE_VERTEX_LIGHTING
- float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 0.9 + 0.3, 0.0, 1.0);
- gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a);
- #elif defined(ENABLE_DAYNIGHT_SHADING)
- float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0);
- float cameraDist = length(czm_view[3]);
- float fadeOutDist = u_lightingFadeDistance.x;
- float fadeInDist = u_lightingFadeDistance.y;
- float t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0);
- diffuseIntensity = mix(1.0, diffuseIntensity, t);
- gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a);
- #else
- gl_FragColor = color;
- #endif
- }
- #ifdef SHOW_REFLECTIVE_OCEAN
- float waveFade(float edge0, float edge1, float x)
- {
- float y = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
- return pow(1.0 - y, 5.0);
- }
- float linearFade(float edge0, float edge1, float x)
- {
- return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
- }
- // Based on water rendering by Jonas Wagner:
- // http://29a.ch/2012/7/19/webgl-terrain-rendering-water-fog
- // low altitude wave settings
- const float oceanFrequencyLowAltitude = 825000.0;
- const float oceanAnimationSpeedLowAltitude = 0.004;
- const float oceanOneOverAmplitudeLowAltitude = 1.0 / 2.0;
- const float oceanSpecularIntensity = 0.5;
-
- // high altitude wave settings
- const float oceanFrequencyHighAltitude = 125000.0;
- const float oceanAnimationSpeedHighAltitude = 0.008;
- const float oceanOneOverAmplitudeHighAltitude = 1.0 / 2.0;
- vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue)
- {
- vec3 positionToEyeEC = -positionEyeCoordinates;
- float positionToEyeECLength = length(positionToEyeEC);
- // The double normalize below works around a bug in Firefox on Android devices.
- vec3 normalizedpositionToEyeEC = normalize(normalize(positionToEyeEC));
-
- // Fade out the waves as the camera moves far from the surface.
- float waveIntensity = waveFade(70000.0, 1000000.0, positionToEyeECLength);
- #ifdef SHOW_OCEAN_WAVES
- // high altitude waves
- float time = czm_frameNumber * oceanAnimationSpeedHighAltitude;
- vec4 noise = czm_getWaterNoise(u_oceanNormalMap, textureCoordinates * oceanFrequencyHighAltitude, time, 0.0);
- vec3 normalTangentSpaceHighAltitude = vec3(noise.xy, noise.z * oceanOneOverAmplitudeHighAltitude);
-
- // low altitude waves
- time = czm_frameNumber * oceanAnimationSpeedLowAltitude;
- noise = czm_getWaterNoise(u_oceanNormalMap, textureCoordinates * oceanFrequencyLowAltitude, time, 0.0);
- vec3 normalTangentSpaceLowAltitude = vec3(noise.xy, noise.z * oceanOneOverAmplitudeLowAltitude);
-
- // blend the 2 wave layers based on distance to surface
- float highAltitudeFade = linearFade(0.0, 60000.0, positionToEyeECLength);
- float lowAltitudeFade = 1.0 - linearFade(20000.0, 60000.0, positionToEyeECLength);
- vec3 normalTangentSpace =
- (highAltitudeFade * normalTangentSpaceHighAltitude) +
- (lowAltitudeFade * normalTangentSpaceLowAltitude);
- normalTangentSpace = normalize(normalTangentSpace);
-
- // fade out the normal perturbation as we move farther from the water surface
- normalTangentSpace.xy *= waveIntensity;
- normalTangentSpace = normalize(normalTangentSpace);
- #else
- vec3 normalTangentSpace = vec3(0.0, 0.0, 1.0);
- #endif
- vec3 normalEC = enuToEye * normalTangentSpace;
-
- const vec3 waveHighlightColor = vec3(0.3, 0.45, 0.6);
-
- // Use diffuse light to highlight the waves
- float diffuseIntensity = czm_getLambertDiffuse(czm_sunDirectionEC, normalEC);
- vec3 diffuseHighlight = waveHighlightColor * diffuseIntensity;
-
- #ifdef SHOW_OCEAN_WAVES
- // Where diffuse light is low or non-existent, use wave highlights based solely on
- // the wave bumpiness and no particular light direction.
- float tsPerturbationRatio = normalTangentSpace.z;
- vec3 nonDiffuseHighlight = mix(waveHighlightColor * 5.0 * (1.0 - tsPerturbationRatio), vec3(0.0), diffuseIntensity);
- #else
- vec3 nonDiffuseHighlight = vec3(0.0);
- #endif
- // Add specular highlights in 3D, and in all modes when zoomed in.
- float specularIntensity = czm_getSpecular(czm_sunDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0) + 0.25 * czm_getSpecular(czm_moonDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0);
- float surfaceReflectance = mix(0.0, mix(u_zoomedOutOceanSpecularIntensity, oceanSpecularIntensity, waveIntensity), specularMapValue);
- float specular = specularIntensity * surfaceReflectance;
-
- return vec4(imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular, imageryColor.a);
- }
- #endif // #ifdef SHOW_REFLECTIVE_OCEAN
|