Board index FlightGear Development Effects and shaders

Implementing moonlight (or not)

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

Implementing moonlight (or not)

Postby bugman » Fri Dec 04, 2015 3:49 pm

Some posts were split off from the topic Light scattering on hazes.


Thorsten wrote in Fri Dec 04, 2015 3:35 pm:
I hope you also consider adding these effects to the moon as well That could make winter night flying quite spectacular!


Considering as in 'Would be cool to have!' - definitely. Considering as in actually implementing - no. The renderer currently has no idea where the moon is, so it can't be done without touching the C++ side and introducing a new uniform vec3 with the information.


Sounds like you're laying down a challenge :) Where is the sun information exposed?

Regards,
Edward
Last edited by Johan G on Sat Dec 05, 2015 5:13 pm, edited 1 time in total.
Reason: Some posts were split off from the topic "Light scattering on hazes".
bugman
Moderator
 
Posts: 1524
Joined: Thu Mar 19, 2015 9:01 am
Version: next

Re: Light scattering on hazes

Postby Thorsten » Fri Dec 04, 2015 4:16 pm

The sun is the main light source for the renderer, so it's gl_LightSource[0].position.xyz (in eye space). On the C++ side, it's going to be a standard part of the stateset.
Thorsten
 
Posts: 9539
Joined: Mon Nov 02, 2009 8:33 am

Re: Light scattering on hazes

Postby bugman » Fri Dec 04, 2015 4:33 pm

Ok, then maybe we need to set up a second OSG light source for the moon and reserve it at gl_LightSource[1]. I guess this will then be a bit more complex! I also guess that we don't currently have the moon reflected in the water, or the moon lighting up the landscape, so this could have a lot of benefits!

Regards,
Edward

Edit: My idea no longer looks so original ;) - [flightgear-devel] Moonlight reloaded.
Last edited by bugman on Fri Dec 04, 2015 5:02 pm, edited 1 time in total.
bugman
Moderator
 
Posts: 1524
Joined: Thu Mar 19, 2015 9:01 am
Version: next

Re: Light scattering on hazes

Postby wkitty42 » Fri Dec 04, 2015 5:33 pm

bugman wrote in Fri Dec 04, 2015 4:33 pm:I also guess that we don't currently have the moon reflected in the water,

i just tested this and you are right... no moon reflection on the water...

bugman wrote in Fri Dec 04, 2015 4:33 pm:or the moon lighting up the landscape,

this is currently a manual slider in Menu->Environment->Environment Settings... it is what i speak of above as having FGFS to move it based on the phase of the moon since it knows what the phase is...
"You get more air close to the ground," said Angalo. "I read that in a book. You get lots of air low down, and not much when you go up."
"Why not?" said Gurder.
"Dunno. It's frightened of heights, I guess."
User avatar
wkitty42
 
Posts: 4539
Joined: Fri Feb 20, 2015 3:46 pm
Location: central NC, USA
Callsign: wk42
Version: git next
OS: Kubuntu 14.04.5

Re: Light scattering on hazes

Postby bugman » Fri Dec 04, 2015 5:52 pm

wkitty42 wrote in Fri Dec 04, 2015 5:33 pm:
bugman wrote in Fri Dec 04, 2015 4:33 pm:or the moon lighting up the landscape,

this is currently a manual slider in Menu->Environment->Environment Settings... it is what i speak of above as having FGFS to move it based on the phase of the moon since it knows what the phase is...


This is not quite the same thing as if I were to drop a real light source into the GL scene. That might open up the possibility of water reflections, cloud scattering (Mie, Rayleigh, and diffuse), real terrain lighting based on the light source with an intensity proportional to the moon phase, and the optical phenomena Thorsten is looking at here. I.e. treated pretty much like a mini-sun, excluding the effects it has on the atmosphere.

Regards,

Edward
bugman
Moderator
 
Posts: 1524
Joined: Thu Mar 19, 2015 9:01 am
Version: next

Re: Light scattering on hazes

Postby bugman » Fri Dec 04, 2015 6:32 pm

Thorsten wrote in Fri Dec 04, 2015 6:00 pm:A second real light source will drag framerate though... it costs whether you use it or not.


I wonder if there is a way of turning one off when the other is on? Assuming:

    gl_LightSource[0] -> sun
    gl_LightSource[1] -> moon

