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!

Re: Implementing moonlight (or not)

Postby Hooray » Sat Dec 05, 2015 8:16 pm

Anybody considering to work on this, may want to check out

http://wiki.flightgear.org/The_FlightGe ... g_Pipeline

While it's not much more than a stub currently, we could certainly extend the whole thing accordingly
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: Implementing moonlight (or not)

Postby bugman » Wed Dec 16, 2015 5:11 pm

I have a quick update for this thread. Step 1 is done - the moon position and vector has been exposed. On top of that I calculate the moon age and phase. This is all exposed on the property tree as:

    "/ephemeris/moon/xg" - the moon's rectangular geocentric coordinates.
    "/ephemeris/moon/yg" - the moon's rectangular geocentric coordinates.
    "/ephemeris/moon/ye" - the moon's rectangular equatorial coordinates.
    "/ephemeris/moon/ze" - the moon's rectangular equatorial coordinates.
    "/ephemeris/moon/local/x" - the moon X-coordinate in the local aircraft frame.
    "/ephemeris/moon/local/y" - the moon Y-coordinate in the local aircraft frame.
    "/ephemeris/moon/local/z" - the moon Z-coordinate in the local aircraft frame.
    "/ephemeris/moon/lat-deg" - the ecliptic latitude.
    "/ephemeris/moon/age" - the moon age from 0 to 2pi.
    "/ephemeris/moon/phase" - the moon phase from 0 to 1.

These are identical matches the information for the sun, excluding the age and phase, but with the moon info. For the angular values, these are all in radians. The changes are in some branches in my fork of the flightgear and simgear repositories. The branches with the newest set of changes have not been pushed to the repositories yet, to allow for easy rebasing to the newest changes. This code may only reach the official repositories if the directional moonlight experiment works, or if these is some interest in using this information (for example for those who are interested in reaching the stars).

The next step is to learn about the fascinating world of the FlightGear renderer:


Including its two seemingly permanently on light sources, both positioned at the location of the sun!

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;
};


The FlightGear renderer code is an incredible beast! I think I'll next try to automatically set the quantity of moonlight in the FlightGear world based on the value of "/ephemeris/moon/phase".

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

Re: Implementing moonlight (or not)

Postby Thorsten » Wed Dec 16, 2015 6:26 pm

I actually suspect we can just pass the exposed coordinates as uniforms and do the rest in the shader. Dependent on what local aircraft frame is... I hope it's not body coordinates but z up, x north and y east (or the last two swapped...).

Do you want to try this, or really install it as a light source?

Including its two seemingly permanently on light sources, both positioned at the location of the sun!


My wild guess is that one is the colored sunlight illuminating terrain and the other the white sunlight illuminating the moon.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby bugman » Wed Dec 16, 2015 6:55 pm

Thorsten wrote in Wed Dec 16, 2015 6:26 pm:I actually suspect we can just pass the exposed coordinates as uniforms and do the rest in the shader. Dependent on what local aircraft frame is... I hope it's not body coordinates but z up, x north and y east (or the last two swapped...).


I'll just continue with the experiments and see what happens. I have 3 'directional_moonlight' branches, one for flightgear, one for simgear, and one for fgdata. So I'll make the changes all over the place.

Do you want to try this, or really install it as a light source?


That's a good question. It depends on what we can do in the various FG locations. It may be unnecessary in the end, but let's see. I'm now looking at replacing all instances of "/environment/moonlight" with "/ephemeris/moon/phase" in the FGData effects (and deleting the option and slider in the PUI dialog). Both values range from 0 to 1, so this might be quite easy. Though the different rendering engines might need tweaking to make everything happy. Then maybe I'll look at getting a reflection off water surfaces. The rest of the moon effects may not need a real light source. So let's see.

Including its two seemingly permanently on light sources, both positioned at the location of the sun!


My wild guess is that one is the colored sunlight illuminating terrain and the other the white sunlight illuminating the moon.


It might take me a while to work out what is going on. Turning one or the other off has devastating results on the FG scene.

