Board index FlightGear Development Effects and shaders

Clustered Forward Rendering

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

Clustered Forward Rendering

Postby icecode » Fri Dec 07, 2018 2:39 pm

In the process of trying to migrate as many Rembrandt features as possible to a new Compositor-based forward pipeline, it was necessary to come up with a way of rendering many lights in real time. Although it took longer than I expected (mainly because I didn't have as much time as I expected :) ), I finally got around to implementing clustered forward rendering.

The only missing feature is how to declare the lights themselves. Rembrandt does it with light volumes and an animation applied to them. It could also be done with a custom <light/> tag in the model.xml. It'd be nice if aircraft/scenery developers could tell me what would be their preferred way to add lights to their models, and what parameters they'd want to be able to control (range, color, etc.).

Thanks!
icecode
 
Posts: 708
Joined: Thu Aug 12, 2010 1:17 pm
Location: Spain
Version: next
OS: Fedora

Re: Clustered Forward Rendering

Postby legoboyvdlp » Fri Dec 07, 2018 2:48 pm

I personally like the nasal implementation of lightspots, where you can adjust stretching, color, size, and position. But anything as long as it is well documented is fine :)
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Clustered Forward Rendering

Postby Richard » Fri Dec 07, 2018 3:38 pm

I've got a long standing WIP that aims to slightly rework the way lights are defined to be consistent across all pipelines.

This is basically an extension of the way Rembrandt defines lights[1], but with an optional way to get the position and direction from model geometry (using the same technique as the axis-animation), possibly also using the pos/dir geometry to provide the amb/diff/specular materials. From a modelling perspective it is so much easier to place a small circle, or maybe two circles that are at the right location than it is to work with model coordinates in the XML file; which is why I'm putting the effort into this.

The reason I'm stalled on getting this working is that I was trying to figure out if there was an elegant way to have a convention for the geometry that would also allow the attenuation, exponent, cut-off, near-m and far-m.

In my opinion defining light points in Nasal is not an ideal solution because it makes it less consistent, requires the Nasal to be loaded, will probably be difficult to get working reliably for MP models.

-------------------------------
[1] http://wiki.flightgear.org/Project_Remb ... int_lights
Richard
 
Posts: 810
Joined: Sun Nov 02, 2014 11:17 pm
Version: Git
OS: Win10

Re: Clustered Forward Rendering

Postby Thorsten » Fri Dec 07, 2018 3:39 pm

That looks like some good progress! :D :D :D

Edit: @Richard Well, Nasal just sets properties, so... properties can be driven by whatever can write properties. A property-controlled framework imo isn't a bad thing because it's flexible,
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Clustered Forward Rendering

Postby Richard » Fri Dec 07, 2018 4:02 pm

@Thorsten; no complaints from me about the underlying architecture of the ALS lights; I'd just prefer an abstraction atop of it that fits with the rest of the way that models are defined in a way that works for player,AI,MP.

We should keep to a minimum the need to use Nasal in models as it requires this Nasal to be in model xml load/unload sections to work properly for non-player models.
Richard
 
Posts: 810
Joined: Sun Nov 02, 2014 11:17 pm
Version: Git
OS: Win10

Re: Clustered Forward Rendering

Postby icecode » Fri Dec 07, 2018 4:22 pm

From a modelling perspective it is so much easier to place a small circle, or maybe two circles that are at the right location than it is to work with model coordinates in the XML file; which is why I'm putting the effort into this.


The light volumes get tested against many camera subfrustums to see if they are in view. If the light volume model is complex, the culling math is complex and the technique is slower, that's why the compositor only supports point lights (bounding spheres) for now. I understand that a model based solution is very appealing, but we also have to consider the performance limitations. In general, the simpler the geometry of the light is, the better.

EDIT: Also this is all supposed to integrate well with a PBR-like shader, i.e. lights have no ambient/diffuse/specular colors, just a physical radiant intensity.
icecode
 
Posts: 708
Joined: Thu Aug 12, 2010 1:17 pm
Location: Spain
Version: next
OS: Fedora

Re: Clustered Forward Rendering

Postby Richard » Fri Dec 07, 2018 5:09 pm

The geometry for the little circles would be processed to find the position (x,y,z) and direction(x,z,y) and then the geometry hidden[1]

So we'd have two vectors (position, direction) - is that compatible. The light volume geometry would probably be ignored except for Rembrandt; the only use for it would be to find a convention based name (i.e. geometrys named shadowVolumeName_lpos and shadowVolumeName_ldir); or these could be specified by <position>lightNamePosition</position>.