It would probably work quite well to assume that if there is any sun lighting, there will be no noticeable moon lighting. I wonder if using the osg::LightSource::setStateSetModes() function would do this? Having only one active light source would avoid the framerate issues - the moon lighting would have the same impact as the sun lighting (well, a little less as it doesn't have an effect on sky colour). It also looks like we use something similar in src/Viewer/renderer.cxx, with the isSun flag in the FGLightSourceUpdateCallback class:

Code: Select all
class FGLightSourceUpdateCallback : public osg::NodeCallback {
public:
 
  /**
   * @param isSun true if the light is the actual sun i.e., for
   * illuminating the moon.
   */
  FGLightSourceUpdateCallback(bool isSun = false) : _isSun(isSun) {}
  FGLightSourceUpdateCallback(const FGLightSourceUpdateCallback& nc,
                              const CopyOp& op)
    : NodeCallback(nc, op), _isSun(nc._isSun)
  {}
  META_Object(flightgear,FGLightSourceUpdateCallback);

  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
  {
    assert(dynamic_cast<osg::LightSource*>(node));
    osg::LightSource* lightSource = static_cast<osg::LightSource*>(node);
    osg::Light* light = lightSource->getLight();
   
    FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
      if (!l) {
          // lighting is down during re-init
          return;
      }
     
    if (_isSun) {
      light->setAmbient(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
      light->setDiffuse(Vec4(1.0f, 1.0f, 1.0f, 1.0f));
      light->setSpecular(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
    } else {
      light->setAmbient(toOsg(l->scene_ambient()));
      light->setDiffuse(toOsg(l->scene_diffuse()));
      light->setSpecular(toOsg(l->scene_specular()));
    }
    osg::Vec4f position(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2], 0);
    light->setPosition(position);

    traverse(node, nv);
  }
private:
  const bool _isSun;
};


Just introduce a _isMoon flag, and have a construct:

Code: Select all
if (_isSun) {
  ...
} else if (_isMoon) {
  ...
} else {
  ...
}


Also, looking a bit further at the sun_vec construct, there is already a moon_vec in src/Time/light.cxx. It should be trivial to extend the moon_vec to match sun_vec:

Code: Select all
[edward@localhost flightgear-flightgear (next)]$
  BRANCH: next  (d56fbfd) / 19 uncommitted changes / STASHES: 1                                                                                                                                                   
$ grep "sun_vec\|moon_vec" src/Time/light.*xx
src/Time/light.cxx:      _sun_vec(0, 0, 0, 0),
src/Time/light.cxx:      _moon_vec(0, 0, 0, 0),
src/Time/light.cxx:      _sun_vec_inv(0, 0, 0, 0),
src/Time/light.cxx:      _moon_vec_inv(0, 0, 0, 0),
src/Time/light.cxx:    tie(prop,"/ephemeris/sun/local/x", SGRawValuePointer<float>(&_sun_vec[0]));
src/Time/light.cxx:    tie(prop,"/ephemeris/sun/local/y", SGRawValuePointer<float>(&_sun_vec[1]));
src/Time/light.cxx:    tie(prop,"/ephemeris/sun/local/z", SGRawValuePointer<float>(&_sun_vec[2]));
src/Time/light.cxx:    _sun_vec = SGVec4f(toVec3f(normalize(sunpos)), 0);
src/Time/light.cxx:    _sun_vec_inv = - _sun_vec;
src/Time/light.cxx:    SGVec3d local_sun_vec = hlOr.transform(nsun);
src/Time/light.cxx:    // y-positive pointing East we need to negate local_sun_vec.x()
src/Time/light.cxx:    _sun_rotation = atan2(local_sun_vec.y(), -local_sun_vec.x());
src/Time/light.hxx:    SGVec4f _sun_vec, _moon_vec;
src/Time/light.hxx:    SGVec4f _sun_vec_inv, _moon_vec_inv;
src/Time/light.hxx:    inline SGVec4f& sun_vec () { return _sun_vec; }
src/Time/light.hxx:    inline SGVec4f& sun_vec_inv () { return _sun_vec_inv; }
src/Time/light.hxx:    inline const SGVec4f& moon_vec () const { return _moon_vec; }
src/Time/light.hxx:    inline const SGVec4f& moon_vec_inv () const { return _moon_vec_inv; }
[edward@localhost flightgear-flightgear (next)]$


Anyway, maybe I should ask to have these messages spun off into a new thread.

Regards,
Edward
bugman
Moderator
 
Posts: 1524
Joined: Thu Mar 19, 2015 9:01 am
Version: next

Re: Light scattering on hazes

Postby wkitty42 » Sat Dec 05, 2015 12:44 am

bugman wrote in Fri Dec 04, 2015 5:52 pm:
wkitty42 wrote in Fri Dec 04, 2015 5:33 pm:this is currently a manual slider in Menu->Environment->Environment Settings... it is what i speak of above as having FGFS to move it based on the phase of the moon since it knows what the phase is...


This is not quite the same thing as if I were to drop a real light source into the GL scene.

right... i understand that... my original comment was directed more at since fgfs apparently knows the phase of the moon, it could adjust that slider for the current lighting condition... then you brought up about having the moon as an additional lighting source... that then brings up the slider being tied into that for proper lighting, too... currently the only thing i can see the slider doing is brightening the landscape and clouds when it is cranked up but that is also separate from the actual phase of the moon which i was suggesting that FGFS handle automatically... this additional light source idea is the next step and would be really great, IMHO... the details are important... we may not always see those that are missing but when we do, they jump out like the bogey man and tend to detract from the overall look and feel...

bugman wrote in Fri Dec 04, 2015 5:52 pm:That might open up the possibility of water reflections, cloud scattering (Mie, Rayleigh, and diffuse), real terrain lighting based on the light source with an intensity proportional to the moon phase, and the optical phenomena Thorsten is looking at here. I.e. treated pretty much like a mini-sun, excluding the effects it has on the atmosphere.

i'm looking at the possibility of the sim getting smarter with regards to the light reflected off the moon in its various phases and how that affects the lighting of the clouds and ground scenery... i do agree that the moon should be an additional light source for several reasons... one being to have moon light shadows as well as the above automatic and proper lighting of the clouds and scenery as well as the big positive of having the moon's reflection on water...

it may be too much to ask at this time but it is something that i believe should be placed on the TODO list ;)
Last edited by wkitty42 on Sat Dec 05, 2015 1:13 am, edited 2 times in total.
"You get more air close to the ground," said Angalo. "I read that in a book. You get lots of air low down, and not much when you go up."
"Why not?" said Gurder.
"Dunno. It's frightened of heights, I guess."
User avatar
wkitty42
 
Posts: 4539
Joined: Fri Feb 20, 2015 3:46 pm
Location: central NC, USA
Callsign: wk42
Version: git next
OS: Kubuntu 14.04.5

Re: Light scattering on hazes

Postby gsagostinho » Sat Dec 05, 2015 12:47 am

wkitty42 wrote in Sat Dec 05, 2015 12:44 am:[...] since fgfs apparently knows the phase of the moon, it could adjust that slider for the current lighting condition...


That's a nice idea which (I believe) could be very simple to implement, right?
User avatar
gsagostinho
 
Posts: 1762
Joined: Thu Jan 15, 2015 6:27 pm
Location: London, UK

Re: Light scattering on hazes

Postby wkitty42 » Sat Dec 05, 2015 1:09 am

bugman wrote in Fri Dec 04, 2015 6:32 pm:
Thorsten wrote in Fri Dec 04, 2015 6:00 pm:A second real light source will drag framerate though... it costs whether you use it or not.


I wonder if there is a way of turning one off when the other is on? Assuming:

    gl_LightSource[0] -> sun
    gl_LightSource[1] -> moon

It would probably work quite well to assume that if there is any sun lighting, there will be no noticeable moon lighting.

my thoughts, exactly... especially with the few times that i have contributed my machines to distributed and local rendering tasks that had more than one light source...

in a worse case scenario, a check box and a --prop: can be added to the sim for realistic lighting including moon lighting...

and that also brings up ""true realism"" where even lamp poles can be added as additional light sources and with certain ground fog scenarios possibly even lead to those emitting rainbows when viewed from the proper angles... the key is to enable and disable those that don't apply to the current viewing angle... in other words, don't process all of them right now... only process those that pertain to the current view...

yeah, i know... after 30+ years coding numerous business oriented apps, the devil is in the details... ""good enough"" never really is when it comes down to brass tacks ;) :mrgreen:
"You get more air close to the ground," said Angalo. "I read that in a book. You get lots of air low down, and not much when you go up."
"Why not?" said Gurder.
"Dunno. It's frightened of heights, I guess."
User avatar
wkitty42
 