Regards,
Edward

Edit: For the coordinates, if they are different, I'd probably perform a coordinate transform in the code and expose the different set coordinate as a different property.
bugman
Moderator
 
Posts: 1808
Joined: Thu Mar 19, 2015 10:01 am
Version: next

Re: Implementing moonlight (or not)

Postby Hooray » Wed Dec 16, 2015 9:41 pm

Referring to (your way of exposing state to the property tree using tied C++ PODs): http://sourceforge.net/u/edauvergne/fli ... a03fb7a93/

Note that, unless you have already been in touch with James and/or Stuart about this approach, you will almost certainly want to refrain from using tied properties, for all the reasons discussed at: http://wiki.flightgear.org/Howto:Use_Pr ... ee_Objects

James introduced the PropertyObject<> templates specifically to get rid of tied properties - which is going to be increasingly important in any rendering related code that may possibly run asynchronously (osg cull/update traversals), but is also going to greatly simplify other multi-threading efforts (think HLA).

The other issue obviously being that tied properties do not work nicely with many other subsystems (think Nasal), while propertyObjects help encapsulate state management.
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: Implementing moonlight (or not)

Postby Thorsten » Thu Dec 17, 2015 7:16 am

I'm now looking at replacing all instances of "/environment/moonlight" with "/ephemeris/moon/phase" in the FGData effect


Don't do that directly - moonlight is a non-linear function of phase

Image

so it'd be good to have an intermediate function (even if you make it unity at the moment).

Turning one or the other off has devastating results on the FG scene.


Just change the color to green and see what happens :-)

you will almost certainly want to refrain from using tied properties


True - the effect framework doesn't read tied properties at all, so you can't use them.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby bugman » Thu Dec 17, 2015 10:07 am

@Hooray: Thanks for the PropertyObject pointers. I only used these because, if you look at the whole file, you'll see that this is simply a cut and paste, and replace 'Sun' with 'MoonPos'. Lazy, but effective programming :) James tied up the sun, so to untie these, I would probably do that as a second commit and convert all together. I'll probably discuss on the mailing list first, and get some pointers from James (then maybe I could use this as a before + after example for the wiki, to show how to eliminate ties). Also note this huge stash of ties: FGLight::bind() (I have a commit touching this part of the code too).

@Thorsten: As a test, I replaced all "/environment/moonlight" with "/ephemeris/moon/phase". It worked beautifully in the ALS framework. So I also deleted the now redundant Moonlight environment setting. This was just a test, I know that we need to probably also log the value to go from illumination to the scalar value. I'll have to look this up and see if there is an easy function (and what that function is after logging it). I could put this in the ephemeris simgear code (probably the computationally cheapest place for it), or in the flightgear Time/light.cxx code where the property tree is populated. There's no need to shift this simple stuff onto the GPU. After this, I'll probably end up with a automatically updated property called "/environment/moonlight" ;)

One thing I would like to experiment with is to shift the moonlight concept from the FGData effects and hard code it directly into the FlightGear renderer (Viewer/renderer.cxx and/or Time/light.cxx). The current solution seems to me to be a little 'hacky', in that it only works in the ALS framework and that every last object in the FG scene needs to have an effect added to be illuminated by moonlight. For example currently the terrain is lit up in ALS, but the trees are pitch black. We already seem to be setting the lighting intensity by combining the sunlight setting with fog, and many other factors (in the Time/light.cxx functions). So I would like to try to include the moonlight in here too, as a parallel experiment. That way I hope to target all rendering frameworks and then we don't have to hook up all effects, or create new effects, just to see each object in the moonlight. I would like to eliminate all black objects from the moonlit scene in one hit.

Cheers,
Edward


P. S. If anyone would like to play with these changes (and you are compiling your own copies of FG from the git repositories and know how to set up and pull from remotes), just say and I'll cut and push a copy of my local 'directional_moonlight' branches. Note that the patch-series are WIP - the final versions will be much improved.
bugman
Moderator
 
Posts: 1808
Joined: Thu Mar 19, 2015 10:01 am
Version: next

