|
|
|
|
@@ -1,4 +1,4 @@
|
|
|
|
|
/*
|
|
|
|
|
/*
|
|
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
@@ -52,9 +52,9 @@
|
|
|
|
|
* */
|
|
|
|
|
#define VEC3OPF(v1, v2, op, f1) \
|
|
|
|
|
{ \
|
|
|
|
|
v1[0] = (v2[0] op (f1)); \
|
|
|
|
|
v1[1] = (v2[1] op (f1)); \
|
|
|
|
|
v1[2] = (v2[2] op (f1)); \
|
|
|
|
|
v1[0] = (v2[0] op(f1)); \
|
|
|
|
|
v1[1] = (v2[1] op(f1)); \
|
|
|
|
|
v1[2] = (v2[2] op(f1)); \
|
|
|
|
|
} (void)0
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -125,12 +125,13 @@ static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta,
|
|
|
|
|
float den, num;
|
|
|
|
|
|
|
|
|
|
den = ((1 + lam[0] * expf(lam[1])) *
|
|
|
|
|
(1 + lam[2] * expf(lam[3] * sunsky->theta) + lam[4] * cosf(sunsky->theta) * cosf(sunsky->theta)));
|
|
|
|
|
(1 + lam[2] * expf(lam[3] * sunsky->theta) + lam[4] * cosf(sunsky->theta) * cosf(sunsky->theta)));
|
|
|
|
|
|
|
|
|
|
num = ((1 + lam[0] * expf(lam[1] / cosf(theta))) *
|
|
|
|
|
(1 + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma)));
|
|
|
|
|
(1 + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma)));
|
|
|
|
|
|
|
|
|
|
return(lvz * num / den);}
|
|
|
|
|
return(lvz * num / den);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* InitSunSky:
|
|
|
|
|
@@ -146,8 +147,8 @@ static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta,
|
|
|
|
|
* back_scatter, controls back scatter light
|
|
|
|
|
* */
|
|
|
|
|
void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness,
|
|
|
|
|
float spread, float sun_brightness, float sun_size, float back_scatter,
|
|
|
|
|
float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace)
|
|
|
|
|
float spread, float sun_brightness, float sun_size, float back_scatter,
|
|
|
|
|
float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace)
|
|
|
|
|
{
|
|
|
|
|
float theta2;
|
|
|
|
|
float theta3;
|
|
|
|
|
@@ -162,10 +163,10 @@ void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_b
|
|
|
|
|
sunsky->sun_brightness = sun_brightness;
|
|
|
|
|
sunsky->sun_size = sun_size;
|
|
|
|
|
sunsky->backscattered_light = back_scatter;
|
|
|
|
|
sunsky->skyblendfac= skyblendfac;
|
|
|
|
|
sunsky->skyblendtype= skyblendtype;
|
|
|
|
|
sunsky->sky_exposure= -sky_exposure;
|
|
|
|
|
sunsky->sky_colorspace= sky_colorspace;
|
|
|
|
|
sunsky->skyblendfac = skyblendfac;
|
|
|
|
|
sunsky->skyblendtype = skyblendtype;
|
|
|
|
|
sunsky->sky_exposure = -sky_exposure;
|
|
|
|
|
sunsky->sky_colorspace = sky_colorspace;
|
|
|
|
|
|
|
|
|
|
sunsky->toSun[0] = toSun[0];
|
|
|
|
|
sunsky->toSun[1] = toSun[1];
|
|
|
|
|
@@ -175,27 +176,27 @@ void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_b
|
|
|
|
|
|
|
|
|
|
sunsky->sunSolidAngle = 0.25 * M_PI * 1.39 * 1.39 / (150 * 150); // = 6.7443e-05
|
|
|
|
|
|
|
|
|
|
theta2 = sunsky->theta*sunsky->theta;
|
|
|
|
|
theta2 = sunsky->theta * sunsky->theta;
|
|
|
|
|
theta3 = theta2 * sunsky->theta;
|
|
|
|
|
T = turb;
|
|
|
|
|
T2 = turb*turb;
|
|
|
|
|
T2 = turb * turb;
|
|
|
|
|
|
|
|
|
|
chi = (4.0f / 9.0f - T / 120.0f) * ((float)M_PI - 2.0f * sunsky->theta);
|
|
|
|
|
sunsky->zenith_Y = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
|
|
|
|
|
sunsky->zenith_Y *= 1000; // conversion from kcd/m^2 to cd/m^2
|
|
|
|
|
|
|
|
|
|
if (sunsky->zenith_Y<=0)
|
|
|
|
|
if (sunsky->zenith_Y <= 0)
|
|
|
|
|
sunsky->zenith_Y = 1e-6;
|
|
|
|
|
|
|
|
|
|
sunsky->zenith_x =
|
|
|
|
|
( + 0.00165f * theta3 - 0.00374f * theta2 + 0.00208f * sunsky->theta + 0.0f) * T2 +
|
|
|
|
|
( -0.02902f * theta3 + 0.06377f * theta2 - 0.03202f * sunsky->theta + 0.00394f) * T +
|
|
|
|
|
( + 0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * sunsky->theta + 0.25885f);
|
|
|
|
|
(+0.00165f * theta3 - 0.00374f * theta2 + 0.00208f * sunsky->theta + 0.0f) * T2 +
|
|
|
|
|
(-0.02902f * theta3 + 0.06377f * theta2 - 0.03202f * sunsky->theta + 0.00394f) * T +
|
|
|
|
|
(+0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * sunsky->theta + 0.25885f);
|
|
|
|
|
|
|
|
|
|
sunsky->zenith_y =
|
|
|
|
|
( + 0.00275f * theta3 - 0.00610f * theta2 + 0.00316f * sunsky->theta + 0.0f) * T2 +
|
|
|
|
|
( -0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * sunsky->theta + 0.00515f) * T +
|
|
|
|
|
( + 0.15346f * theta3 - 0.26756f * theta2 + 0.06669f * sunsky->theta + 0.26688f);
|
|
|
|
|
(+0.00275f * theta3 - 0.00610f * theta2 + 0.00316f * sunsky->theta + 0.0f) * T2 +
|
|
|
|
|
(-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * sunsky->theta + 0.00515f) * T +
|
|
|
|
|
(+0.15346f * theta3 - 0.26756f * theta2 + 0.06669f * sunsky->theta + 0.26688f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sunsky->perez_Y[0] = 0.17872f * T - 1.46303f;
|
|
|
|
|
@@ -248,24 +249,24 @@ void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_b
|
|
|
|
|
* phi, is sun's phi
|
|
|
|
|
* color_out, is computed color that shows sky radiance in XYZ color format
|
|
|
|
|
* */
|
|
|
|
|
void GetSkyXYZRadiance(struct SunSky* sunsky, float theta, float phi, float color_out[3])
|
|
|
|
|
void GetSkyXYZRadiance(struct SunSky *sunsky, float theta, float phi, float color_out[3])
|
|
|
|
|
{
|
|
|
|
|
float gamma;
|
|
|
|
|
float x, y, Y, X, Z;
|
|
|
|
|
float hfade=1, nfade=1;
|
|
|
|
|
float hfade = 1, nfade = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (theta>(0.5f*(float)M_PI)) {
|
|
|
|
|
hfade = 1.0f-(theta*(float)M_1_PI-0.5f)*2.0f;
|
|
|
|
|
hfade = hfade*hfade*(3.0f-2.0f*hfade);
|
|
|
|
|
theta = 0.5*M_PI;
|
|
|
|
|
if (theta > (0.5f * (float)M_PI)) {
|
|
|
|
|
hfade = 1.0f - (theta * (float)M_1_PI - 0.5f) * 2.0f;
|
|
|
|
|
hfade = hfade * hfade * (3.0f - 2.0f * hfade);
|
|
|
|
|
theta = 0.5 * M_PI;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sunsky->theta>(0.5f*(float)M_PI)) {
|
|
|
|
|
if (theta<=0.5f*(float)M_PI) {
|
|
|
|
|
nfade = 1.0f-(0.5f-theta*(float)M_1_PI)*2.0f;
|
|
|
|
|
nfade *= 1.0f-(sunsky->theta*(float)M_1_PI-0.5f)*2.0f;
|
|
|
|
|
nfade = nfade*nfade*(3.0f-2.0f*nfade);
|
|
|
|
|
if (sunsky->theta > (0.5f * (float)M_PI)) {
|
|
|
|
|
if (theta <= 0.5f * (float)M_PI) {
|
|
|
|
|
nfade = 1.0f - (0.5f - theta * (float)M_1_PI) * 2.0f;
|
|
|
|
|
nfade *= 1.0f - (sunsky->theta * (float)M_1_PI - 0.5f) * 2.0f;
|
|
|
|
|
nfade = nfade * nfade * (3.0f - 2.0f * nfade);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -274,10 +275,10 @@ void GetSkyXYZRadiance(struct SunSky* sunsky, float theta, float phi, float colo
|
|
|
|
|
// Compute xyY values
|
|
|
|
|
x = PerezFunction(sunsky, sunsky->perez_x, theta, gamma, sunsky->zenith_x);
|
|
|
|
|
y = PerezFunction(sunsky, sunsky->perez_y, theta, gamma, sunsky->zenith_y);
|
|
|
|
|
Y = 6.666666667e-5f * nfade * hfade * PerezFunction(sunsky, sunsky->perez_Y, theta, gamma, sunsky->zenith_Y);
|
|
|
|
|
Y = 6.666666667e-5f *nfade *hfade *PerezFunction(sunsky, sunsky->perez_Y, theta, gamma, sunsky->zenith_Y);
|
|
|
|
|
|
|
|
|
|
if (sunsky->sky_exposure!=0.0f)
|
|
|
|
|
Y = 1.0 - exp(Y*sunsky->sky_exposure);
|
|
|
|
|
if (sunsky->sky_exposure != 0.0f)
|
|
|
|
|
Y = 1.0 - exp(Y * sunsky->sky_exposure);
|
|
|
|
|
|
|
|
|
|
X = (x / y) * Y;
|
|
|
|
|
Z = ((1 - x - y) / y) * Y;
|
|
|
|
|
@@ -295,12 +296,12 @@ void GetSkyXYZRadiance(struct SunSky* sunsky, float theta, float phi, float colo
|
|
|
|
|
* varg, shows direction
|
|
|
|
|
* color_out, is computed color that shows sky radiance in XYZ color format
|
|
|
|
|
* */
|
|
|
|
|
void GetSkyXYZRadiancef(struct SunSky* sunsky, const float varg[3], float color_out[3])
|
|
|
|
|
void GetSkyXYZRadiancef(struct SunSky *sunsky, const float varg[3], float color_out[3])
|
|
|
|
|
{
|
|
|
|
|
float theta, phi;
|
|
|
|
|
float v[3];
|
|
|
|
|
float theta, phi;
|
|
|
|
|
float v[3];
|
|
|
|
|
|
|
|
|
|
copy_v3_v3(v, (float*)varg);
|
|
|
|
|
copy_v3_v3(v, (float *)varg);
|
|
|
|
|
normalize_v3(v);
|
|
|
|
|
|
|
|
|
|
if (v[2] < 0.001f) {
|
|
|
|
|
@@ -336,7 +337,7 @@ static void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3])
|
|
|
|
|
fAlpha = 1.3f;
|
|
|
|
|
fBeta = 0.04608365822050f * turbidity - 0.04586025928522f;
|
|
|
|
|
|
|
|
|
|
m = 1.0f/(cosf(theta) + 0.15f*powf(93.885f-theta/(float)M_PI*180.0f, -1.253f));
|
|
|
|
|
m = 1.0f / (cosf(theta) + 0.15f * powf(93.885f - theta / (float)M_PI * 180.0f, -1.253f));
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
// Rayleigh Scattering
|
|
|
|
|
@@ -362,15 +363,15 @@ static void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3])
|
|
|
|
|
* disf, is distance factor, multiplyed to pixle's z value to compute each pixle's distance to camera,
|
|
|
|
|
* */
|
|
|
|
|
void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float rayf,
|
|
|
|
|
float inscattf, float extincf, float disf)
|
|
|
|
|
float inscattf, float extincf, float disf)
|
|
|
|
|
{
|
|
|
|
|
const float pi = 3.14159265358f;
|
|
|
|
|
const float pi = M_PI;
|
|
|
|
|
const float n = 1.003f; // refractive index
|
|
|
|
|
const float N = 2.545e25;
|
|
|
|
|
const float pn = 0.035f;
|
|
|
|
|
const float T = 2.0f;
|
|
|
|
|
float fTemp, fTemp2, fTemp3, fBeta, fBetaDash;
|
|
|
|
|
float c = (6.544f*T - 6.51f)*1e-17f;
|
|
|
|
|
float c = (6.544f * T - 6.51f) * 1e-17f;
|
|
|
|
|
float K[3] = {0.685f, 0.679f, 0.670f};
|
|
|
|
|
float vBetaMieTemp[3];
|
|
|
|
|
|
|
|
|
|
@@ -387,14 +388,14 @@ void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float r
|
|
|
|
|
sunSky->atm_ExtinctionMultiplier = extincf;
|
|
|
|
|
sunSky->atm_DistanceMultiplier = disf;
|
|
|
|
|
|
|
|
|
|
sunSky->atm_HGg=0.8;
|
|
|
|
|
sunSky->atm_HGg = 0.8;
|
|
|
|
|
|
|
|
|
|
fLambda[0] = 1/650e-9f;
|
|
|
|
|
fLambda[1] = 1/570e-9f;
|
|
|
|
|
fLambda[2] = 1/475e-9f;
|
|
|
|
|
for (i=0; i < 3; i++) {
|
|
|
|
|
fLambda2[i] = fLambda[i]*fLambda[i];
|
|
|
|
|
fLambda4[i] = fLambda2[i]*fLambda2[i];
|
|
|
|
|
fLambda[0] = 1 / 650e-9f;
|
|
|
|
|
fLambda[1] = 1 / 570e-9f;
|
|
|
|
|
fLambda[2] = 1 / 475e-9f;
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
fLambda2[i] = fLambda[i] * fLambda[i];
|
|
|
|
|
fLambda4[i] = fLambda2[i] * fLambda2[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vLambda2[0] = fLambda2[0];
|
|
|
|
|
@@ -406,19 +407,19 @@ void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float r
|
|
|
|
|
vLambda4[2] = fLambda4[2];
|
|
|
|
|
|
|
|
|
|
// Rayleigh scattering constants.
|
|
|
|
|
fTemp = pi*pi*(n*n-1)*(n*n-1)*(6+3*pn)/(6-7*pn)/N;
|
|
|
|
|
fBeta = 8*fTemp*pi/3;
|
|
|
|
|
fTemp = pi * pi * (n * n - 1) * (n * n - 1) * (6 + 3 * pn) / (6 - 7 * pn) / N;
|
|
|
|
|
fBeta = 8 * fTemp * pi / 3;
|
|
|
|
|
|
|
|
|
|
VEC3OPF(sunSky->atm_BetaRay, vLambda4, *, fBeta);
|
|
|
|
|
fBetaDash = fTemp/2;
|
|
|
|
|
fBetaDash = fTemp / 2;
|
|
|
|
|
VEC3OPF(sunSky->atm_BetaDashRay, vLambda4, *, fBetaDash);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Mie scattering constants.
|
|
|
|
|
fTemp2 = 0.434f*c*(2*pi)*(2*pi)*0.5f;
|
|
|
|
|
fTemp2 = 0.434f * c * (2 * pi) * (2 * pi) * 0.5f;
|
|
|
|
|
VEC3OPF(sunSky->atm_BetaDashMie, vLambda2, *, fTemp2);
|
|
|
|
|
|
|
|
|
|
fTemp3 = 0.434f*c*pi*(2*pi)*(2*pi);
|
|
|
|
|
fTemp3 = 0.434f * c * pi * (2 * pi) * (2 * pi);
|
|
|
|
|
|
|
|
|
|
VEC3OPV(vBetaMieTemp, K, *, fLambda);
|
|
|
|
|
VEC3OPF(sunSky->atm_BetaMie, vBetaMieTemp, *, fTemp3);
|
|
|
|
|
@@ -434,7 +435,7 @@ void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float r
|
|
|
|
|
* s, is distance
|
|
|
|
|
* rgb, contains rendered color value for a pixle
|
|
|
|
|
* */
|
|
|
|
|
void AtmospherePixleShader(struct SunSky* sunSky, float view[3], float s, float rgb[3])
|
|
|
|
|
void AtmospherePixleShader(struct SunSky *sunSky, float view[3], float s, float rgb[3])
|
|
|
|
|
{
|
|
|
|
|
float costheta;
|
|
|
|
|
float Phase_1;
|
|
|
|
|
@@ -465,7 +466,7 @@ void AtmospherePixleShader(struct SunSky* sunSky, float view[3], float s, float
|
|
|
|
|
VEC3OPV(sunSky->atm_BetaRM, sunSky->atm_BetaRay, +, sunSky->atm_BetaMie);
|
|
|
|
|
|
|
|
|
|
//e^(-(beta_1 + beta_2) * s) = E1
|
|
|
|
|
VEC3OPF(E1, sunSky->atm_BetaRM, *, -s/(float)M_LN2);
|
|
|
|
|
VEC3OPF(E1, sunSky->atm_BetaRM, *, -s / (float)M_LN2);
|
|
|
|
|
E1[0] = exp(E1[0]);
|
|
|
|
|
E1[1] = exp(E1[1]);
|
|
|
|
|
E1[2] = exp(E1[2]);
|
|
|
|
|
@@ -475,7 +476,7 @@ void AtmospherePixleShader(struct SunSky* sunSky, float view[3], float s, float
|
|
|
|
|
//Phase2(theta) = (1-g^2)/(1+g-2g*cos(theta))^(3/2)
|
|
|
|
|
fTemp = 1 + sunSky->atm_HGg - 2 * sunSky->atm_HGg * costheta;
|
|
|
|
|
fTemp = fTemp * sqrtf(fTemp);
|
|
|
|
|
Phase_2 = (1 - sunSky->atm_HGg * sunSky->atm_HGg)/fTemp;
|
|
|
|
|
Phase_2 = (1 - sunSky->atm_HGg * sunSky->atm_HGg) / fTemp;
|
|
|
|
|
|
|
|
|
|
VEC3OPF(vTemp1, sunSky->atm_BetaDashRay, *, Phase_1);
|
|
|
|
|
VEC3OPF(vTemp2, sunSky->atm_BetaDashMie, *, Phase_2);
|
|
|
|
|
|