Board index FlightGear Development Effects and shaders

Atmospheric scattering, with terrain shader preview

An exciting "new" option in FlightGear, that includes reflections, lightmaps, the particle system etc.. A lot is yet to be discovered/implemented!

Re: Atmospheric scattering, with terrain shader preview

Postby Thorsten » Wed Sep 21, 2011 8:32 am

Thanks for the video. I was looking for such material yesterday in order to calibrate the shader parameters at high altitude, but I didn't find so much. So this

Image

actually is quite a good guess :D Seeing clouds from above out to 150 km is a *real* problem. With the current setup, we can do 60-90 km dependent on direction (they're drawn as square tiles) if (and that's a big if) your computer can handle it. Being able to do 150 km would require to restructure the tile management code - but the numbers of objects needed to render is probably going to kill you long before.

One thing to note though is that one of the main effects of this shader is the sunrise/sunset effect near the horison. I'd feel bad to take that away by blending to some constant color...


Blending to constant below the horizon line is also not really what you want. It looks too artificial to be perceived as fog/haze. There needs to be some modulation in the angles. Currently, there's no problem above the horizon (sunrise/set looks nice there), but the region below the horizon gets colors at odds with the terrain.

The original vertex colors, that are used in the non shader version, are available in gl_FrontColor in the vertex shader. Might be possible to use the scattering shader above the horison, and below the cpu calculated old values.


Maybe I'll play with them and mix them in a bit - could work.

This is something I though should happen. I always thought that the coefficients would be calculated depending on the METAR, and the sky would then reflect the real weather, no manual editing of parameters needed.
(...)
I'm not sure if you're talking only about weather conditions, or also changing the parameters depending on altitude etc. I think the former is the correct way, and the latter is not.


That's not what METAR ever gives you. If visibility is bad, METAR reports the actual value on the ground. Say we have 2000 m. In bad visibility, I usually can't see the sky at all, either I see featureless fog above me (which the shader can't do - it doesn't grey out the zenith for any parameter) or I see distinct clouds above me and a dark horizon line reflecting the fact that the clouds filter out lots of light which doesn't reach the horizon line. Visibility will be *way* better than 2000 m once I reach above the fog/cloud layer - but METAR contains zero information how good it actually will be at what altitude. Currently we have to guess that.

If visibility is good, you can see the sky from the ground, but METAR tends to report either 10 km or 10 miles - in this case, you don't even know the real visibility on the ground, you just know that it's larger than the reported value.

I suspect that in the region where the shader is consistently working fine, say above 20.000 ft or so, to a good approximation the real weather conditions on the ground don't really matter so much for the appearance of the sky any more and the density of scatterers is largely given by altitude.

Real weather conditions are largely stuff that makes the shader fail because there's no code to handle it (non-exponential density distribution of scatterers, optically thick limit, light absorption by cloud layers...), so I'm not sure how far you get by trying to tie shader parameters to real weather.

I'd like to see a model which would simulate clear sky, fog, rain and smoke for example, to allow for very different looking skies with just few parameters which are easily figured from METAR. And the same model should be applied to both terrain and sky, and it would give consistent and good looking results... I guess this model with added support for low visibility (and maybe layered fog?) would be a good start.


Agreed - it would be terrific to get it. But... how?

What's missing is:

* scattering equations for optically thick media (light diffusion)
* blending between optically thick and optically thin solution
* cross talk with weather system to get light absorption by cloud layers right
* support for non-exponential distribution of Rayleigh and Mie scatterers independently

and all running at decent framerate... That's a lot of math, but it can be done. But in the general case, that's multiple nested integrals without an analytical approximation, and that's not going to be fast.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: What/Where did you fly today?

Postby erik » Thu Sep 22, 2011 8:23 am

This is starting to look great. I might want to spent some time to adjust the non-shader sky coloring code to match the shader more closely which should (almost) eliminate the horizon problems.

Erik
Current: Parachutist, Paraglider, Pterosaur, Pilatus PC-9M and variants, ERCO Ercoupe, Fokker Dr.1, Fokker 50, Fokker 100
Less active: Cessna T-37, T-38, Santa Claus. Previous: General Dynamics F-16. Worked on: Wright Flyer
erik
 
Posts: 2245
Joined: Thu Nov 01, 2007 2:41 pm

Re: What/Where did you fly today?

Postby Thorsten » Thu Sep 22, 2011 12:34 pm

Erik, if you could work on the horizon issue, that'd be really terrific. My problem is that I roughly know what I want to do (mix the colors of the default shader in such that they blend with the terrain shader below the horizon where the scattering shader gives nonsense), but don't know enough GLSL to figure out how I transfer the info I need into the shader code...
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: What/Where did you fly today?

Postby i4dnf » Thu Sep 22, 2011 12:57 pm

Thorsten, I've been thinking some more about this, you're pretty close. To get it even closer I think you need to mix in the ambient colour into the horizon haze. IIRC ambient colour in our scene is gl_LightSource[0].diffuse (I might be wrong though).
i4dnf
Retired
 
Posts: 743
Joined: Wed Sep 09, 2009 8:17 am
Location: LRBS
Callsign: YR-I4D
Version: GIT
OS: Gentoo Linux ~amd64