Re: Implementing moonlight (or not)

Postby Thorsten » Thu Dec 17, 2015 10:31 am

The current solution seems to me to be a little 'hacky', in that it only works in the ALS framework and that every last object in the FG scene needs to have an effect added to be illuminated by moonlight.


Won't work - moonlight will only illuminate anything if you explicitly instruct the shader to do so. Regardless of what you do on the C++ side, default won't use it until you add it to every shader.

The shaders really are the last word in rendering - all you set up before is just a potential set of things the shaders can use, but each shader decides what of it it does use.

I know, hard to accept for a C++ programmer :-)
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby bugman » Thu Dec 17, 2015 10:46 am

Thorsten wrote in Thu Dec 17, 2015 10:31 am:
The current solution seems to me to be a little 'hacky', in that it only works in the ALS framework and that every last object in the FG scene needs to have an effect added to be illuminated by moonlight.


Won't work - moonlight will only illuminate anything if you explicitly instruct the shader to do so. Regardless of what you do on the C++ side, default won't use it until you add it to every shader.

The shaders really are the last word in rendering - all you set up before is just a potential set of things the shaders can use, but each shader decides what of it it does use.


As I said, these are just experiments :) Anyway, it would just plug directly into the system for sun illumination, as currently used in all rendering frameworks (default, ALS, Rembrandt). As all objects are lit up by the sun in the current FG scene, I hope to do the same with moonlight. As it says on the wiki article Rendering system improvements#One pass multi lights, "Lighting is calculated for all pixels for all lights, even if they are unlit".

Oh, one other thing I'll look into implementing is working out the visibility of the moon (i.e. if the z coordinate > 0.0), and multiply the moonlight value by 0 or 1.

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

Re: Implementing moonlight (or not)

Postby bugman » Thu Dec 17, 2015 10:52 am

Thorsten wrote in Thu Dec 17, 2015 10:31 am:I know, hard to accept for a C++ programmer :-)


Like you, I'm not a C++ programmer ;) My expertise is Python. You should give it a go - if you can handle Nasal and GLSL, modifying existing C++ code will not be too hard. That'll give you a lot more power to set up awesome effects!

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

Re: Implementing moonlight (or not)

Postby Thorsten » Thu Dec 17, 2015 11:06 am

You should give it a go - if you can handle Nasal and GLSL, modifying existing C++ code will not be too hard. That'll give you a lot more power to set up awesome effects!


Guess who wrote the tree shadow patches...

I do go into the rendering C++ when needed, but most of the time what I want to do can really best be done on the GLSL level. And of course it's a question of time. You'll discover it :-)
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby Hooray » Thu Dec 17, 2015 11:07 am

There's tons of legacy code using tied properties, but we generally want to avoid adding even more stuff, for all the reasons that James, Mathias and Tim mentioned (see the archives for reference).

(Canvas was specifically ported from using tying to listeners/propertyObject for pretty much the same reasons)
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: Implementing moonlight (or not)

Postby MIG29pilot » Thu Dec 17, 2015 2:24 pm

I missed something--are we implementing the moon so that the computer thinks of it like the sun?
User avatar
MIG29pilot
 
Posts: 1465
Joined: Tue May 19, 2015 5:03 pm
Location: 6 feet under Snow
Callsign: MIG29pilot
Version: 2020.1.3
OS: Windows 10

Re: Implementing moonlight (or not)

Postby bugman » Thu Dec 17, 2015 3:55 pm

MIG29pilot wrote in Thu Dec 17, 2015 2:24 pm:I missed something--are we implementing the moon so that the computer thinks of it like the sun?


For rendering, it's all about using tricks to best implement the idea ;) It's not at all about mimicking how things happen in reality, but mimicking their appearance (without having a large impact on fps). Implementing directional moonlight might just be easiest using the infrastructure for the Sun in FG, as this is independent of the renderer. Both are very remote light sources, so there will be a lot in common. Many ALS effects are set up for sunlight, so they could be tricked into using moonlight in the same way without requiring the effects to be modified. Note that I'm just performing a number of experiments and seeing how this affects the 3 different rendering frameworks we have. There are multiple ways to do this. This may or may not make it to the core source code/data repositories.