Posts: 4539
Joined: Fri Feb 20, 2015 3:46 pm
Location: central NC, USA
Callsign: wk42
Version: git next
OS: Kubuntu 14.04.5

Re: Light scattering on hazes

Postby wkitty42 » Sat Dec 05, 2015 1:10 am

bugman wrote in Fri Dec 04, 2015 6:32 pm:Anyway, maybe I should ask to have these messages spun off into a new thread.

that works for me... not that i can contribute anything more than observations and ideas based on my past coding experiences...
"You get more air close to the ground," said Angalo. "I read that in a book. You get lots of air low down, and not much when you go up."
"Why not?" said Gurder.
"Dunno. It's frightened of heights, I guess."
User avatar
wkitty42
 
Posts: 4539
Joined: Fri Feb 20, 2015 3:46 pm
Location: central NC, USA
Callsign: wk42
Version: git next
OS: Kubuntu 14.04.5

Re: Light scattering on hazes

Postby wkitty42 » Sat Dec 05, 2015 1:14 am

gsagostinho wrote in Sat Dec 05, 2015 12:47 am:
wkitty42 wrote in Sat Dec 05, 2015 12:44 am:[...] since fgfs apparently knows the phase of the moon, it could adjust that slider for the current lighting condition...


That's a nice idea which (I believe) could be very simple to implement, right?

