1
0
Fork 0

Horizon blur and noise modulation model based on aloft visibility and weather variability for Atmospheric Light Scattering

This commit is contained in:
Thorsten Renk 2013-08-29 15:15:51 +03:00
parent f1bee8b5ab
commit bdd9520ca5
3 changed files with 348 additions and 315 deletions

View file

@ -14,6 +14,7 @@
<terminator><use>/environment/terminator-relative-position-m</use></terminator>
<terrain_alt><use>/environment/mean-terrain-elevation-m</use></terrain_alt>
<cloud_self_shading><use>/environment/cloud-self-shading</use></cloud_self_shading>
<horizon_roughness><use>/local-weather/config/small-scale-persistence</use></horizon_roughness>
</parameters>
<technique n="8">
<predicate>
@ -102,6 +103,11 @@
<type>float</type>
<value><use>cloud_self_shading</use></value>
</uniform>
<uniform>
<name>horizon_roughness</name>
<type>float</type>
<value><use>horizon_roughness</use></value>
</uniform>
</pass>
</technique>

View file

@ -10,7 +10,7 @@ varying vec3 mie;
varying vec3 eye;
varying vec3 hazeColor;
varying float ct;
//varying float cosphi;
varying float cphi;
varying float delta_z;
varying float alt;
varying float earthShade;
@ -21,6 +21,7 @@ uniform float visibility;
uniform float avisibility;
uniform float scattering;
uniform float cloud_self_shading;
uniform float horizon_roughness;
const float EarthRadius = 5800000.0;
@ -41,7 +42,39 @@ float rayleighPhase(in float cosTheta)
return 1.5 * (2.0 + 0.5*cosTheta*cosTheta);
}
float rand2D(in vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
float simple_interpolate(in float a, in float b, in float x)
{
return a + smoothstep(0.0,1.0,x) * (b-a);
}
float interpolatedNoise2D(in float x, in float y)
{
float integer_x = x - fract(x);
float fractional_x = x - integer_x;
float integer_y = y - fract(y);
float fractional_y = y - integer_y;
float v1 = rand2D(vec2(integer_x, integer_y));
float v2 = rand2D(vec2(integer_x+1.0, integer_y));
float v3 = rand2D(vec2(integer_x, integer_y+1.0));
float v4 = rand2D(vec2(integer_x+1.0, integer_y +1.0));
float i1 = simple_interpolate(v1 , v2 , fractional_x);
float i2 = simple_interpolate(v3 , v4 , fractional_x);
return simple_interpolate(i1 , i2 , fractional_y);
}
float Noise2D(in vec2 coord, in float wavelength)
{
return interpolatedNoise2D(coord.x/wavelength, coord.y/wavelength);
}
void main()
{
@ -198,7 +231,18 @@ color = sat * color + (1.0 - sat) * mix(color, black, smoothstep(0.4+cthorizon,0
// the terrain below the horizon gets drawn in one optical thickness
vec3 terrainHazeColor = eqColorFactor * hColor;
color = mix(color, terrainHazeColor ,smoothstep(0.01 + ctterrain, 0.0+ctterrain, ct));
// determine a visibility-dependent angle for how smoothly the haze blends over the skydome
float hazeBlendAngle = max(0.01,1000.0/avisibility + 0.3 * (1.0 - smoothstep(5000.0, 30000.0, avisibility)));
float altFactor = smoothstep(-300.0, 0.0, delta_z);
float altFactor2 = 0.2 + 0.8 * smoothstep(-3000.0, 0.0, delta_z);
hazeBlendAngle = hazeBlendAngle + 0.1 * altFactor;
hazeBlendAngle = hazeBlendAngle + (1.0-horizon_roughness) * altFactor2 * 0.1 * Noise2D(vec2(0.0,cphi), 0.3);
color = mix(color, terrainHazeColor ,smoothstep(hazeBlendAngle + ctterrain, 0.0+ctterrain, ct));
// mix fog the skydome with the right amount of haze

View file

@ -18,7 +18,7 @@ varying vec3 mie;
varying vec3 eye;
varying vec3 hazeColor;
varying float ct;
//varying float cosphi;
varying float cphi;
varying float delta_z;
varying float alt;
varying float earthShade;
@ -252,19 +252,9 @@ void main()
if (terminator > 1000000.0){yprime = -sqrt(2.0 * EarthRadius * hazeLayerAltitude);}
//float edgeAlt = max(hazeLayerAltitude - (alt-terrain_alt)/avisibility * visibility, terrain_alt);
//yprime = yprime -sqrt(2.0 * EarthRadius * edgeAlt);
float terminator_width = 200000.0;
earthShade = 0.9 * smoothstep((terminator_width+ terminator), (-terminator_width + terminator), yprime) + 0.1;
//hazeColor = vec3 (gl_LightSource[0].diffuse.x, gl_LightSource[0].diffuse.y, gl_LightSource[0].diffuse.z);
//hazeColor.x = hazeColor.x * 0.83;
//hazeColor.y = hazeColor.y * 0.9;
float lightArg = (terminator-yprime)/100000.0;
vec4 light_diffuse;
light_diffuse.b = light_func(lightArg, 1.330e-05, 0.264, 2.527, 1.08e-05, 1.0);
@ -275,18 +265,11 @@ void main()
float intensity = length(hazeColor.xyz);
float mie_magnitude = 0.5 * smoothstep(350000.0, 150000.0, terminator -sqrt(2.0 * EarthRadius * terrain_alt));
cphi = dot(normalize(relVector), normalize(lightHorizon));
float mie_angle = (0.5 * dot(normalize(relVector), normalize(lightFull)) ) + 0.5;
hazeColor = intensity * ((1.0 - mie_magnitude) + mie_magnitude * mie_angle) * normalize(mix(hazeColor, vec3 (0.5, 0.58, 0.65), mie_magnitude * (0.5 - 0.5 * mie_angle)) );
// high altitude desaturation - would be best here this causes a box-like bug for some reason
// so it moved to the fragment shader where it has no issues
//float intensity = length(hazeColor.xyz);
//hazeColor = intensity * normalize (mix(hazeColor, intensity * vec3 (1.0,1.0,1.0), 0.8* smoothstep(5000.0, 50000.0, alt)));
// Transform
gl_Position = gl_ModelViewProjectionMatrix * finalVertex;
}