Anyway, it doesn't matter in the end how or which tricks are used. The idea is to have directional moonlight in all rendering frameworks, exactly as you see it in reality - a scene illumination of all objects that is proportional to the phase of the moon, moonlight reflections off water, ice, glass, etc, clouds scattering and reflecting light as they would with real moonlight, to have halos, etc.

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

Re: Implementing moonlight (or not)

Postby Hooray » Thu Dec 17, 2015 5:50 pm

You should give it a go - if you can handle Nasal and GLSL, modifying existing C++ code will not be too hard. That'll give you a lot more power to set up awesome effects!


Like Thorsten said already, once you know C/C++, OpenGL and how to build patch/build FlightGear, the main challenge is understanding the FlightGear rendering pipeline and how the effects/shader framework is working, which is why I am hoping that you consider to add your findings to the wiki, like I suggested previously - even if just in terms of open questions. For the time being, the number of active core developers familiar with those parts of FlightGear is remarkably low, and apparently Stuart, Mathias and Tim never got around to documenting such internals, despite being obviously tremendously helpful for those wanting to work with the rendering/viewer related code.

Meanwhile, most of the people who would be considered "mentors" years ago, are now longer as actively involved in the corresponding FlightGear areas, or in the project as a whole - which leaves us with the expertise of the few people who were actually mentored a few years ago. So, our "bus factor" when it comes to rendering related code is a little problematic admittedly:

http://sourceforge.net/p/flightgear/mai ... /26794801/
Tim Moore wrote:it would be nice
one day to have better comments in the code, but this code has accreted over
many years, starting long before my involvement with FG. At a very high
level, when a model is loaded, its OSG subgraph is copied, except for its
textures and geometry. This is not-optimal, but it allows animation of all
models without a complicated optimizer.
In the monster function sgLoad3DModel_internal, effects mentioned in the
.xml file are gathered, along with any created implicitly by animations. An
effect is associated with named objects in the model. The .XML file can also
specify a default effect for the whole file; by default that is
Effects/model-default.eff. The model itself is transformed by
instantiateEffects, which uses MakeEffectVisitor. For each named object in
the model, this MakeEffectVisitor sets the appropriate effect as a "parent"
effect, and then creates a new effect for any osg::StateSet found,
inheriting from the parent. osg::Geode objects are replaced with
simgear::EffectGeode objects that will apply the effect at runtime. There is
quite a bit of hair to share effects and avoid creating new ones where
possible.

The dependency on .ac exists at this level in MakeEffectVisitor. The visitor
expects to find osg::StateSet objects only in osg::Geode objects i.e., near
the leaves of the scene graph. It only works with the simple attributes
created by the .ac loader (see makeParametersFromStateSet): osg::Material
properties, smooth vs. flat shading, polygon culling, blending (for
transparency), and one texture binding. Any other attributes are ignored.

If you want to apply effects to other kinds of models, you would need to
generalize MakeEffectVisitor "in both directions." StateSet objects can
appear in any scene graph node and also in the Geometry nodes that sit below
osg::Geode. A more general effects visitor needs to track the graphics state
as it traverses the scene graph and also needs to examine the geometry.
Effects sit at the Geode level.

Alternatively you could ignore any state attributes in the model and specify
it all in the .xml file, but this would quickly get tiresome.

I recommend you use the osgconv program to dump out the .osg representation
of our .ac models and the models that interest you and get an idea of the
differences you are up against. For .ac you should use our Optimizer options
found in ModelRegistry.cxx; you can set them with the OSG_OPTIMIZER
environment variable.

I'll try to write more comments in the code over the next few weeks. In the
mean time, keep hitting me with questions. I don't have the bandwidth to
answer basic OSG questions
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

PreviousNext

Return to Effects and shaders

Who is online

Users browsing this forum: No registered users and 1 guest