--------------------
[1] similar to http://wiki.flightgear.org/Howto:Animat ... 82017.2.29
Richard
 
Posts: 810
Joined: Sun Nov 02, 2014 11:17 pm
Version: Git
OS: Win10

Re: Clustered Forward Rendering

Postby Thorsten » Fri Dec 07, 2018 5:10 pm

@Richard:

We should keep to a minimum the need to use Nasal in models as it requires this Nasal to be in model xml load/unload sections to work properly for non-player models.


You must have misunderstood me as I completely agree with this - Nasal to make lights work is only a crutch.

What I'd like to see is something property-controlled (rather than model-geometry), i.e. you can specify a light completely using xml rather than ac3d. That's all I'm saying here (and of course, if it is property controlled, you can use Nasal if you wish to change it runtime as needed... whereas you can't change a mesh runtime easily)
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Clustered Forward Rendering

Postby Hooray » Fri Dec 07, 2018 5:16 pm

Icecode also once considered that, we were actually talking about this a while ago, i.e. how light sources are currently hard-coded to set up the root scene, and if it'd be worth the hassle to come up with dedicated listener/property-based light-manager analogous to the Canvas/Compositor systems (i.e. via PropertyBasedMgr).

IIRC, it's under 100 lines of C++ code that would have to be mapped to property based interface, which I once touched to add all sorts of draw-masks to be able to disable those light sources easily (aka via properties) - this was mainly to tinker with alternate fgfs environments, i.e. fgfs minus its default scene (terrain, lighting etc), often just to tinker with Canvas stuff.

http://wiki.flightgear.org/Draw_masks

Image
http://wiki.flightgear.org/Canvas_Troub ... for_Canvas
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: Clustered Forward Rendering

Postby Necolatis » Fri Dec 07, 2018 5:21 pm

AC3D actually supports Pointlights (And so does the OSG ac3d loader). But sadly, not a way to define its color or attenuation: https://sites.google.com/view/ac3dfileformat/home

However, since it can be named, maybe could change the color via material animations. Or a custom animation.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 2232
Joined: Mon Oct 29, 2012 1:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2020.3.19
OS: Windows 10

Re: Clustered Forward Rendering

Postby icecode » Fri Dec 07, 2018 9:42 pm

The geometry for the little circles would be processed to find the position (x,y,z) and direction(x,z,y) and then the geometry hidden[1]


Since you are referring to directions, I guess you are talking about spotlights. How would we define the cutoff angle? What about other parameters common to both point lights and spot lights like color and attenuation? Should they be controlled by extra attributes in an animation ala Rembrandt?

I also want to note that clustered forward rendering doesn't strictly require light volumes, i.e. the light "hitbox" can be calculated and passed to some kind of LightManager class, they don't have to be real geometry attached to the scene graph like in Rembrandt.

AC3D actually supports Pointlights (And so does the OSG ac3d loader). But sadly, not a way to define its color or attenuation:


Very interesting, I didn't know that. But if we use AC3D native point lights, what about spot lights? Should we use two different approaches?


I'm just asking questions here since I have no idea what's better or worse. Richard, if you are able to specify a bit more, I'd gladly take your approach since I personally have no preference over this.
icecode
 
Posts: 708
Joined: Thu Aug 12, 2010 1:17 pm
Location: Spain
Version: next
OS: Fedora

Re: Clustered Forward Rendering

Postby Richard » Mon Dec 10, 2018 4:35 pm

Icecode GL wrote in Fri Dec 07, 2018 9:42 pm:I'm just asking questions here since I have no idea what's better or worse. Richard, if you are able to specify a bit more, I'd gladly take your approach since I personally have no preference over this.


I figure that starting with how Rembrandt defines light points is a good place; ignore all of the stuff I said about processing geometry.

I'm happy to help making any changes that are required to the animation parsing/handling; including putting stuff into the property tree.

If you look at an example it might help so below is the entire external lighting for the F-14. The <object-name> refers to the light volume so that can be ignored; but I think there is enough detail in the rest (even if some of the other parts need to be ignored).
Code: Select all
<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>RBT-coll_halo_CP</name>
    <object-name>RBT-coll_halo_CP</object-name>
    <position>    <x>-7.7476</x>                <y>0</y>                      <z>-1.7990</z>                </position>
    <ambient>     <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </ambient>
    <diffuse>     <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </diffuse>
    <specular>    <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </specular>
    <attenuation> <c>1.3</c>                    <l>1.5</l>                    <q>4</q>                      </attenuation>
    <cutoff>10</cutoff>
    <near-m>0.01</near-m>
    <far-m>10</far-m>
