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 Thorsten » Wed Dec 23, 2015 7:26 am

Note that the shader (approximately) corrects for the attenuation by the air column above (well, in practice haze and clouds are the dominant players) - so the input value you want to produce is the illumination above the atmosphere.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby bugman » Wed Dec 23, 2015 9:41 am

Would this be the skydome shader? And is this ALS specific? Does it take the zenith angle of the sun into account, i.e. the amount of air the light travels through increases with the zenith angle? The Xm equation here models both the Rayleigh and Mie scattering of the atmosphere, and is supposed to be very accurate for zenith angles close to 90 degrees. For angles > 90 degrees, I would have used a value of zero.

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

Re: Implementing moonlight (or not)

Postby Thorsten » Wed Dec 23, 2015 11:29 am

No, it's really all the shaders which have to do it.

The light reduction by the atmosphere above depends on where the pixel is you're looking at - you might be in the shadow of a cloud, but the pixel you're looking at is on a mountain-top, so it's brilliantly lit. The only place in the rendering pipeline where you know where the pixel is is the vertex shader corresponding to that pixel.

As weird as this sounds, but you should think of light and fog being attached to the surface you're looking at, because that's how they need to be computed. There really is no 'fog' object in the scenegraph, the appearance of fog arises from coloring pixels differently based on where they are relative to you. And there is no light absorbing object in the scenegraph - the light reduction arises from coloring pixels differently based on where they are relative to the light source.

Also, the light reduction by a clear atmosphere is a minor correction to the light absorption by water droplets - there's almost always clouds and haze in a scene. Horizontal visibility in clear air at sea level is in excess of 250 km before scattering on air molecules blues the scene too much. Real visibilities on the ground are more often in the 30-50 km category even on fair days - you will get the predominant light reduction from the cloud layers, the first correction from haze, and only then the atmosphere matters.

What is ALS-specific is that light reduction is computed based on pixel position - Rembrandt and default compute based on your position. So the terrain will appear somewhat gloomy if you're underneath a cloud layer and as soon as you cross the layer and look down through a gap in the clouds, it will be bright in default but remain dark in ALS.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby chris_blues » Wed Dec 23, 2015 4:23 pm

What an interesting discussion! I sure hope we'll get to see the results in action! Keep it up! :)
Don't hesitate to let me know if I'm incorrect or just annoying! As long as you do it gently! :)
Debian stable 64bit - i7 8x2.8GHz - 20GB RAM - GeForce GTS 450
Citation II
User avatar
chris_blues
Retired
 
Posts: 1577
Joined: Mon May 03, 2010 2:30 pm
Location: claws of real life
Callsign: chris_blues
Version: GIT
OS: Debian stable 64

Re: Implementing moonlight (or not)

Postby bugman » Wed Dec 23, 2015 5:52 pm

Thorsten wrote in Wed Dec 23, 2015 11:29 am:No, it's really all the shaders which have to do it.

The light reduction by the atmosphere above depends on where the pixel is you're looking at - you might be in the shadow of a cloud, but the pixel you're looking at is on a mountain-top, so it's brilliantly lit. The only place in the rendering pipeline where you know where the pixel is is the vertex shader corresponding to that pixel.

As weird as this sounds, but you should think of light and fog being attached to the surface you're looking at, because that's how they need to be computed. There really is no 'fog' object in the scenegraph, the appearance of fog arises from coloring pixels differently based on where they are relative to you. And there is no light absorbing object in the scenegraph - the light reduction arises from coloring pixels differently based on where they are relative to the light source.


Cheers! I had seen a little of this in the Viewer/renderer.cxx and Time/light.cxx code. I guess OSG does most of the pixel work for you. My first experiment might be to set the ambient, diffuse and specular light in the FG renderer for the moon, adding to the sun settings. I will generalise the sun light source so that we can switch from the sun vector to the moon vector once the sun angle is > 90 degrees (plus a small amount), and use the same code paths for setting the ambient, diffuse and specular lighting. This can then be refined to have smooth transitions with the twilight periods between sunset and dusk, and dawn and sunrise (when there should be no directional specular or diffuse lighting), and to have the colour shifted to match the eye response to low light.

