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.
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.
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.
I hope that most of this will be taken care of by simply hijacking the sun!
The difference is in the response of your eye.
bugman wrote in Wed Dec 23, 2015 5:52 pm:For anyone following, note that moonlight and sunlight are not too different.
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 ?
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")
Log of illuminance of the moon.
Minimum: -10.1305600899
Maximum: -1.16057276024
---------
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
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
Log of illuminance of the moon.
Minimum: -4.39964634562
Maximum: -0.504030345621
Users browsing this forum: No registered users and 2 guests