</animation>

<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>RBT-coll_halo_TR</name>
    <object-name>RBT-coll_halo_TR</object-name>
    <position>    <x>9.0232</x>                 <y>1.6616</y>                 <z>1.9674</z>                 </position>
    <ambient>     <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </ambient>
    <diffuse>     <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </diffuse>
    <specular>    <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </specular>
    <attenuation> <c>1.3</c>                    <l>1.5</l>                    <q>4</q>                      </attenuation>
    <cutoff>10</cutoff>
    <near-m>0.01</near-m>
    <far-m>10</far-m>
</animation>

<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>RBT-coll_halo_TL</name>
    <object-name>RBT-coll_halo_TL</object-name>
    <position>    <x>8.1077</x>                 <y>-1.6616</y>                <z>1.9674</z>                 </position>
    <ambient>     <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </ambient>
    <diffuse>     <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </diffuse>
    <specular>    <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </specular>
    <attenuation> <c>1.3</c>                    <l>1.5</l>                    <q>4</q>                      </attenuation>
    <cutoff>10</cutoff>
    <near-m>0.01</near-m>
    <far-m>10</far-m>
</animation>

<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>RBT-coll_halo_WL</name>
    <object-name>RBT-coll_halo_WL</object-name>
    <position>     <x>3.0700</x>                 <y>-9.1247</y>                <z>-0.5790</z>                </position>
    <ambient>      <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </ambient>
    <diffuse>      <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </diffuse>
    <specular>     <r>1</r>                      <g>0.15</g>                   <b>0</b>                      <a>1.0</a>                    </specular>
    <attenuation>  <c>1.3</c>                    <l>1.5</l>                    <q>4</q>                      </attenuation>
    <cutoff>10</cutoff>
    <near-m>0.01</near-m>
    <far-m>10</far-m>
</animation>

<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>RBT-coll_halo_WR</name>
    <object-name>RBT-coll_halo_WR</object-name>
    <position>    <x>3.0700</x>                 <y>9.1247</y>                 <z>-0.5790</z>                </position>
    <ambient>     <r>0</r>                      <g>1</g>                      <b>0.1</b>                    <a>1</a>                      </ambient>
    <diffuse>     <r>0</r>                      <g>1</g>                      <b>0.1</b>                    <a>1</a>                      </diffuse>
    <specular>    <r>0</r>                      <g>1</g>                      <b>0.1</b>                    <a>1</a>                      </specular>
    <attenuation> <c>1.3</c>                    <l>1.5</l>                    <q>4</q>                      </attenuation>
    <cutoff>10</cutoff>
    <near-m>0.01</near-m>
    <far-m>10</far-m>
</animation>

<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>RBT-pos_halo_Tail</name>
    <object-name>RBT-pos_halo_Tail</object-name>
    <position>    <x>9.16</x>                   <y>-1.7127</y>                <z>1.7549</z>                 </position>
    <ambient>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </ambient>
    <diffuse>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </diffuse>
    <specular>    <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </specular>
    <attenuation> <c>1.3</c>                    <l>1.5</l>                    <q>4</q>                      </attenuation>
    <cutoff>10</cutoff>
    <near-m>0.01</near-m>
    <far-m>10</far-m>
</animation>

<animation>
    <type>light</type>
    <light-type>spot</light-type>
    <name>taxi-light</name>
    <object-name>taxi-light-cone</object-name>
    <direction><x>-1</x>                     <y>0</y>                      <z>-0.024</z>                 </direction>
    <position>    <x>-10.5672</x>               <y>0</y>                      <z>-1.6267</z>                </position>
    <ambient>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </ambient>
    <diffuse>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </diffuse>
    <specular>    <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </specular>
    <attenuation> <c>0.5</c>                    <l>0.07</l>                   <q>0</q>                      </attenuation>
    <exponent>30.0</exponent>
    <cutoff>200</cutoff>
    <near-m>0.01</near-m>
    <far-m>200</far-m>
</animation>

<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>taxi-halo</name>
    <object-name>taxi-halo-sphere</object-name>
    <position>    <x>-6.2612</x>                <y>0</y>                      <z>-2.1269</z>                </position>
    <ambient>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </ambient>
    <diffuse>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </diffuse>
    <specular>    <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </specular>
    <attenuation> <c>1</c>                      <l>1.7</l>                    <q>4</q>                      </attenuation>
    <cutoff>1.3</cutoff>
    <near-m>0.01</near-m>
    <far-m>1.3</far-m>