For anyone following, note that moonlight and sunlight are not too different. You can see this with super long night time time-lapse photography:

Image

The difference is in the response of your eye.

Also, the light reduction by a clear atmosphere is a minor correction to the light absorption by water droplets - there's almost always clouds and haze in a scene. Horizontal visibility in clear air at sea level is in excess of 250 km before scattering on air molecules blues the scene too much. Real visibilities on the ground are more often in the 30-50 km category even on fair days - you will get the predominant light reduction from the cloud layers, the first correction from haze, and only then the atmosphere matters.


I hope that most of this will be taken care of by simply hijacking the sun! I'll test if we need to take the light reduction due to changes in air mass with the changing zenith angle (Xm) into account later. For the "illuminance of the moon outside the atmosphere", I'll place this in the simgear ephemeris code, as this is not dependent on the local position. The Xm value cannot be calculated here as it is dependent on the local frame for the zenith angle, so that would go into the flightgear Time/bodysolver.cxx and Time/light.cxx code where the local frame + celestial bodies is handled.

What is ALS-specific is that light reduction is computed based on pixel position - Rembrandt and default compute based on your position. So the terrain will appear somewhat gloomy if you're underneath a cloud layer and as soon as you cross the layer and look down through a gap in the clouds, it will be bright in default but remain dark in ALS.


I still have to work out where ALS kicks in along this pathway. I can see that it is classified as a 'classic' renderer together with the default renderer, and Rembrandt is separate. Anyway, I hope that there won't be much tweaking required for such effects to work with moonlight, especially if we hijack the sun.

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 23, 2015 7:19 pm

I still have to work out where ALS kicks in along this pathway. I can see that it is classified as a 'classic' renderer together with the default renderer, and Rembrandt is separate. Anyway, I hope that there won't be much tweaking required for such effects to work with moonlight, especially if we hijack the sun.


As I've tried to explain a few times, ALS does most of the work on the graphics card, so you wouldn't see any of its lighting by looking at the C++ code because it's simply not there - or turned the other way round, whatever you define as light on the C++ level is going to be discarded by ALS, and so is whatever you set up as fog there.

Since the horizon is significantly brighter in sunward direction than opposite to it, there is in fact directional light even after sundown, and this is relevant till the sun is 15 deg below the horizon.

I hope that most of this will be taken care of by simply hijacking the sun!


No, not at all. As I tried to explain, ALS doesn't use the light color you set because that's too simplistic - you need to light different parts of the scene with different colors, so the color is computed for every pixel based on sun position on the graphics card.

Which will go wrong if you pretend the sun is the moon.

The difference is in the response of your eye.


That's true, but it doesn't buy you anything - if you illuminate the scene in small_number x (1.0, 1.0, 1.0), it'll appear wrong because the response of the eye isn't properly considered.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby MIG29pilot » Wed Dec 23, 2015 10:38 pm

bugman wrote in Wed Dec 23, 2015 5:52 pm:For anyone following, note that moonlight and sunlight are not too different.

Well of course, moonlight is just sunlight bouncing off the moon.
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 Hooray » Wed Dec 23, 2015 10:52 pm

Thorsten wrote in Wed Dec 23, 2015 7:19 pm:ALS doesn't use the light color you set because that's too simplistic - you need to light different parts of the scene with different colors, so the color is computed for every pixel based on sun position on the graphics card.


which probably is to say that the ALS framework/shaders contain the implicit assumption about the light source being "the" sun, so the whole "moonlight is reflected sunlight" approach won't work directly, short of adapting the underlying effects/shaders to also teach them about the position of the moon ?
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 24, 2015 8:08 am

