Board index FlightGear Support osgEarth

osgEarth with airport lighting and structures

osgEarth renders the terrain scene by building the textured geometry at runtime from raw source imagery and elevation data. An experimental FlightGear integration is currently available.

Re: osgEarth with airport lighting and structures

Postby poweroftwo » Mon Jun 16, 2014 7:20 pm

-- Fog ---

an additional note about the current fog implementation (FG / osgEarth) that adds a slight twist and why the fog in the high altitude image shown above looks different. I am scaling visibility based on AGL of the eyepoint in order to see further into the distance. Near ground level, scaling is unity, as you get higher, visibility is increased. Not ideal but it works effectively.
poweroftwo
 
Posts: 100
Joined: Tue Mar 05, 2013 3:35 am
Location: USA - Alabama

Re: osgEarth with airport lighting and structures

Postby poweroftwo » Tue Jun 17, 2014 5:07 am

Esri recently updated the ArcGis World imagery at multiple LODs. TerraColor 15m imagery is now displayed globally which eliminates much of the previous unbalanced colored low resolution tiles. It's a big improvement when transitioning among the levels of detail.

Here is the esri article:
http://blogs.esri.com/esri/arcgis/2014/06/12/world-imagery-updated-at-multiple-scales/

Image
Flightgear/osgEarth with new ArcGis world imagery

Image
Flightgear/osgEarth with old ArcGis world imagery

If you are currently using the Flightgear / osgEarth integration, remove you ArcGis file cache and allow it rebuild to enjoy the updated imagery.
poweroftwo
 
Posts: 100
Joined: Tue Mar 05, 2013 3:35 am
Location: USA - Alabama

Re: osgEarth with airport lighting and structures

Postby Thorsten » Tue Jun 17, 2014 6:12 am

an additional note about the current fog implementation (FG / osgEarth) that adds a slight twist and why the fog in the high altitude image shown above looks different. I am scaling visibility based on AGL of the eyepoint in order to see further into the distance. Near ground level, scaling is unity, as you get higher, visibility is increased. Not ideal but it works effectively.


The crucial thing is that at the edge of the terrain, skydome and 100% fogged terrain must match in color at every point. And that's generically difficult, because the skydome isn't a real object which can be fogged like any other object, it doesn't have a real distance and it can't be fogged isotropically, but must be fogged as function of altitude.

I think if you want to render from high altitude and have plausible visuals, you can't use scaled isotropic fog, you need to define a separate ground layer like ALS does.

At some level, osgEarth must just be a textured mesh - so you should be able to assign an effect to it just like one can do for a model. And would guess that a normal terrain shader would crunch it just fine.

So the first question would be - what is your skydome? Is it from FG or does it come from osgEarth somehow?


With regard to overlay texturing - it's not difficult and I know how to do that, but the info on what overlay textures to use must somehow go into the shader. In native FG scenery, we texture each triangle by landclass, and in the definition file of the landclass is the information what texture, overlay textures and other parameters should be used by the shader. For osgEarth, we would need something equivalent, something that 'tags' a pixel as belonging to desert rather than road. This can be a meta-texture for the scene into which this is coded, theoretically the landclass info, ...

I'll take a look into the osg shaders you linked, but conceptually I'd prefer to use FG-native fog, as this is already interfaced with the weather system (including the altitude dependence...).
Thorsten
 
Posts: 10986
Joined: Mon Nov 02, 2009 8:33 am

Re: osgEarth with airport lighting and structures

Postby poweroftwo » Tue Jun 17, 2014 3:27 pm

I think if you want to render from high altitude and have plausible visuals, you can't use scaled isotropic fog, you need to define a separate ground layer like ALS does.


thanks, sounds right. I will consider it.

So the first question would be - what is your skydome? Is it from FG or does it come from osgEarth somehow?

For now, the skydome is FG's.

I'll take a look into the osg shaders you linked, but conceptually I'd prefer to use FG-native fog, as this is already interfaced with the weather system (including the altitude dependence...).


yep, I understand. Might be difficult though.

thanks,
jeff
poweroftwo
 
Posts: 100
Joined: Tue Mar 05, 2013 3:35 am
Location: USA - Alabama

Re: osgEarth with airport lighting and structures

Postby Thorsten » Tue Jun 17, 2014 5:44 pm

Well... if the current skydome is ALS, then the ALS functions have to go to certain injection points to make it consistent.

Something like this