Re: Atmospheric scattering, with terrain shader preview

Postby Gijs » Thu Sep 22, 2011 1:13 pm

Torsten posted some more images under viewtopic.php?p=137193#p137193
In order to keep athmospheric discussion in one place I moved some replies to this topic.
Airports: EHAM, EHLE, KSFO
Aircraft: 747-400
User avatar
Gijs
Moderator
 
Posts: 9544
Joined: Tue Jul 03, 2007 3:55 pm
Location: Delft, the Netherlands
Callsign: PH-GYS
Version: Git
OS: Windows 10

Re: Atmospheric scattering, with terrain shader preview

Postby Zan » Thu Sep 22, 2011 9:49 pm

The skydome.vert has this "intersection" function, which is used to detect if viewer is outside of the atmosphere, and limit calculations only to the inside. It could also be used to detect e.g. mean sea level, and render some color there. And because terrain is rendered over the skydome, it would not block deep valleys or anything.

Don't know if it is for any use, but just thought about it.

Something like this:
Code: Select all
float i_ground = intersection(cameraRealAltitude, -normalize(relativePosition), groundLevel*groundLevel);
if (i_ground >= 0.0) { // pixel would be blocked by earth (sphere with radius @ mean sea level
 // Do something different here
} else {
  // Normal color calculation
}


Didn't test the code, but Iirc that is the way it should work.

Zan
Zan
 
Posts: 123
Joined: Tue Oct 20, 2009 11:28 am

Re: Atmospheric scattering, with terrain shader preview

Postby Thorsten » Fri Sep 23, 2011 8:05 am

The original vertex colors, that are used in the non shader version, are available in gl_FrontColor in the vertex shader.


Tried that, but the shader complains that I can't access gl_FrontColor from where I need it...

I have a number of ideas that just might work, but often I simply lack the knowledge to get the info to where I need it.

1) Can anyone post a fragment of (tested) code that can give me access to the default skydome color of a pixel? Since that blends nicely with the terrain shader, it's the first fix I'd like to try to create something which blends better before going into the full gory details of a dedicated terrain shader.

2) What is the color of the sun inside the shader? What is the position of the sun?

3) How do I get one or more property value at runtime into the shader code? I think adding support for one (several?) layers of optically thick fog layers of uniform density isn't that complicated (I know how to do it for the skydome, I think it'd also work for terrain in a similar way, and with several layers of constant density, you an already approximate any more complicated function), but the info where the layers are must be set in the tree and then brought into the shader.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Atmospheric scattering, with terrain shader preview

Postby Hooray » Fri Sep 23, 2011 3:15 pm

Thorsten wrote in Fri Sep 23, 2011 8:05 am:3) How do I get one or more property value at runtime into the shader code?


Generally, this works at the API level, i.e. parameters are passed by coding C++ and accessing the GLSL interface to pass certain hard-coded parameters (i.e. primitive types) to the driver/GLSL program. In other words, you need to hack the C++ code to expose new parameters/properties:

http://www.openscenegraph.org/projects/ ... Parameters
http://idlastro.gsfc.nasa.gov/idl_html_ ... ogram.html

So, one would need to provide a new API to shaders running inside FGFS so that they can request arbitrary properties to be used, I don't know if or how that could be made to work, though.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Atmospheric scattering, with terrain shader preview

Postby Thorsten » Fri Sep 23, 2011 3:41 pm

Generally, this works at the API level, i.e. parameters are passed by coding C++ and accessing the GLSL interface to pass certain hard-coded parameters (i.e. primitive types) to the driver/GLSL program


*grin* Found it myself by retro-engineering the flow of the rayleigh, mie and density parameters from menu to shader. You simply declare them as parameters referring to properties in the effect file, pass them to the shader where you declare the shader in the effect file and then retrieve them as uniform float parametername; in the header of the shader.

I'm currently teaching the skydome shader to respect overcast, light saturation and visibility settings - makes it appear less 'better than life' clear-coloured.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Atmospheric scattering, with terrain shader preview

Postby Hooray » Fri Sep 23, 2011 4:21 pm

Yes, I could however see this being pretty useful in general, i.e. a generic function to access properties from shaders (like Nasal's "getprop" API) - but I really don't know enough about shader programming to say if it's possible or feasible at all...

Basically, we would need a way to make a new function available that can access the property tree (or some cached readonly version of it) and read out a primitive value by accessing the property equivalent ...

To be honest, I don't think that will work at all - as far as I understand, shaders run as part of the driver core and there doesn't seem to be any way to "call back" into the host application.

I guess I need to do some reading to answer that reliably ;-)
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Atmospheric scattering, with terrain shader preview

Postby i4dnf » Fri Sep 23, 2011 4:27 pm

Hooray, what are you talking about? :P
It's already implemented in the effect/shader framework and it's been there for 1.5 years alredy :D
Last edited by i4dnf on Fri Sep 23, 2011 4:38 pm, edited 1 time in total.
i4dnf
Retired
 