which probably is to say that the ALS framework/shaders contain the implicit assumption about the light source being "the" sun, so the whole "moonlight is reflected sunlight" approach won't work directly, short of adapting the underlying effects/shaders to also teach them about the position of the moon ?


Yes, except that it's not an implicit assumption, it's pretty explicit in the code and documentation that the main light source computed is the sun :-)

Which is why I suggested to use the exposed position and phase of the moon as uniforms.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby bugman » Tue Dec 29, 2015 6:59 pm

Image

The graph above is the scaling factor I'll use for the moon illumination. It is the log of the illumination scaled to be between zero and one, with the formula:

    factor = (log(I) - max_loglux) / (max_loglux - min_loglux) + 1.0

This will work for the illumination formulae for both outside and inside the atmosphere. The prototyping Python code for this is:

Code: Select all
from math import log, pi, sin
from numpy import array

# The zenith angles.
Z = array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90]) / 360.0 * 2 * pi

# Number of phases to plot.
N = 101

# Extinction coefficient.
k = 0.172

# Foot-candles to lux conversion factor.
conv = 10.7639

def lux(phase=1.0, Z=0.0):
    """Calculate the illuminance of the moon inside the atmosphere in lux."""

    # Illuminance of the moon outside the atmosphere.
    I_star = 10**(-0.4 * (3.84 + 0.026*abs(phase) + 4e-9*phase**4))

    # Outside the atmosphere.
    if Z == None:
        I = I_star

    # Inside the atmosphere.
    else:
        # The optical pathlength to the moon (or air mass along the line of sight).
        Xm = (1.0 - 0.96*sin(Z)**2)**-0.5

        # Illuminance of the moon inside the atmosphere (equation 7).
        I = I_star * 10**(-0.4 * k * Xm)

    # Convert from foot-candles to lux.
    I *= conv

    # Return the illuminance.
    return I


# Maximum and minimum log lux.
min_loglux = log(lux(phase=180.0, Z=pi/2.0))
max_loglux = log(lux(phase=0.0, Z=None))
print("Log of illuminance of the moon.")
print("Minimum: %s" % min_loglux)
print("Maximum: %s" % max_loglux)

# Output Grace file (https://en.wikipedia.org/wiki/Grace_%28plotting_tool%29).
file = open('loglux_factor.agr', 'w')

# Loop over the zenith angles.
for i in range(len(Z)):
    # A new graph.
    file.write("@target G0.S%s\n" % i)
    file.write("@type xy\n")

    # Loop over the different phases.
    for j in range(N):
        # The phase (from -180 to 180).
        phase = 180 * (j - (N-1)/2.0) / ((N-1)/2.0)

        # The illuminance of the moon inside the atmosphere.
        I = lux(phase=phase, Z=Z[i])

        # Log lux factor.
        logI = (log(I) - max_loglux) / (max_loglux - min_loglux) + 1.0

        # Write the point out to file.
        file.write("%s %s\n" % (phase, logI))

    # Terminate the graph.
    file.write("&\n")


And the values of max_loglux (outside the atmosphere) and min_loglux (inside the atmosphere) are:

Code: Select all
Log of illuminance of the moon.
Minimum: -10.1305600899
Maximum: -1.16057276024


I might just apply this directly to the simgear ephemeris code to set the "/environment/moonlight" value based on the moon illuminance outside of the atmosphere. The Xm formula could be applied later to decrease the illuminance based on the atmospheric extinction coefficient and the moon's zenith angle.

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

Re: Implementing moonlight (or not)

Postby wkitty42 » Tue Dec 29, 2015 8:30 pm

hey bugman, i saw something in an astronomy program (stellarium) the other day that i found quite interesting... i was experimenting with their scripts and gathering data on certain objects... in the returned data, there are numerous fields... in two of those fields they calculate the illumination and phase for the object requested... i was quite surprised to find that one is the other multiplied by 100... it kinda makes sense, though... the following numbers are supposedly accurate as of the time of this post...

eg:
Code: Select all
---------
Mercury Data
---------
phase        : 0.5772908329963684
illumination : 57.72908329963684