my (positive) vote is already in :)
"You get more air close to the ground," said Angalo. "I read that in a book. You get lots of air low down, and not much when you go up."
"Why not?" said Gurder.
"Dunno. It's frightened of heights, I guess."
User avatar
wkitty42
 
Posts: 4539
Joined: Fri Feb 20, 2015 3:46 pm
Location: central NC, USA
Callsign: wk42
Version: git next
OS: Kubuntu 14.04.5

Re: Light scattering on hazes

Postby Thorsten » Sat Dec 05, 2015 7:18 am

since fgfs apparently knows the phase of the moon, it could adjust that slider for the current lighting condition...


Except FG really doesn't know the phase of the moon.

The moon actually is a real sphere in FG, and it's the only object coming with its own light source (because it has to be always white regardless of how sunlight appears on the ground). The sphere is moved around by the moon orbital code (including perturbations from Jupiter it seems) - so the moon phase emerges as a consequence of relative position between the moon's sun and the moon and the lighting equation on the screen.

There's no parameter anywhere in FG that tells you what the moon phase is.

Now, the actual code computes earth and planet orbits in double precision in a heliocentric coordinate system, but the moon goes around Earth, whereas the renderer operates in floating position, so no celestial object is at its true position as far as the renderer is concerned, and also the renderer doesn't know what geocentric is, it just does camera-centric.

So even something like getting pointing vectors to objects in the same coordinate system such as to do a dot product is not trivial in this context. I've actually spent some three hours reading through everything without finding the obvious position where to obtain the phase, and I've asked Durk (who wrote the celestial objects code in the first place) whether he'd know an obvious spot and he didn't know either.

That's the difference between 'could just' and actually doing it.

(Not that I wouldn't have tried, since the idea is so obvious even I got it back when I implemented the moonlight).

the key is to enable and disable those that don't apply to the current viewing angle... in other words, don't process all of them right now... only process those that pertain to the current view...


Thanks for teaching me optimization :-) Unfortunately, GLSL usually doesn't play along.

You'd think that if you do

if (condition)
{do something that takes 5 ms;}
else
{do something that takes 4 ms;}

you end up taking no more than 5 ms, but the sad reality is that under many conditions you will take 9 ms, because the way this is frequently processed is that the driver frequently thinks it wiser to evaluate first both branches fully and then decides which one to take (the reasons being connected with how a texture mapping internally is represented via gradiant fields and the need to avoid discontinuities).

Also, the condition to evaluate doesn't come free either - often it's surprisingly expensive because it's not just a simple a==b, it requires you to check on several environmental conditions and angles. And suddenly you save some work by not doing something, but you add workload by computing the condition - and you may in fact lose out on this.

So more often then not, the disabling thing doesn't work out the way you expect - the object disappears from view alright, but its performance footprint is still there. You can do this only under a rather limited set of conditions.

If you want to optimize shader code, you need to learn to think a different way. That's why I said in another thread that being able to read GLSL doesn't equal understanding why it's written the way it is or how it should be written :-)

in a worse case scenario, a check box and a --prop: can be added to the sim for realistic lighting including moon lighting...


Yeah, then you have a property somewhere. You still need to write an extra set of shaders to make use of it, because, as explained above, chains of 'if-statements' don't do the trick. You need to maintain the shaders, i.e. whenever you want to change something in, say, haze, you need to modify all these extra shaders as well. That's a lot of work.


I wonder if there is a way of turning one off when the other is on? Assuming:

gl_LightSource[0] -> sun
gl_LightSource[1] -> moon

It would probably work quite well to assume that if there is any sun lighting, there will be no noticeable moon lighting.


