diff options
Diffstat (limited to 'tests/spec/arb_es2_compatibility/ge7.frag')
-rw-r--r-- | tests/spec/arb_es2_compatibility/ge7.frag | 710 |
1 files changed, 710 insertions, 0 deletions
diff --git a/tests/spec/arb_es2_compatibility/ge7.frag b/tests/spec/arb_es2_compatibility/ge7.frag new file mode 100644 index 00000000..2d354eab --- /dev/null +++ b/tests/spec/arb_es2_compatibility/ge7.frag @@ -0,0 +1,710 @@ +//!GL2 +#define GE_PIXEL_SHADER +#define GE_PRECISION mediump +#define ATMOSPHERE_OFF +#define GROUND +#define SUN_OFF +#define OVERLAY +#define ENABLE_VERTEX_REJECT +#if defined(GL_ES) +precision GE_PRECISION float; +#else +#define lowp +#define mediump +#define highp +#endif + +uniform mat4 ig_ModelViewMatrix; +uniform mat4 ig_ModelViewProjectionMatrix; +uniform mat4 ig_TextureMatrix; +uniform vec4 ig_LightDirectionInModelSpace; +uniform vec4 ig_env_atmosphere_custom_state_value; +uniform lowp vec4 ig_env_atmosphere_custom_color_value; +uniform lowp float alpha_ref_value; + +float saturate(float v) { return clamp(v, 0.0, 1.0); } +vec2 saturate(vec2 v) { return clamp(v, 0.0, 1.0); } +vec3 saturate(vec3 v) { return clamp(v, 0.0, 1.0); } +vec4 saturate(vec4 v) { return clamp(v, 0.0, 1.0); } + +// Returns the quadrant portion of the given vertex flags. +float getQuadrant(vec4 vertexQuadrant) { + return dot(vertexQuadrant, vec4(1.0, 2.0, 4.0, 8.0)); +} + +// Both getMasked methods assume that quadrantMask has a single 1 and the +// rest are 0. + +vec4 getMaskedVertex(vec4 pos, vec4 quadrantMask, vec4 vertexQuadrant) { + return pos * dot(quadrantMask, vertexQuadrant); +} + +float getMaskedAlpha(vec4 quadrantAlphas, vec4 vertexQuadrant) { + return dot(quadrantAlphas, vertexQuadrant); +} + +// Computes a vertex color to show which quadrant a vertex is in. Also marks +// vertices that would be rejected and error conditions (e.g. invalid +// quadrant). +vec4 getDebugVertexColor(vec4 quadrantMask, vec4 vertexQuadrant) { + vec4 color; + float quadrant = getQuadrant(vertexQuadrant); + if (quadrant == 1.0) { + // Red + color = vec4(1.0, 0.0, 0.0, 1.0); + } else if (quadrant == 2.0) { + // Green + color = vec4(0.0, 1.0, 0.0, 1.0); + } else if (quadrant == 4.0) { + // Blue + color = vec4(0.0, 0.0, 1.0, 1.0); + } else if (quadrant == 8.0) { + // Cyan + color = vec4(0.0, 1.0, 1.0, 1.0); + } else if (quadrant == 0.0) { + // Vertex didn't have a quadrant bit set. Mark as saturated Yellow. + color = vec4(10.0, 10.0, 0.0, 1.0); + } else if (quadrant == 15.0) { + // All quadrant bits were set. Mark as White. + color = vec4(10.0, 10.0, 10.0, 1.0); + } else { + // More than one quadrant bit was set or a quadrant bit was set to + // something other than 1.0, so flag verts in saturated Magenta. + color = vec4(10.0, 0.0, 10.0, 1.0); + } + // Make hidden quadrants dimmer. + if (dot(quadrantMask, vertexQuadrant) == 0.) + color *= .5; + return color; +} + +#ifdef DEBUG_QUADRANT_COLORS +// Used by the pixel shader to show quadrants, culled verts and error +// conditions when DEBUG_QUADRANT_COLORS is defined. +varying vec4 vout_debug_color; +#endif + +// The \"discard\" instruction is not available for vertex shaders, so +// this function needs to be excluded when parsing a vertex shader. +#ifdef GE_PIXEL_SHADER + +// When debugging is on, modulates the pixel color by the debug color output +// from the vertex shader. Otherwise, the given pixel color is returned +// unchanged. +vec4 computeDebugPixelColor(vec4 pixelShaderColor) { +// OGL ES 2.0 does not support alpha test, so need to do it in the +// shader. +#if defined(GL_ES) && !defined(FORCE_NO_ALPHA_TEST) +// Terrain and sky don't use alpha test. +#if defined(OVERLAY) || defined(MODEL) + // alpha_ref_value is set by igVisualContext, and will be -1 if alpha test + // is off. + if (pixelShaderColor.a < alpha_ref_value) { + discard; + } +#endif // defined(OVERLAY) || defined(MODEL) +#endif // defined(GL_ES) && !defined(FORCE_NO_ALPHA_TEST) + +#ifdef DEBUG_QUADRANT_COLORS + return pixelShaderColor * vout_debug_color; +#else + return pixelShaderColor; +#endif +} + +#endif // GE_PIXEL_SHADER +// Constant g for phase function used for Mie scattering. +const float gMieConst = -0.990; +const float gMieConst2 = gMieConst * gMieConst; + +varying vec4 vout_texCoordAndFogFactor; +#if defined(QUADRANT_ALPHAS) +varying float vout_alpha; +#endif + +uniform lowp sampler2D groundTexture; +uniform lowp vec4 groundColor; + +#if defined(OVERLAY) +uniform vec4 groundOverlayExtent; +float GetMaskedOverlayAlpha(float alpha, vec2 texCoord) { + return ((texCoord.s - groundOverlayExtent.x) * + (groundOverlayExtent.y - texCoord.s) >= 0. && + (texCoord.t - groundOverlayExtent.z) * + (groundOverlayExtent.w - texCoord.t) >= 0. ? alpha : 0.0); +} + +#endif // defined(OVERLAY) + +#if defined(USE_IMPROVED_SHADER_VARIATION) +// x: atmosphere density. +// y: atmosphere angle falloff. +// z: night intensity. +// w: camera exposure. +uniform vec4 atmosphereTweaks; + +#endif // defined(USE_IMPROVED_SHADER_VARIATION) + +//", '=' <repeats 30 times>, " ground sun off +#if defined(ATMOSPHERE_ON) && defined(GROUND) && defined(SUN_OFF) + +#if !defined(USE_SIMPLIFIED_SHADER_VARIATION) +varying vec4 vout_blendTexCoordAndRayleighT; +#endif + +uniform lowp sampler2D groundRayleighMap; +uniform vec4 groundSunOffPixelParams; +uniform lowp vec4 groundFogColor; + +#if defined(DEBUG_GE_BUILD) +uniform lowp vec4 sidedb_color; +#endif + +void AtmosphereGroundSunOffFragShader() { + // Get the texture color for the object. + lowp vec4 texColor = texture2D(groundTexture, vout_texCoordAndFogFactor.st); + +#if defined(DEBUG_GE_BUILD) + if (sidedb_color.a > 0.0) { + texColor = mix(texColor, sidedb_color, 0.1); + } +#endif + texColor *= groundColor; + + lowp vec4 color; + #if defined(USE_SIMPLIFIED_SHADER_VARIATION) + color = texColor; + #else + // The rayleigh map's s-coordinate depends on camera height and is computed + // on the CPU. + float rayleighS = groundSunOffPixelParams.x; + lowp vec4 rayleigh = texture2D(groundRayleighMap, vec2(rayleighS, vout_blendTexCoordAndRayleighT.z)); + texColor.rgb += rayleigh.rgb; + lowp float fogFactor = vout_texCoordAndFogFactor.w; + color.rgb = mix(groundFogColor.rgb, texColor.rgb, fogFactor); + color.a = texColor.a; + #endif + + gl_FragColor = computeDebugPixelColor(color); +} + +//", '=' <repeats 30 times>, " ground sun off overlay +#if defined(OVERLAY) +uniform lowp sampler2D groundRayleighOverlayMap; + +void AtmosphereGroundSunOffOverlayFragShader() { + // Get the texture color for the object. The projective component is to + // allow us to do Arbitrary Ground Overlays. + lowp vec4 texColor = + texture2DProj(groundTexture, vout_texCoordAndFogFactor.stp) * + groundColor; + // Note that we do not allow texture blend for overlays. + // Perform texture edge clamping for ground overlays by setting alpha to zero + // outside of texture coordinate range [0, 1] + vec2 stOverZ = vout_texCoordAndFogFactor.xy / vout_texCoordAndFogFactor.z; + texColor.a = GetMaskedOverlayAlpha(texColor.a, stOverZ); + + // The rayleigh map's s-coordinate depends on camera height and is computed + // on the CPU. + float rayleighS = groundSunOffPixelParams.x; + lowp vec4 rayleigh = texture2D( + groundRayleighOverlayMap, + vec2(rayleighS, vout_blendTexCoordAndRayleighT.z)); + texColor.rgb += rayleigh.rgb; + lowp float fogFactor = vout_texCoordAndFogFactor.w; + lowp vec4 color; + color.rgb = mix(groundFogColor.rgb, texColor.rgb, fogFactor); + color.a = texColor.a; + gl_FragColor = computeDebugPixelColor(color); +} +#endif // defined(OVERLAY) +#endif // defined(ATMOSPHERE_ON) && defined(GROUND) && defined(SUN_OFF) + +//", '=' <repeats 30 times>, " ground sun on (default) +#if defined(ATMOSPHERE_ON) && defined(GROUND) && defined(SUN_ON) && !defined(USE_IMPROVED_SHADER_VARIATION) +varying vec3 vout_rayleigh; +varying vec3 vout_adjustedMie; +uniform vec4 fogColor; + +#if defined(MODEL) +uniform float has_texture; +uniform lowp vec4 global_color; +#endif + +void AtmosphereGroundSunOnFragShader() { + // If texturing is off, use white as diffuse color. Otherwise use color + // from texture. +#if defined(MODEL) + lowp vec4 texColor = mix( + global_color, + texture2D(groundTexture, vout_texCoordAndFogFactor.st) * global_color, + has_texture); +#else + lowp vec4 texColor = ig_env_atmosphere_custom_state_value.y != 0.0 ? + texture2D(groundTexture, vout_texCoordAndFogFactor.st) * groundColor : + groundColor; +#endif // defined(MODEL) + vec3 scatteredColor = vout_rayleigh.rgb + texColor.rgb * vout_adjustedMie.rgb; + float fogFactor = vout_texCoordAndFogFactor.w; + vec4 color; + color.rgb = mix(fogColor.rgb, scatteredColor, fogFactor); + color.a = texColor.a; + gl_FragColor = computeDebugPixelColor(color); +} + + +//", '=' <repeats 29 times>, " ground sun on overlay (default) +#if defined(OVERLAY) +// Similar to above, but sets output alpha to zero when the projected texture +// coordinates are outside of the [0,1] range. +void AtmosphereGroundSunOnOverlayFragShader() { + // Get the texture color for the object. The projective component is to + // allow us to do Arbitrary Ground Overlays. + // If texturing is off, use white as diffuse color. Otherwise use color + // from texture. + lowp vec4 texColor = (ig_env_atmosphere_custom_state_value.y == 0.0) ? + groundColor : + (texture2DProj(groundTexture, vout_texCoordAndFogFactor.xyz) * + groundColor); + // Perform texture edge clamping for ground overlays by setting alpha to zero + // outside of texture coordinate range [0, 1] + vec2 stOverZ = vout_texCoordAndFogFactor.xy / vout_texCoordAndFogFactor.z; + texColor.a = GetMaskedOverlayAlpha(texColor.a, stOverZ); + + vec3 scatteredColor = vout_rayleigh.rgb + texColor.rgb * vout_adjustedMie.rgb; + float fogFactor = vout_texCoordAndFogFactor.w; + vec4 color; + color.rgb = mix(fogColor.rgb, scatteredColor, fogFactor); + color.a = texColor.a; + gl_FragColor = computeDebugPixelColor(color); +} +#endif // defined(OVERLAY) +#endif // defined(ATMOSPHERE_ON) && defined(GROUND) && defined(SUN_ON) && !defined(USE_IMPROVED_SHADER_VARIATION) + +//", '=' <repeats 30 times>, " ground sun on (improved) +#if defined(ATMOSPHERE_ON) && defined(GROUND) && defined(SUN_ON) && defined(USE_IMPROVED_SHADER_VARIATION) +uniform vec3 worldOriginInView; +// The direction vector to the light source. +uniform vec4 cameraToSunDirAndExposure; +// xyz: Extra ambient color that is stronger during sunsets (and sunrises). +// w: density used in fog exp2 function. +uniform vec4 sunsetAmbientAndFogDensity; +uniform vec4 fogColor; + +varying vec4 vout_viewPosAndNormalDotSun; +#if defined(MORPH_VERTICES) +varying vec4 vout_blendTexCoord; +#endif // defined(MORPH_VERTICES) + +// Implements the abstract function defined in atmosphere.glsllib. +// Returns a fading factor to attenuate the atmospheric effects when the camera +// altitude decreases, unless the view zenith angle gets close to the horizon +// angle. +float atmosphereTweak(float r, float mu) { + float r0 = max(kMinCameraRadius, cameraAndSunState.x); + float muHoriz = -sqrt(1.0 - 1.0 / (r * r)); + float angleFalloff = pow((1.0 + mu) / (1.0 + muHoriz), atmosphereTweaks.y); + return clamp(angleFalloff, 0.1, 1.0) * atmosphereTweaks.x; +} + +vec4 ImprovedAtmosphereGroundSunOnAboveWater(vec4 texColor) { + // Computes the ground albedo, i.e. the proportion of incident ligth reflected + // by the ground, for each r,g,b wavelength, divided by pi. Ideally the ground + // texture would directly contain this physical quantity, but in fact it + // contains some uncalibrated values. Assuming that these values correctly + // represent the albedo, and that they are simply gamma corrected as in almost + // all images with a gamma value of 2.2, we can compute the albedo with a + // pow(color.rgb, 2.2) or approximate it with a square to avoid a costly pow + // function: + vec3 albedoOverPi = texColor.rgb * texColor.rgb * (0.55 / kPi); + + // Computes the fragment position in geocentric coordinates. + vec3 groundPos = vout_viewPosAndNormalDotSun.xyz - worldOriginInView.xyz; + + // Computes the radiance of the Sun reaching groundPos, relatively to the + // outer Sun radiance. This is the transmittance of the atmosphere from the + // ground to the top atmosphere boundary in the Sun direction. + float gR = length(groundPos); + float gMuS = dot(groundPos, cameraToSunDirAndExposure.xyz) / gR; + vec3 sunRadiance = atmoTex(gR, gMuS).rgb; + + // Computes the irradiance due to the sky dome (excluding the Sun). + vec3 skyIrradiance = skyTex(gR, gMuS) * atmosphereTweaks.x; + // Tweaks the sky irradiance to avoid a dark ground during night. + float night = smoothstep(0.0, 0.2, -gMuS) * atmosphereTweaks.z; + vec3 gSkyIrradiance = max(skyIrradiance, vec3(0.002, 0.005, 0.01) * night); + + // Computes the radiance reflected by the ground (using a Lambertian BRDF). + vec3 groundL = albedoOverPi * + (max(vout_viewPosAndNormalDotSun.w, 0.0) * sunRadiance + gSkyIrradiance); + + vec3 pixel = aerialPerspective(groundL, -worldOriginInView, groundPos, + cameraToSunDirAndExposure.xyz, atmosphereTweaks.w); + return vec4(pixel, texColor.a); +} + +vec4 ImprovedAtmosphereGroundSunOnBelowWater(vec4 texColor) { + // The following shading is completely ad-hoc and not physically-based at all. + // For instance distant water is always blue, even at night, which is of + // course wrong. Also the Sun light is not attenuated with depth, so that the + // sea bottom is always visible (in reality everything becomes completely dark + // at a few dozens meters below the surface). + texColor.rgb *= 0.66 * max(vout_viewPosAndNormalDotSun.w, 0.33); + float fogDistSq = dot(vout_viewPosAndNormalDotSun.xyz, + vout_viewPosAndNormalDotSun.xyz); + float fogFactor = exp(-2.0 * sunsetAmbientAndFogDensity.w * sqrt(fogDistSq)); + return vec4(mix(fogColor.rgb, texColor.rgb, fogFactor), texColor.a); +} + +void ImprovedAtmosphereGroundSunOnFragShader() { +#if defined(OVERLAY) + // Get the texture color for the object. The projective component is to + // allow us to do Arbitrary Ground Overlays. + // If texturing is off, use white as diffuse color. Otherwise use color + // from texture. + lowp vec4 texColor = (ig_env_atmosphere_custom_state_value.y == 0.0) ? + vec4(1.0) : texture2DProj(groundTexture, vout_texCoordAndFogFactor.xyz); + // Perform texture edge clamping for ground overlays by setting alpha to zero + // outside of texture coordinate range [0, 1] + vec2 stOverZ = vout_texCoordAndFogFactor.xy / vout_texCoordAndFogFactor.z; + texColor.a = GetMaskedOverlayAlpha(texColor.a, stOverZ); +#else + // If texturing is off, use white as diffuse color. Otherwise use color + // from texture. + vec4 texColor; + if (ig_env_atmosphere_custom_state_value.y != 0.0) { + texColor = texture2D(groundTexture, vout_texCoordAndFogFactor.st); + #if defined(MORPH_VERTICES) + float blend_param = blendUnpopPixelParams[0]; + if (blend_param != 0.) { + // We are blending between 2 textures. + vec4 blendBlendColor = texture2D(blendTexture, vout_blendTexCoord.st); + // Compute final pixel color, blend between texture 1 and texture 2 + texColor = mix(texColor, blendBlendColor, blend_param); + } + #endif // defined(MORPH_VERTICES) + } else { + texColor = vec4(1.0); + } +#endif + + vec4 color; + // TODO(ebruneton): water level may not always be exactly at r=1, + // how can we detect that? + if (cameraAndSunState.x < 1.0) { + color = ImprovedAtmosphereGroundSunOnBelowWater(texColor); + } else { + color = ImprovedAtmosphereGroundSunOnAboveWater(texColor); + } + #if defined(MORPH_VERTICES) + float unpop_alpha = blendUnpopPixelParams[1]; + color.a *= unpop_alpha; + #endif // defined(MORPH_VERTICES) + gl_FragColor = computeDebugPixelColor(color); +} +#endif // defined(ATMOSPHERE_ON) && defined(GROUND) && defined(SUN_ON) && defined(USE_IMPROVED_SHADER_VARIATION) + +//", '=' <repeats 32 times>, " sky sun off", '=' <repeats 26 times>, " +#if defined(ATMOSPHERE_ON) && defined(SKY) && defined(SUN_OFF) +varying vec4 vout_rayleighT; +uniform vec4 skySunOffPixelParams; +uniform lowp sampler2D skyMap; + +void AtmosphereSkySunOffFragShader() { + // The rayleigh map's s-coordinate depends on camera height and is computed + // on the CPU. + float rayleighS = skySunOffPixelParams.x; + lowp vec4 color = texture2D(skyMap, vec2(rayleighS, vout_rayleighT.x)); + gl_FragColor = color; +} +#endif // defined(ATMOSPHERE_ON) && defined(SKY) && defined(SUN_OFF) + +//", '=' <repeats 32 times>, " sky sun on (default)", '=' <repeats 22 times>, " +#if defined(ATMOSPHERE_ON) && defined(SKY) && defined(SUN_ON) && !defined(USE_IMPROVED_SHADER_VARIATION) +varying vec4 vout_rayleighColorAndSkyOpacity; +varying vec4 vout_vertToCameraDir; +// The direction vector to the light source in View coordinate system. +uniform vec4 cameraToSunDirAndExposure; +// xyz: Attribute for Mie color corresponding to the brightest spot in the +// sky (i.e. usually the sun's front color during the day, and black +// during the night). +// This is computed on the CPU in double floating precision to avoid +// precision problems on the GPU. +// w: Sun strength: [0, 1] where 0 = no sun, 1 = full strength. +uniform vec4 brightestMieColorAndSunStrength; + +// Calculates the Rayleigh phase function. +float getRayleighPhase(float cosAngle2) { + return 0.75 + 0.75 * cosAngle2; +} + +// Calculates the Mie phase function. +float getMiePhase(float cosAngle, float cosAngle2) { + return 1.5 * ((1.0 - gMieConst2) / (2.0 + gMieConst2)) * (1.0 + cosAngle2) / + pow(1.0 + gMieConst2 - 2.0 * gMieConst * cosAngle, 1.5); +} + +// Returns the luminance of an RGB color. +float getLuminance(vec3 color) { + const vec3 luminance = vec3(0.3, 0.59, 0.11); + return dot(luminance, color); +} + +void AtmosphereSkySunOnFragShader() { + // Variables needed to compute Rayleigh and Mie phases. + float cosAngle = dot(cameraToSunDirAndExposure.xyz, + vout_vertToCameraDir.xyz) / length(vout_vertToCameraDir.xyz); + // Tweak cosAngle by sunStrength. This dims the sun strength for lower + // values of sunStrength. + cosAngle *= brightestMieColorAndSunStrength.w; + float cosAngle2 = cosAngle * cosAngle; + // Compute final color using Rayleigh and Mie phases. + // The alpha component gets overwritten later. + vec4 color; + color.rgb = getRayleighPhase(cosAngle2) * vout_rayleighColorAndSkyOpacity.rgb + + getMiePhase(cosAngle, cosAngle2) * brightestMieColorAndSunStrength.rgb; + // Tone HDR using constant exposure for the whole scene. + color.rgb = vec3(1.0) - exp(color.rgb * -cameraToSunDirAndExposure.w); + // Use color's luminance to compute its opacity. + float luminanceAlphaComponent = 2.0 * getLuminance(color.rgb); + color.a = luminanceAlphaComponent + vout_rayleighColorAndSkyOpacity.a; + gl_FragColor = color; +} +#endif // defined(ATMOSPHERE_ON) && defined(SKY) && defined(SUN_ON) && !defined(USE_IMPROVED_SHADER_VARIATION) + +//", '=' <repeats 32 times>, " sky sun on (improved)", '=' <repeats 22 times>, " +#if defined(ATMOSPHERE_ON) && defined(SKY) && defined(SUN_ON) && defined(USE_IMPROVED_SHADER_VARIATION) + +// The radius of the atmosphere mesh, divided by the Earth radius. +const float kAtmosphereMeshRadius = (6378.0 + 170.0) / 6378.0; + +uniform vec3 worldOriginInView; +// The direction vector to the light source. +uniform vec4 cameraToSunDirAndExposure; + +varying vec3 vout_viewPos; // Vertex position in view coordinates. +varying vec3 vout_sunPos; // Vertex position in Sun coordinates. + +// Implements the abstract function defined in atmosphere.glsllib. +float atmosphereTweak(float r, float mu) { + return atmosphereTweaks.x; +} + +// Computes the final pixel color and alpha value from its radiance. The color +// is computed with a tone mapping operator to map the high dynamic range of the +// radiance values to the low dynamic range of the screen. The alpha value is +// used to approximate the correct compositing, which should in theory occur +// before tone mapping, and not after as we do for stars (see below). This alpha +// value is computed with an adhoc formula so that stars only appear in the very +// dark areas of the sky (i.e at night). +vec4 fragColor(vec3 pixelL) { + pixelL = toneMapping(pixelL, atmosphereTweaks.w); + return vec4(pixelL, dot(pixelL, vec3(2.0))); +} + +void ImprovedAtmosphereSkySunOnFragShader() { + // Computes the view ray direction in view and Sun coordinates. + vec3 viewViewRayDir = normalize(vout_viewPos); + vec3 sunViewRayDir = normalize(vout_sunPos); + + // Computes the radiance of the background behind the atmosphere. This should + // includes the Sun, the Moon and the stars, but here we only take the Sun + // into account. The Moon would not be difficult to handle, but rendering the + // stars here would require a very high res skymap. Instead, we render them + // with points, before rendering the sky, and we approximate the correct + // compositing, toneMapping(starL * transmittance + inscatterL), with alpha + // blending, i.e. with toneMapping(inscatterL) + (1 - a) * starL. We compute + // alpha with an adhoc formula based on toneMapping(inscatterL) -- see the + // fragColor function. + vec3 backgroundL = outerSunRadiance(sunViewRayDir); + + // Computes the camera to Earth center distance r, the view direction zenith + // angle cosinus mu, the Sun zenith angle cosinus muS, and the phase angle + // cosinus nu. + float r = cameraAndSunState.x; + float rMu = -dot(worldOriginInView.xyz, viewViewRayDir); + float rMuS = -dot(worldOriginInView.xyz, cameraToSunDirAndExposure.xyz); + float nu = dot(viewViewRayDir, cameraToSunDirAndExposure.xyz); + bool hitAtmosphere = true; + + // If the camera is outside the atmosphere, moves it to the entry point of the + // view ray inside the atmosphere, if it exists (otherwise the view ray does + // not traverse the atmosphere, and so we can return the background radiance). + if (r > kAtmosphereRadius) { + // Computes the distance from the view ray to the Earth center, squared. + float hSq = r * r - rMu * rMu; + // Computes the distance to the view ray entry point in the atmosphere. + float delta = kAtmosphereRadius * kAtmosphereRadius - hSq; + float distanceToAtmosphereEntryPoint = -rMu - sqrt(delta); + if (delta < 0.0 || distanceToAtmosphereEntryPoint < 0.0) { + // The view ray does not hit the atmosphere, return the background color, + // i.e the Sun color. In order to avoid discontinuities when switching + // from the Sun color computed here, to the Sun color resulting from the + // Sun billboard, we use an alpha value going from 1 at kAtmosphereRadius + // to 0 at kAtmosphereMeshRadius. + const float kAtmosphereRadiusSq = kAtmosphereRadius * kAtmosphereRadius; + const float kMeshRadiusSq = kAtmosphereMeshRadius * kAtmosphereMeshRadius; + float a = (kMeshRadiusSq - hSq) / (kMeshRadiusSq - kAtmosphereRadiusSq); + gl_FragColor = vec4(toneMapping(backgroundL, atmosphereTweaks.w) * a, a); + hitAtmosphere = false; + } else { + // Moves the camera to the view ray entry point inside the atmosphere. + r = kAtmosphereRadius; + rMu += distanceToAtmosphereEntryPoint; + rMuS += distanceToAtmosphereEntryPoint * nu; + } + } + + if (hitAtmosphere) { + // Computes the light which is scattered towards the viewer along the view + // ray, and the transmittance of the atmosphere along this ray. + vec3 transmittance; + vec3 inscatterL = inscatter(r, rMu / r, rMuS / r, nu, atmosphereTweaks.w, + transmittance); + + // The pixel radiance is the background radiance, multiplied by the + // atmosphere transmittance and augmented by the inscattered light. + vec3 pixelL = backgroundL * transmittance + inscatterL; + + gl_FragColor = fragColor(pixelL); + } +} +#endif // defined(ATMOSPHERE_ON) && defined(SKY) && defined(SUN_ON) && defined(USE_IMPROVED_SHADER_VARIATION) + +// ", '=' <repeats 65 times>, " +#if defined(ATMOSPHERE_OFF) && defined(SUN_OFF) +varying vec4 vout_groundTexCoord; // Transformed texture coordinate. + +void NoAtmosphereSunOffFragShader() { + vec4 diffuseColor = texture2D(groundTexture, vout_groundTexCoord.st); + gl_FragColor = computeDebugPixelColor(diffuseColor); +} +#endif // defined(ATMOSPHERE_OFF) && defined(SUN_OFF) + +// ", '=' <repeats 68 times>, " +#if defined(ATMOSPHERE_OFF) && defined(SUN_ON) +varying vec4 vout_transformedCoords; +varying float vout_diffuse_factor; + +void NoAtmosphereSunOnFragShader() { + // Get the texture color for the object. + vec4 diffuseColor = texture2D(groundTexture, vout_transformedCoords.xy); + diffuseColor.rgb *= vout_diffuse_factor; + gl_FragColor = computeDebugPixelColor(diffuseColor); +} +#endif // defined(ATMOSPHERE_OFF) && defined(SUN_ON) + +// ", '=' <repeats 67 times>, " +#if defined(ATMOSPHERE_OFF) && defined(GROUND) && defined(OVERLAY) +varying vec4 vout_texCoord; + +void NoAtmosphereGroundOverlayFragShader() { + // Get the texture color for the object. The projective component is to + // allow us to do Arbitrary Ground Overlays. + vec4 texColor = (texture2DProj(groundTexture, vout_texCoord.xyw)) * + groundColor; + + // Compute projected texture coordinates + vec2 stOverW = vout_texCoord.xy / vout_texCoord.w; + // Zero out alpha outside of texture edges. + texColor.a = GetMaskedOverlayAlpha(texColor.a, stOverW); + gl_FragColor = computeDebugPixelColor(texColor); +} +#endif // defined(ATMOSPHERE_OFF) && defined(GROUND) && defined(OVERLAY) + +// ", '=' <repeats 64 times>, " +// Forward-declare top-level functions. (This may fix some pre-processor issues +// when loading the shaders on Mali embedded GPUs.) +void AtmosphereGroundSunOnOverlayFragShader(); +void AtmosphereGroundSunOnFragShader(); +void AtmosphereGroundSunOffOverlayFragShader(); +void AtmosphereGroundSunOffFragShader(); +void AtmosphereSkySunOnFragShader(); +void AtmosphereSkySunOffFragShader(); +void ImprovedAtmosphereGroundSunOnFragShader(); +void ImprovedAtmosphereSkySunOnFragShader(); +void NoAtmosphereSunOnFragShader(); +void NoAtmosphereSunOffFragShader(); +void NoAtmosphereGroundOverlayFragShader(); + +void main() +{ + // All #elif directives have been replaced with #else + nested #if. + // Do not use #elif directives in shader files because they cause errors + // when loaded on Mali-400 based devices. See bug #6662252. +#if defined(ATMOSPHERE_ON) + #if defined(GROUND) + #if defined(SUN_ON) + #if defined(OVERLAY) + #if defined(USE_IMPROVED_SHADER_VARIATION) + ImprovedAtmosphereGroundSunOnFragShader(); + #else + AtmosphereGroundSunOnOverlayFragShader(); + #endif + #else + #if defined(USE_IMPROVED_SHADER_VARIATION) + ImprovedAtmosphereGroundSunOnFragShader(); + #else + AtmosphereGroundSunOnFragShader(); + #endif + #endif + #else + #if defined(SUN_OFF) + #if defined(OVERLAY) + AtmosphereGroundSunOffOverlayFragShader(); + #else + AtmosphereGroundSunOffFragShader(); + #endif + #else + #error Invalid shader config 1 + #endif + #endif + #if defined(QUADRANT_ALPHAS) + gl_FragColor.a *= vout_alpha; + #endif + #else + #if defined(SKY) + #if defined(SUN_ON) + #if defined(USE_IMPROVED_SHADER_VARIATION) + ImprovedAtmosphereSkySunOnFragShader(); + #else + AtmosphereSkySunOnFragShader(); + #endif + #else + #if defined(SUN_OFF) + AtmosphereSkySunOffFragShader(); + #else + #error Invalid shader config 2 + #endif + #endif + #else + #if defined(USE_IMPROVED_SHADER_VARIATION) + gl_FragColor = computeInscatter(gl_FragCoord.xy, atmosphereTweaks.w); + #else + #error Invalid shader config 3 + #endif + #endif + #endif +#elif defined(ATMOSPHERE_OFF) + #if defined(GROUND) && defined(OVERLAY) + NoAtmosphereGroundOverlayFragShader(); + #else + #if defined(SUN_ON) + NoAtmosphereSunOnFragShader(); + #elif defined(SUN_OFF) + NoAtmosphereSunOffFragShader(); + #else + #error Invalid shader config 4 + #endif + #endif + #if defined(QUADRANT_ALPHAS) + gl_FragColor.a *= vout_alpha; + #endif +#else + #error Invalid shader config 6 +#endif + + // Added by BrianP + gl_FragColor = vec4(0, 1, 0, 0); +} + |