---------
Venus Data
---------
phase        : 0.7649145126342773
illumination : 76.49145126342773

---------
Moon Data
---------
phase        : 0.8053301572799683
illumination : 80.53301572799683

---------
Mars Data
---------
phase        : 0.9147176742553711
illumination : 91.47176742553711

---------
Jupiter Data
---------
phase        : 0.9922244548797607
illumination : 99.22244548797607

---------
Saturn Data
---------
phase        : 0.9995062351226807
illumination : 99.95062351226807

---------
Uranus Data
---------
phase        : 0.9994080066680908
illumination : 99.94080066680908

---------
Neptune Data
---------
phase        : 0.9997990131378174
illumination : 99.97990131378174

---------
Pluto Data
---------
phase        : 0.9999963045120239
illumination : 99.99963045120239
"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: 9123
Joined: Fri Feb 20, 2015 4:46 pm
Location: central NC, USA
Callsign: wk42
Version: git next
OS: Kubuntu 20.04

Re: Implementing moonlight (or not)

Postby Thorsten » Wed Dec 30, 2015 7:46 am

It's wrong to simply take the illuminated area of the Moon (i.e. phase) as proxy for brightness. The reason is that the reflectivity of moon surface dust has a strong angular dependence, the dust reflects much better when the incident light angle is large.

It may work better for, say, Venus, since here the reflection is mainly on clouds.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Implementing moonlight (or not)

Postby bugman » Wed Dec 30, 2015 10:09 am

Like Thorsten said, this is not right. Actually, that multiplication by 100 is wrong on so many levels, I don't know where to start. I guess this is used as an extremely rough rule of thumb. The moon is a little like a mirror, it reflects far more light back at the sun than it does sideways. But all solar system bodies do this to some extent. Think of the sun lighting around you just before sunset. There will be longer and more shadows, and it's not as bright as when the sun is directly overhead, so the amount of light reflected out to space will be a lot less at the edges of the illuminated surface of any solar system body.

For the moon itself, the reflected light is modelled as:

    -12.73 + 0.026*abs(phase) + 4e-9*phase**4

You'll see this in the equations I used (see the prototyping code above). This is directly from the astronomer's bible, specifically page 144 of the first edition of:


If you look at the table on page 144, note the variation of V with phase column (deltaV). This shows that the multiplication by 100 is wrong, very wrong. The correct formula is given in that column together with the V column, as V + deltaV.

Regards,
Edward

Edit: Fixes for the equations.
bugman
Moderator
 
Posts: 1808
Joined: Thu Mar 19, 2015 10:01 am
Version: next

Re: Implementing moonlight (or not)

Postby bugman » Wed Dec 30, 2015 5:05 pm

bugman wrote in Tue Dec 29, 2015 6:59 pm:And the values of max_loglux (outside the atmosphere) and min_loglux (inside the atmosphere) are:

Code: Select all
Log of illuminance of the moon.
Minimum: -10.1305600899
Maximum: -1.16057276024




For reference, as these will be hardcoded into the simgear code, the base 10 log values are:

Code: Select all
Log of illuminance of the moon.
Minimum: -4.39964634562
Maximum: -0.504030345621


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

Re: Implementing moonlight (or not)

Postby wkitty42 » Wed Dec 30, 2015 9:00 pm

i don't know if those numbers i posted are being used as a proxy for brightness or not... perhaps more likely to be the lit area of a circle... i thought it was interesting and possibly helpful but perhaps not as much as i had thought... like i said, it is an astronomy program... AFAICT what it shows on screen for my location looks very accurate compared to what i see in RL when i step outside and look at the same object(s)...
"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: 9123
Joined: Fri Feb 20, 2015 4:46 pm
Location: central NC, USA
Callsign: wk42
Version: git next
OS: Kubuntu 20.04

PreviousNext

Return to Effects and shaders

Who is online

Users browsing this forum: No registered users and 1 guest