Posts: 743
Joined: Wed Sep 09, 2009 8:17 am
Location: LRBS
Callsign: YR-I4D
Version: GIT
OS: Gentoo Linux ~amd64

Re: Atmospheric scattering, with terrain shader preview

Postby Hooray » Fri Sep 23, 2011 4:30 pm

great, if it really is!

Like I said already, I am not at all familiar with shaders ! (and haven't been very much involved in FG lately) :-)
Just reading http://gitorious.org/fg/fgdata/blobs/ma ... ME.effects
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Atmospheric scattering, with terrain shader preview

Postby Zan » Sat Sep 24, 2011 2:38 pm

Thorsten wrote in Fri Sep 23, 2011 8:05 am:1) Can anyone post a fragment of (tested) code that can give me access to the default skydome color of a pixel? Since that blends nicely with the terrain shader, it's the first fix I'd like to try to create something which blends better before going into the full gory details of a dedicated terrain shader.


You need to add this line to the top of vertex and fragment programs, to the end of the other "varying ..." things:
Code: Select all
varying vec3 originalColor;


And then to the end of the vertex program, just before the closing "}", add:
Code: Select all
originalColor = gl_Color.rgb;


Then you can use that "originalColor" variable in the fragment program. Though, to really get the correct color, you must also replace in the vertex shader:
Code: Select all
gl_Position = gl_ModelViewProjectionMatrix * finalVertex;

with
Code: Select all
gl_Position = ftransform();

which most likely breaks the scattering shader functionality. The reason for this is that the shader uses scaling function to scale the skydome to match earth curvature and moves it down depending on the altitude. The normal, non-shader, skydome instead uses a small sphere which is always at ground level...

Anyways, in some cases you must cast it to vec4 (so that it includes the alpha) like this:
Code: Select all
... vec4(originalColor, 1.0) ...

which makes the alpha value 1.0. Just add your own calculations in place of "...". You might need it or not, depends on the types. GLSL does not usually support implicit casts to other types...

2) What is the color of the sun inside the shader? What is the position of the sun?

I use the "sunIntensity" parameter, it is defined at the top of vertex shader.

3) How do I get one or more property value at runtime into the shader code? I think adding support for one (several?) layers of optically thick fog layers of uniform density isn't that complicated (I know how to do it for the skydome, I think it'd also work for terrain in a similar way, and with several layers of constant density, you an already approximate any more complicated function), but the info where the layers are must be set in the tree and then brought into the shader.

You already figured this out I think, but the parameters are defined as "uniform <type> <name>" in the vertex or fragment programs, and then the same name is used in the .eff file to define which property/value/something is passed to the shader. The values are always defined per frame or per object, you cannot change them while rendering one object. There are ways for that, but they require changing C++ code (or maybe using .osg format objects, I don't know...)

Zan
Zan
 
Posts: 123
Joined: Tue Oct 20, 2009 11:28 am

Re: Atmospheric scattering, with terrain shader preview

Postby Thorsten » Sun Sep 25, 2011 7:27 pm

Though, to really get the correct color, you must also replace in the vertex shader:

Code: Select all
gl_Position = gl_ModelViewProjectionMatrix * finalVertex;


with

Code: Select all
gl_Position = ftransform();


which most likely breaks the scattering shader functionality.


Hm, unfortunately that is the show stopper. :( Anyway, I'm thinking of doing it in more detail anyway with a more sophisticated terrain shader. I have derived the equations for an optically thick approximation within a finite layer, and this looks sort of plausible for the skydome. Are you interested to work on a terrain shader with me? I completely lack the knowledge to write one from scratch (no idea how effect files really work...), but if I could either get your previous version, or I give you a writeup of the equations so that you can add that to what you have, that'd be interesting. Let me know.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Atmospheric scattering, with terrain shader preview

Postby Thorsten » Mon Sep 26, 2011 10:29 pm

I've more or less finished adding an optically thick model to the shader. As of now, it allows to define a region of ground haze with a different visibility than the rest of the air with the parameters /environement/ground-visibility-m and /environment/ground-haze-tickness-m which Local Weather automatically sets. I'm not too fond of praising myself, but... I am rather pleased.

Sunrise with a warm sector tile (rather poor ground visibility):

Image

Same scene with cold sector tile (way higher overall visibility):

Image

Back to scene 1 just about clearing the ground haze

Image

Clouds 'swimming' in the soup of ground haze (really needs a dedicated terrain shader... but I've always so much wanted to be able to do this!)

Image

Also works with the global weather settings (just the shader control properties need to be set manually). Two pics showing the effect of layer thickness: Ground visibility 16000 m, layer thickness 1300 m:

Image

... and layer thickness up to 2600 m - looks visually thicker, but also blocks more light and appears thus darker at the horizon.

Image

Still missing: If the sun is low, sunlight doesn't reach everywhere - it should be possible to compute a rim of shadow to improve the sunsets a bit. Various bits, odds and ends - like color changes by light absorption. And the terrain shader of course - it'd be terrific to see mountains reach above the ground haze and such things. I'm pretty sure that the equations work well - I just haven't any clue where to put them...
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

PreviousNext

Return to Effects and shaders

Who is online

Users browsing this forum: No registered users and 10 guests