</animation>

<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>left afterburner</name>
    <object-name>RBT-afterburner_halo_l</object-name>
    <position>    <x>8.512</x>                  <y>-0.7</y>                   <z>0</z>                      </position>
    <ambient>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </ambient>
    <diffuse>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </diffuse>
    <specular>    <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </specular>
    <attenuation> <c>1</c>                      <l>2.7</l>                    <q>1</q>                      </attenuation>
    <near-m>0.01</near-m>
    <far-m>17.3</far-m>
    <dim-factor><expression><product><value>0.2</value></product></expression></dim-factor>
</animation>

<animation>
    <type>light</type>
    <light-type>point</light-type>
    <name>right afterburner</name>
    <object-name>RBT-afterburner_halo_r</object-name>
    <position>    <x>8.512</x>                  <y>0.7</y>                    <z>0</z>                      </position>
    <ambient>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </ambient>
    <diffuse>     <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </diffuse>
    <specular>    <r>0.95</r>                   <g>0.9</g>                    <b>0.9</b>                    <a>1</a>                      </specular>
    <attenuation> <c>1</c>                      <l>2.7</l>                    <q>1</q>                      </attenuation>
    <near-m>0.01</near-m>
    <far-m>17.3</far-m>
    <dim-factor><expression><product><value>0.2</value></product></expression></dim-factor>
</animation>

Richard
 
Posts: 810
Joined: Sun Nov 02, 2014 11:17 pm
Version: Git
OS: Win10

Re: Clustered Forward Rendering

Postby icecode » Wed Jan 02, 2019 2:06 am

Richard wrote in Mon Dec 10, 2018 4:35 pm:I'm happy to help making any changes that are required to the animation parsing/handling; including putting stuff into the property tree.


Perhaps it's not too late to ask for help. :) I've been working on other stuff and I kind of left Clustered Forward behind.

I basically just need a list of all the lights that may affect geometry in view, and all the lighting-related parameters for each one of them. A NodeVisitor or the EffectCullVisitor itself can be used to recover the light volumes from the scene graph, but I don't know how to recover the parameters since the light volumes are OSG nodes. Feel free to work on SGLightAnimation if you want, I'd very much appreciate it.
icecode
 
Posts: 708
Joined: Thu Aug 12, 2010 1:17 pm
Location: Spain
Version: next
OS: Fedora

Re: Clustered Forward Rendering

Postby Richard » Sun Jan 06, 2019 7:46 am

It's never too late to ask for help -)

I've had a look at how SGLightAnimation works and I think it's already got most of what we need; however I need to do more work to figure out how it's using the geodes and the shaders to do its work.

It has the params internally; so possibly we might just need a geode inherited light object that has these properties exposed so they can be accessed; or possibly it might be a case of changing the interface to the shaders to suit what you need. Some guidance on what you actually need might help me with this.
Richard
 
Posts: 810
Joined: Sun Nov 02, 2014 11:17 pm
Version: Git
OS: Win10

Re: Clustered Forward Rendering

Postby icecode » Sun Jan 06, 2019 2:16 pm

Some guidance on what you actually need might help me with this.


I need two things from the lights:

  • A std::vector (or equivalent) holding a list of structs where each field is a parameter to be sent to the model shader. These parameters should be the position (in either world or view space), range, color, etc. This list could be created during the cull traversal in the EffectCullVisitor so the Clustered Forward algorithm, which is implemented in an InitialDrawCallback, could access it and update the textures/UBOs that are passed to the shader.
  • A std::vector (or equivalent) holding a list of bounding spheres (or whatever shape best describes the light's shape) to use for intersection tests with the subdivided view frustums. This is the tricky part, specially for spot lights. The subdivided subfrusta are stored as osg::Polytopes, which only allow intersection tests for vertices, spheres and bounding boxes. Point lights's shape is easy to describe with a bounding sphere, but spot lights require cone intersection tests, which are not directly provided by osg::Polytope.

I'm stuck on the second point. We can have two light lists (one for point lights and another for spot lights), but that doesn't solve the problem of how to describe the spot light's shape, specially if it comes from a light volume which can have any arbitrary shape.
icecode
 
Posts: 708
Joined: Thu Aug 12, 2010 1:17 pm
Location: Spain
Version: next
OS: Fedora

Next

Return to Effects and shaders

Who is online

Users browsing this forum: No registered users and 0 guests