Code: Select all
 /// BEGIN geometry for light

    vec3 up = (gl_ModelViewMatrix * vec4(0.0,0.0,1.0,0.0)).xyz;
    //vec4 worldPos3D = (osg_ViewMatrixInverse * vec4 (0.0,0.0,0.0, 1.0));
    //worldPos3D.a = 0.0;
    //vec3 up = (osg_ViewMatrix * worldPos3D).xyz;
    float dist = length(vertVec);
    float vertex_alt = max(100.0,dot(up, vertVec) + alt);
    float vertex_scattering = ground_scattering + (1.0 - ground_scattering) * smoothstep(hazeLayerAltitude -100.0, hazeLayerAltitude + 100.0, vertex_alt);


    vec3 lightHorizon = gl_LightSource[0].position.xyz - up * dot(up,gl_LightSource[0].position.xyz);
    float yprime = -dot(vertVec, lightHorizon);
    float yprime_alt = yprime - sqrt(2.0 * EarthRadius * vertex_alt);
    float lightArg = (terminator-yprime_alt)/100000.0;

    float earthShade = 0.6 * (1.0 - smoothstep(-terminator_width+ terminator, terminator_width + terminator, yprime_alt)) + 0.4;

    float mie_angle;
    if (lightArg < 10.0)
        {mie_angle = (0.5 *  dot(normalize(vertVec), normalize(gl_LightSource[0].position.xyz)) ) + 0.5;}
    else
        {mie_angle = 1.0;}

    float fog_vertex_alt = max(vertex_alt,hazeLayerAltitude);
    float fog_yprime_alt = yprime_alt;
    if (fog_vertex_alt > hazeLayerAltitude)
        {
        if (dist > 0.8 * avisibility)
            {
            fog_vertex_alt = mix(fog_vertex_alt, hazeLayerAltitude, smoothstep(0.8*avisibility, avisibility, dist));
            fog_yprime_alt = yprime -sqrt(2.0 * EarthRadius * fog_vertex_alt);
            }
        }
    else
        {
        fog_vertex_alt = hazeLayerAltitude;
        fog_yprime_alt = yprime -sqrt(2.0 * EarthRadius * fog_vertex_alt);
        }

    float fog_lightArg = (terminator-fog_yprime_alt)/100000.0;
    float fog_earthShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, fog_yprime_alt) + 0.1;

    float ct = dot(normalize(up), normalize(vertVec));

    /// END geometry for light


needs to go to LOCATION_VERTEX_MODEL

Then this

Code: Select all
/// BEGIN light
    vec4 light_diffuse;
    vec4 light_ambient;
    float intensity;

    light_diffuse.b = light_func(lightArg, 1.330e-05, 0.264, 3.827, 1.08e-05, 1.0);
    light_diffuse.g = light_func(lightArg, 3.931e-06, 0.264, 3.827, 7.93e-06, 1.0);
    light_diffuse.r = light_func(lightArg, 8.305e-06, 0.161, 3.827, 3.04e-05, 1.0);
    light_diffuse.a = 1.0;
    light_diffuse = light_diffuse * vertex_scattering;

    light_ambient.r = light_func(lightArg, 0.236, 0.253, 1.073, 0.572, 0.33);
    light_ambient.g = light_ambient.r * 0.4/0.33;
    light_ambient.b = light_ambient.r * 0.5/0.33;
    light_ambient.a = 1.0;

    if (earthShade < 0.5)
        {
        intensity = length(light_ambient.rgb);
        light_ambient.rgb = intensity * normalize(mix(light_ambient.rgb,  shadedFogColor, 1.0 -smoothstep(0.1, 0.8,earthShade) ));
        light_ambient.rgb = light_ambient.rgb +   moonLightColor *  (1.0 - smoothstep(0.4, 0.5, earthShade));

        intensity = length(light_diffuse.rgb);
        light_diffuse.rgb = intensity * normalize(mix(light_diffuse.rgb,  shadedFogColor, 1.0 -smoothstep(0.1, 0.7,earthShade) ));
        }


    /// END light


goes to LOCATION_FRAGMENT_lighting