We're using sun position until sun is 15 deg below the horizon to compute dawn light in ALS - you'd screw that first. Furthermore, you'd immediately screw Rembrandt and default, since they don't know we're doing trickery with the light source and just faithfully use it 'as is'. You'd probably get some strong discontinuities in lighting, with the Moon suddenly flashing on. This could be all made to work in principle by delving into all shaders and smoothing over the discontinuities, passing flags on what to do etc,

Again, plenty of work.
Thorsten
 
Posts: 9539
Joined: Mon Nov 02, 2009 8:33 am

Re: Light scattering on hazes

Postby bugman » Sat Dec 05, 2015 5:00 pm

I'll take up your moonlight challenge :) Let's see how far it goes, if it goes anywhere at all!

Thorsten wrote in Sat Dec 05, 2015 7:18 am:
since fgfs apparently knows the phase of the moon, it could adjust that slider for the current lighting condition...


Except FG really doesn't know the phase of the moon.

The moon actually is a real sphere in FG, and it's the only object coming with its own light source (because it has to be always white regardless of how sunlight appears on the ground). The sphere is moved around by the moon orbital code (including perturbations from Jupiter it seems) - so the moon phase emerges as a consequence of relative position between the moon's sun and the moon and the lighting equation on the screen.

There's no parameter anywhere in FG that tells you what the moon phase is.

Now, the actual code computes earth and planet orbits in double precision in a heliocentric coordinate system, but the moon goes around Earth, whereas the renderer operates in floating position, so no celestial object is at its true position as far as the renderer is concerned, and also the renderer doesn't know what geocentric is, it just does camera-centric.

So even something like getting pointing vectors to objects in the same coordinate system such as to do a dot product is not trivial in this context. I've actually spent some three hours reading through everything without finding the obvious position where to obtain the phase, and I've asked Durk (who wrote the celestial objects code in the first place) whether he'd know an obvious spot and he didn't know either.


Great, the problem sounds even more interesting now! I'll look at the level of the OSG scene graph to set the light intensity using the c++ interface. This will give a lot more flexibility for coming up with an approximate algorithm for setting the intensity.

That's the difference between 'could just' and actually doing it.


It doesn't sound totally impossible :)


(Not that I wouldn't have tried, since the idea is so obvious even I got it back when I implemented the moonlight).


I would like to try a different approach. And that is to pretend that the moon is the sun, but with a far lower intensity.

the key is to enable and disable those that don't apply to the current viewing angle... in other words, don't process all of them right now... only process those that pertain to the current view...


Thanks for teaching me optimization :-) Unfortunately, GLSL usually doesn't play along.

You'd think that if you do

if (condition)
{do something that takes 5 ms;}
else
{do something that takes 4 ms;}

you end up taking no more than 5 ms, but the sad reality is that under many conditions you will take 9 ms, because the way this is frequently processed is that the driver frequently thinks it wiser to evaluate first both branches fully and then decides which one to take (the reasons being connected with how a texture mapping internally is represented via gradiant fields and the need to avoid discontinuities).


What if the conditionals are set up at the c++ OSG interface? I.e. direct modification of the scene graph set up rather than playing around with shaders.


Also, the condition to evaluate doesn't come free either - often it's surprisingly expensive because it's not just a simple a==b, it requires you to check on several environmental conditions and angles. And suddenly you save some work by not doing something, but you add workload by computing the condition - and you may in fact lose out on this.

So more often then not, the disabling thing doesn't work out the way you expect - the object disappears from view alright, but its performance footprint is still there. You can do this only under a rather limited set of conditions.


Would this also be the case if you even physically remove the light source from the scenegraph? I have to look into OSG more, but there might be a way of deactivating the light source itself so that it's cost is zero. Something like this should do the trick:

Code: Select all
state->setMode( GL_LIGHTING, osg::StateAttribute::OFF );


Otherwise we could just switch the lightsource position from that of the sun to that of the moon, and change its intensity. This approach should also have zero rendering cost. I would also like to test fps cost of 2 light sources in OSG.

If you want to optimize shader code, you need to learn to think a different way. That's why I said in another thread that being able to read GLSL doesn't equal understanding why it's written the way it is or how it should be written :-)


I'd prefer to optimise the scene graph set up instead. When it comes to the GLSL, depending on the effect, then maybe we could perform a weighted sum of the two light sources, with the weight equal to the light source intensity? Or we expose a single set of generic light source properties for the shaders to use? Then the shaders don't need to care between sun or moon, though that could be exposed as well.

