Unigine.LightWorld Class
Inherits: | Light |
This class is used to create world light sources. This type of light source imitates sunlight and uses parallel-split shadow mapping.
Example#
The following code illustrates how to create a world light source and set its parameters (intensity scattering, etc.).
/* .. */
// creating a world light source and setting its color to white (1.0f, 1.0f, 1.0f, 1.0f)
LightWorld thesun = new LightWorld(new vec4(1.0f, 1.0f, 1.0f, 1.0f));
// setting the name of the world light
thesun.setName("Sun");
// setting disable angle of the world light
thesun.setDisableAngle(90.0f);
// setting light intensity
thesun.setIntensity(1.0f);
// setting scattering type to sun scattering
thesun.setScattering(LightWorld.SCATTERING_SUN);
Setting Position#
A world light is an infinitely distant light source, so its physical position is not important, only the direction matters, as it defines orientation of shadows. You can change the light's direction via the setRotation() method.
Let's illustrate that by setting the correct position of the Sun for a certain geographic location (latitude, longitude), date and time. To calculate elevation and azimuth values let's use the following sunPosition() function:
sunPosition() function:
/// function calculating azimuth and elevation for the specified date, time (GMT) and geo-coordinates (https://stackoverflow.com/questions/8708048/position-of-the-sun-given-time-of-day-latitude-and-longitude)
void sunPosition(ref double elevation, ref double azimuth, double lat, double lon, int year = 2012, int month = 12, int day = 22, double hour = 12, int min = 00, int sec = 00)
{
double pi = 3.141592650f;
double twopi = 2 * pi;
double deg2rad = pi / 180.0f;
// get a day of the year, e.g. Feb 1 = 32, Mar 1 = 61 on leap years
int[] month_days = new int[] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
for (int i=0; i<month; i++)
day += month_days[i];
bool leapdays = ((year % 4) == 0 && ((year % 400) == 0 || (year % 100) != 0) && day >= 60 && !(month==2 && day==60));
if (leapdays) day++;
// Get Julian date - 2400000
hour += min / 60.0f + sec / 3600.0f; // hour plus fraction
double delta = year - 1949.0f;
double leap = Math.Truncate(delta / 4.0f); // former leapyears
double jd = 32916.5f + delta * 365 + leap + day + hour / 24.0f;
// calculating input for the Atronomer's almanach as the difference between
// the Julian date and JD 2451545.0 (noon, 1 January 2000)
double time = jd - 51545.0f;
// calculating mean longitude and mean anomaly
double mnlong = 280.460f + 0.9856474f * time;
mnlong = mnlong % 360;
if (mnlong < 0) mnlong += 360;
double mnanom = 357.528f + 0.9856003f * time;
mnanom = mnanom %360;
if (mnanom < 0) mnanom += 360;
mnanom *= deg2rad;
// calculating ecliptic longitude and obliquity of ecliptic
double eclong = mnlong + 1.915f * MathLib.Sin(mnanom) + 0.020f * MathLib.Sin(2 * mnanom);
eclong = eclong % 360;
if (eclong < 0) eclong+= 360;
double oblqec = 23.439f - 0.0000004f * time;
eclong *= deg2rad;
oblqec *= deg2rad;
// calculating celestial coordinates: right ascension and declination
double num = MathLib.Cos(oblqec) * MathLib.Sin(eclong);
double den = MathLib.Cos(eclong);
double ra = MathLib.Atan(num / den);
if (den < 0) ra += pi;
if (den >= 0 && num < 0) ra += twopi;
double dec = MathLib.asin(MathLib.Sin(oblqec) * MathLib.Sin(eclong));
// calculating local coordinates Greenwich mean sidereal time
double gmst = 6.697375f + 0.0657098242f * time + hour;
gmst = gmst % 24;
if (gmst < 0) gmst += 24.0f;
// calculating local mean sidereal time
double lmst = gmst + lon / 15.0f;
lmst = lmst % 24;
if (lmst < 0) lmst += 24.0f;
lmst = lmst * 15.0f * deg2rad;
// calculating hour angle
double ha = lmst - ra;
if (ha < -pi) ha += twopi;
if (ha > pi) ha -= twopi;
// converting latitude to radians
lat = lat * deg2rad;
// calculating zimuth and elevation
elevation = MathLib.Asin(MathLib.Sin(dec) * MathLib.Sin(lat) + MathLib.Cos(dec) * MathLib.Cos(lat) * MathLib.Cos(ha));
azimuth = MathLib.Asin(-MathLib.Cos(dec) * MathLib.Sin(ha) / MathLib.Cos(elevation));
// for logic and names, see Spencer, J.W. 1989. Solar Energy. 42(4):353
bool cosAzPos = (0 <= MathLib.Sin(dec) - MathLib.Sin(elevation) * MathLib.Sin(lat));
bool sinAzNeg = (MathLib.Sin(azimuth) < 0);
if (cosAzPos && sinAzNeg) azimuth +=twopi;
if (!cosAzPos) azimuth= pi - azimuth;
// return elevation and azimuth
elevation = elevation / deg2rad;
azimuth = azimuth / deg2rad;
}
Thus, we can simply set the position of the Sun as follows:
public override bool Init()
{
/* ... */
// geo-coordinates of a point (latitude and longitude)
double lat = 56.49771;
double lon = 84.97437;
// elevation and azimuth to store calculated values
double elevation=0, azimuth=0;
LightWorld sun = World.GetNodeByName("sun") as LightWorld;
if (sun != null)
{
// calculating azimuth and elevation
// for the specified date,
// GMT time and geo-coordinates
sunPosition(ref elevation, ref azimuth, lat, lon,
2019, 2, 5, // February 5, 2019
4, 0, 0); // 04:00:00 (GMT)
// setting real Sun position for the calculated azimuth and elevation values
sun.Rotation = new quat(90, 270, 270) * (new quat((float)azimuth, 0, 0)) * (new quat(0, 90, 0)) * (new quat((float)elevation, 0, 0)) * (new quat(90, 0, 0));
}
return 1;
}
LightWorld Class
Enums
SCATTERING#
SHADOW_CASCADE_MODE#
Properties
int Mode#
float ShadowZFar#
float ShadowWidth#
float ShadowHeight#
int NumShadowCascades#
LightWorld.SHADOW_CASCADE_MODE ShadowCascadeMode#
- Dynamic - shadow cascades are built dynamically relative to the camera's position.
- Static - shadow cascades are built relative to the world light's position and baked. This mode is suitable for archviz projects.
float DisableAngle#
LightWorld.SCATTERING Scattering#
Members
static LightWorld ( vec4 color ) #
Constructor. Creates a new world light source with a given color.Arguments
- vec4 color - Color of the new light source.
void SetShadowCascadeBorder ( int num, float r ) #
Sets the multiplier for the distance to the border of the specified shadow cascade at which the corresponding shadows are rendered.Arguments
- int num - The number of the cascade in range [0;num_cascades-1].
- float r - Distance multiplier to be set, in range [0; 1].
float GetShadowCascadeBorder ( int num ) #
Returns the multiplier for the distance to the border of the specified shadow cascade at which the corresponding shadows are rendered.Arguments
- int num - The number of the cascade in range [0;num_cascades-1].