Code: Select all
/// BEGIN fog amount

    float transmission;
    float vAltitude;
    float delta_zv;
    float H;
    float distance_in_layer;
    float transmission_arg;
    float eqColorFactor;

    float delta_z = hazeLayerAltitude - eye_alt;

    if (dist > max(40.0, 0.04 * min(visibility,avisibility)))
        {
        if (delta_z > 0.0) // we're inside the layer
            {
            if (ct < 0.0) // we look down
                {
                distance_in_layer = dist;
                vAltitude = min(distance_in_layer,min(visibility, avisibility)) * ct;
                delta_zv = delta_z - vAltitude;
                }
            else    // we may look through upper layer edge
                {
                H = dist * ct;
                if (H > delta_z) {distance_in_layer = dist/H * delta_z;}
                else {distance_in_layer = dist;}
                vAltitude = min(distance_in_layer,visibility) * ct;
                delta_zv = delta_z - vAltitude;   
                }
            }
        else // we see the layer from above, delta_z < 0.0
            {   
            H = dist * -ct;
            if (H  < (-delta_z)) // we don't see into the layer at all, aloft visibility is the only fading
                {
                distance_in_layer = 0.0;
                delta_zv = 0.0;
                }      
            else
                {
                vAltitude = H + delta_z;
                distance_in_layer = vAltitude/H * dist;
                vAltitude = min(distance_in_layer,visibility) * (-ct);
                delta_zv = vAltitude;
                }
            }

        transmission_arg = (dist-distance_in_layer)/avisibility;


        if (visibility < avisibility)
            {
            transmission_arg = transmission_arg + (distance_in_layer/visibility);
            eqColorFactor = 1.0 - 0.1 * delta_zv/visibility - (1.0 -effective_scattering);
            }
        else
            {
            transmission_arg = transmission_arg + (distance_in_layer/avisibility);
            eqColorFactor = 1.0 - 0.1 * delta_zv/avisibility - (1.0 -effective_scattering);
            }
        transmission =  fog_func(transmission_arg, alt);
        if (eqColorFactor < 0.2) eqColorFactor = 0.2;
        }
    else
        {
        eqColorFactor = 1.0;
        transmission = 1.0;
        }

    /// END fog amount


and

Code: Select all
/// BEGIN fog color

    vec3 hazeColor;

    if (transmission<  1.0)
        {

        hazeColor.b = light_func(fog_lightArg-0.5, 1.330e-05, 0.264, 2.527, 1.08e-05, 1.0);
        hazeColor.g = light_func(fog_lightArg-0.5, 3.931e-06, 0.264, 3.827, 7.93e-06, 1.0);
        hazeColor.r = light_func(fog_lightArg-0.5, 8.305e-06, 0.161, 3.827, 3.04e-05, 1.0);

        if (fog_lightArg < 10.0)
            {
            intensity = length(hazeColor);
            float mie_magnitude = 0.5 * smoothstep(350000.0, 150000.0, terminator-sqrt(2.0 * EarthRadius * terrain_alt));
            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)) );
            }

        intensity = length(hazeColor);
        hazeColor = intensity * normalize (mix(hazeColor, intensity * vec3 (1.0,1.0,1.0), 0.7* smoothstep(5000.0, 50000.0, alt)));

        hazeColor.r = hazeColor.r * 0.83;
        hazeColor.g = hazeColor.g * 0.9;

        float fade_out = max(0.65 - 0.3 *overcast, 0.45);
        intensity = length(hazeColor);
        hazeColor = intensity * normalize(mix(hazeColor,  1.5* shadedFogColor, 1.0 -smoothstep(0.25, fade_out,fog_earthShade) ));
        hazeColor = intensity * normalize(mix(hazeColor,  shadedFogColor, (1.0-smoothstep(0.5,0.9,eqColorFactor))));

        float shadow = mix( min(1.0 + dot(VNormal,gl_LightSource[0].position.xyz),1.0), 1.0, 1.0-smoothstep(0.1, 0.4, transmission));
        hazeColor = mix(shadow * hazeColor, hazeColor, 0.3 + 0.7* smoothstep(250000.0, 400000.0, terminator));
        }
    else
        {
        hazeColor = vec3 (1.0, 1.0, 1.0);
        }


    /// END fog color
    fragColor = clamp(fragColor, 0.0, 1.0);
    fragColor.rgb = mix(eqColorFactor * hazeColor * fog_earthShade, fragColor.rgb,transmission);
    gl_FragColor = fragColor;
    }


then need to go below that. Then the main challenge is to pass all uniforms properly and to match all the varyings, which is a dreadful business... So I think conceptually it's all doable using the injection points, but in practice it's messy...

But with this skydome, that's your only option to make it consistent. So... how good are your GLSL skills?
Thorsten
 
Posts: 10986
Joined: Mon Nov 02, 2009 8:33 am

Re: osgEarth with airport lighting and structures

Postby poweroftwo » Wed Jun 18, 2014 2:57 pm

Thorsten,

Thanks for the pointers. I will investigate.

jeff
poweroftwo
 
Posts: 100
Joined: Tue Mar 05, 2013 3:35 am
Location: USA - Alabama

Previous

Return to osgEarth

Who is online

Users browsing this forum: No registered users and 1 guest