in a worse case scenario, a check box and a --prop: can be added to the sim for realistic lighting including moon lighting...


Yeah, then you have a property somewhere. You still need to write an extra set of shaders to make use of it, because, as explained above, chains of 'if-statements' don't do the trick. You need to maintain the shaders, i.e. whenever you want to change something in, say, haze, you need to modify all these extra shaders as well. That's a lot of work.


If what I have in mind works, then you'll treat the moon lighting exactly the same way you treat the sun lighting.

I wonder if there is a way of turning one off when the other is on? Assuming:

gl_LightSource[0] -> sun
gl_LightSource[1] -> moon

It would probably work quite well to assume that if there is any sun lighting, there will be no noticeable moon lighting.


We're using sun position until sun is 15 deg below the horizon to compute dawn light in ALS - you'd screw that first. Furthermore, you'd immediately screw Rembrandt and default, since they don't know we're doing trickery with the light source and just faithfully use it 'as is'. You'd probably get some strong discontinuities in lighting, with the Moon suddenly flashing on. This could be all made to work in principle by delving into all shaders and smoothing over the discontinuities, passing flags on what to do etc,

Again, plenty of work.


Plenty of work sounds like another challenge! Here's another challenge - what about some Gegenschein ;) Anyway, there should be some ways to handle discontinuities. For example ramping up the moon light source from zero to the full moon intensity. I also have to look at the code for how we ramp down and turn off the sun light source. I'd do this all at the lower OSG c++ level rather than shader level. The first thing I might try out is setting up the correct moon vector and exposing it at /ephemeris/moon/local/{x,y,z}, etc. Then for light sources I might play with both a single source switching position and intensity, two light sources, testing their fps impact, and toggling between two light sources. Then to play around in FGData to see how the current shaders can be hooked up for the light sources. Something useful might come out of the experiments, even if it is just me learning about the FG rendering backend.

Regards,
Edward
bugman
Moderator
 
Posts: 1524
Joined: Thu Mar 19, 2015 9:01 am
Version: next

Re: Implementing moonlight (or not)

Postby Hooray » Sat Dec 05, 2015 5:39 pm

bugman wrote in Sat Dec 05, 2015 5:00 pm:What if the conditionals are set up at the c++ OSG interface? I.e. direct modification of the scene graph set up rather than playing around with shaders.
[...]
Would this also be the case if you even physically remove the light source from the scenegraph? I have to look into OSG more, but there might be a way of deactivating the light source itself so that it's cost is zero.


For pointers to the corresponding code, see the draw-mask patches I posted a while ago, to see where you can find the code that sets up the corresponding osg/opengl lights:
Image


Context: http://sourceforge.net/p/flightgear/fli ... .cxx#l1470

Subject: No go airports for weak gpus ...
Hooray wrote:I am probably going to add a few more draw-masks, also for Canvas - not because I believe that we need to run FG without Canvas :lol: , but to provide stats/evidence for benchmarking purposes, i.e. we can tell people to use those draw masks to disable all CanvasGUI/CanvasScenery/CanvasAircraft rendering and watch their frame rate/spacing accordingly.

For the "fgcanvas" mode, this just means that sky/sunlight and PUI rendering can be completely disabled for even better performance/appearance, i.e. Nasal/Canvas are up and running in under 5 seconds here normally. Likewise, this is a good thing for debugging and regression testing, i.e. to keep certain rendering features completely disabled - for example so that only Canvas related OSG/OpenGL calls show up in the gDebugger profile, i.e. much more fine-grained info, without having to patch FG.

Code: Select all
diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx
index 2c4d5c7..d3ba9a6 100644
--- a/src/Viewer/renderer.cxx
+++ b/src/Viewer/renderer.cxx
@@ -82,7 +82,10 @@
 #include <simgear/scene/tgdb/pt_lights.hxx>
 #include <simgear/scene/tgdb/userdata.hxx>
 #include <simgear/structure/OSGUtils.hxx>
+
 #include <simgear/props/props.hxx>
+#include <simgear/props/propertyObject.hxx>
+
 #include <simgear/timing/sg_time.hxx>
 #include <simgear/ephemeris/ephemeris.hxx>
 #include <simgear/math/sg_random.h>
@@ -380,9 +383,60 @@ public:
 
   static bool scenery_enabled;
 };
-
 bool FGScenerySwitchCallback::scenery_enabled = false;
 
+// update callback for the sky switch node
+struct FGSkySwitchCallback : public osg::NodeCallback {
+  FGSkySwitchCallback() : _enabled("/sim/rendering/draw-mask/sky") {}
+
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+  {
+    assert(dynamic_cast<osg::Switch*>(node));
+    osg::Switch* sw = static_cast<osg::Switch*>(node);
+
+    sw->setValue(0, _enabled);
+    if (!_enabled)
+      return;
+    traverse(node, nv);
+  }
+private:
+simgear::PropertyObject<bool> _enabled;
+};
+
+// update callback for the GUI (old) switch node
+struct FGOldGUISwitchCallback : public osg::NodeCallback {
+  FGOldGUISwitchCallback() : _enabled("/sim/rendering/draw-mask/old-gui") {}
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+  {
+    assert(dynamic_cast<osg::Switch*>(node));
+    osg::Switch* sw = static_cast<osg::Switch*>(node);
+
+    sw->setValue(0, _enabled);
+    if (!_enabled)
+      return;
+    traverse(node, nv);
+  }
+private:
+simgear::PropertyObject<bool> _enabled;
+};
+
+// update callback for the GUI (old) switch node
+struct FGSunlightSwitchCallback : public osg::NodeCallback {
+  FGSunlightSwitchCallback() : _enabled("/sim/rendering/draw-mask/sunlight") {}
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+  {
+    assert(dynamic_cast<osg::Switch*>(node));
+    osg::Switch* sw = static_cast<osg::Switch*>(node);
+
+    sw->setValue(0, _enabled);
+    if (!_enabled)
+      return;
+    traverse(node, nv);
+  }
+private:
+simgear::PropertyObject<bool> _enabled;
+};
+
 FGRenderer::FGRenderer() :
     _sky(NULL),
     _ambientFactor( new osg::Uniform( "fg_SunAmbientColor", osg::Vec4f() ) ),
@@ -1483,7 +1537,8 @@ FGRenderer::setupView( void )
     lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
     lightSource->setUpdateCallback(new FGLightSourceUpdateCallback);
     _viewerSceneRoot->addChild(lightSource);
-   
+
+
     // we need a white diffuse light for the phase of the moon
     osg::ref_ptr<LightSource> sunLight = new osg::LightSource;
     sunLight->setName("sunLightSource");
@@ -1501,7 +1556,11 @@ FGRenderer::setupView( void )
     sunLight->addChild(skyGroup);
     
     if ( _classicalRenderer ) {
-        _root->addChild(sunLight);
+    osg::Switch *sw = new osg::Switch;
+    sw->setName("sunLightSwitch");
+    sw->setUpdateCallback( new FGSunlightSwitchCallback);
+    sw->addChild(sunLight);
+    _root->addChild(sw);
     }
   
     osg::Group* sceneGroup = globals->get_scenery()->get_scene_graph();
@@ -1531,19 +1590,25 @@ FGRenderer::setupView( void )
     stateSet->setAttributeAndModes(fog);
     stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
 

     // plug in the GUI
     osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault());
     if (guiCamera) {
+      osg::Switch* sw = new osg::Switch;
+      sw->setName("OldGUISwitch");
+      sw->setUpdateCallback(new FGOldGUISwitchCallback);
+
       osg::Geode* geode = new osg::Geode;
       geode->addDrawable(new SGHUDDrawable);
       geode->addDrawable(new SGPuDrawable);
+      sw->addChild(geode);
+      sw->addChild( FGPanelNode::create2DPanelNode() );
 
       // Draw first (eg. before Canvas GUI)
-      guiCamera->insertChild(0, geode);
-      guiCamera->insertChild(0, FGPanelNode::create2DPanelNode());
+      guiCamera->insertChild(0, sw);
     }
     
-    osg::Switch* sw = new osg::Switch;
+    osg::Switch *sw = new osg::Switch;
     sw->setName("scenerySwitch");
     sw->setUpdateCallback(new FGScenerySwitchCallback);
     sw->addChild(_root.get());
@@ -1552,8 +1617,13 @@ FGRenderer::setupView( void )
     // because, in theory, they don't want the same default state set
     // as the rest of the scene. This may not be true in practice.
     if ( _classicalRenderer ) {
-      _viewerSceneRoot->addChild(_sky->getCloudRoot());
-      _viewerSceneRoot->addChild(FGCreateRedoutNode());
+   sw = new osg::Switch;
+       sw->setName("skySwitch");
+       sw->setUpdateCallback(new FGSkySwitchCallback);
+        sw->addChild(_sky->getCloudRoot());
+        sw->addChild(FGCreateRedoutNode());
+
+        _viewerSceneRoot->addChild(sw);
     }
   
     // Attach empty program to the scene root so that shader programs
@@ -1625,7 +1695,8 @@ FGRenderer::update( ) {
                           : osg::Vec4(0, 0, 0, 1);
     camera->setClearColor(clear_color);
 
-    updateSky();
+    if (fgGetBool("/sim/rendering/draw-mask/sky",true))
+       updateSky();
     
     // need to call the update visitor once
     _frameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
diff --git a/preferences.xml b/preferences.xml
index dbbbe2a..bc35ef3 100644
--- a/preferences.xml
+++ b/preferences.xml
@@ -224,10 +224,13 @@ Started September 2000 by David Megginson, david@megginson.com
             non-cockpit + aircraft elements. Use draw-mask instead. -->
          <draw-otw type="bool">true</draw-otw>
             <draw-mask>
+                <sunlight type="bool">true</sunlight>
                 <terrain type="bool">true</terrain>
                 <models type="bool">true</models>
                 <aircraft type="bool">true</aircraft>
                 <clouds type="bool">true</clouds>
+                <sky type="bool">true</sky>
+                <old-gui type="bool">true</old-gui>
             </draw-mask>
             
          <shadows-ac type="bool" userarchive="y">false</shadows-ac>



PS: We could probably unify those structs and make the property path configurable via the ctor and just parameterize the thing in the new call:
FGPropertySwitchCallback("/my/property");
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: 11100
Joined: Tue Mar 25, 2008 8:40 am

Re: Implementing moonlight (or not)

Postby Thorsten » Sat Dec 05, 2015 5:47 pm

I'll take up your moonlight challenge


You're very welcome to it. I don't think it's impossible - though it's not something that can 'just' be done.

What if the conditionals are set up at the c++ OSG interface?


Okay, let's clear a few misconceptions before they come haunting you.

You can set up all sorts of things on the C++ side - if the shader doesn't use them, they're going to remain variables (and won't actually take performance - that comes only when inside the shader). For instance to generate tree shadows, I'm attaching the normal of the triangle the tree is standing on to the state set. The ALS tree shader uses this information, the non-ALS tree shader does not. Unless it's used by a shader (i.e. explicitly picked up), additional uniforms will just reside in memory without doing anything and without costing more than memory. What's expensive is to do the additional lighting calculation, not to store a single vector.

So an additional light source won't illuminate anything if the shader doesn't call it.

Now, the opposite is not true - a shader referencing a variable that hasn't been set up at the C++ level will just crash. So you have no choice but to write a shader which references two light sources, set them up both and do a conditional in the shader. Or to have two distinct shaders dependent on how many light sources you have.

It goes even further - ALS knows several lightsources which never even appear in the scenegraph. It knows textures you never declared - what the shader does and generates is the last word before it all goes on-screen, and you can generate movements, lights, textures and even vertices at this stage.

Otherwise we could just switch the lightsource position from that of the sun to that of the moon, and change its intensity.


Except that won't work in any of the current renderers without a striking discontinuity - see above.

If what I have in mind works, then you'll treat the moon lighting exactly the same way you treat the sun lighting.


That won't work, because the moon is in a much fainter regime, so despite moonlight being white, it doesn't actually look white - it looks bluish, because that's the only color we can recognize at low intensity. Also the log weighting of intensity perception which is true over many decades fails here.

I also have to look at the code for how we ramp down and turn off the sun light source. I'd do this all at the lower OSG c++ level rather than shader level.


Except you can't, because it's just so way too slow.

The whole point of ALS is position differential light, i.e. you do a separate light computation for every screen pixel - twice in fact because the fog before a pixel is in different light than the pixel itself.

ALS explicitly discards whatever you store as the light source ambient and diffuse color vector, so even if you set this to pure white at night it won't change the visuals a bit.

You see the difference in looking at high clouds with the sun just below the horizon.

In default and Rembrandt, the clouds will appear in the same red light you are in. As you take off and reach the cloud, the cloud will change color, because you get higher and so brighter light reaches you - and since the whole scene is drawn in the single light color that reaches you, the whole scene will get brighter as you climb.

In contrast, in ALS the colors on the ground will always be the colors on the ground and the aloft colors will also remain - and only you will see different light color as you climb out. Because every pixel gets its own light computation.

I think a reasonable step to aim at would be to expose a pointing vector to the moon in properties - like we have for the sun now.
Thorsten
 
Posts: 9539
Joined: Mon Nov 02, 2009 8:33 am

Next

Return to Effects and shaders

Who is online

Users browsing this forum: No registered users and 5 guests