paysages : Progress on bruneton atmospheric model (WIP).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@481 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
9da260a5e8
commit
70b42a33c0
5 changed files with 252 additions and 65 deletions
|
@ -25,24 +25,28 @@ static const double Rt = 6420.0;
|
|||
static const double RL = 6421.0;
|
||||
static const double exposure = 0.4;
|
||||
static const double ISun = 100.0;
|
||||
static const double AVERAGE_GROUND_REFLECTANCE = 0.1;
|
||||
|
||||
#define RES_MU 128
|
||||
#define RES_MU_S 32
|
||||
#define RES_R 32
|
||||
#define RES_NU 8
|
||||
#define TRANSMITTANCE_INTEGRAL_SAMPLES 500
|
||||
#define SKY_W 64
|
||||
#define SKY_H 16
|
||||
#define TRANSMITTANCE_W 256
|
||||
#define TRANSMITTANCE_H 64
|
||||
#define TRANSMITTANCE_INTEGRAL_SAMPLES 500
|
||||
#define INSCATTER_INTEGRAL_SAMPLES 50
|
||||
#define IRRADIANCE_INTEGRAL_SAMPLES 32
|
||||
#define INSCATTER_SPHERICAL_INTEGRAL_SAMPLES 16
|
||||
|
||||
Texture2D* _transmittanceTexture = NULL;
|
||||
Texture2D* _irrDeltaETexture = NULL;
|
||||
Texture2D* _deltaETexture = NULL;
|
||||
Texture2D* _irradianceTexture = NULL;
|
||||
Texture3D* _inscatterTexture = NULL;
|
||||
Texture3D* _deltaSMTexture = NULL;
|
||||
Texture3D* _deltaSRTexture = NULL;
|
||||
Texture3D* _deltaJTexture = NULL;
|
||||
|
||||
// Rayleigh
|
||||
static const double HR = 8.0;
|
||||
|
@ -369,29 +373,27 @@ static Color _hdr(Color c1, Color c2, Color c3)
|
|||
|
||||
static void _getMuMuSNu(double x, double y, double r, Color dhdH, double* mu, double* muS, double* nu)
|
||||
{
|
||||
x -= 0.5;
|
||||
y -= 0.5;
|
||||
#ifdef INSCATTER_NON_LINEAR
|
||||
double d;
|
||||
if (y < (double)(RES_MU) / 2.0)
|
||||
{
|
||||
d = 1.0 - y / ((double)(RES_MU) / 2.0 - 1.0);
|
||||
d = 1.0 - y / ((double)(RES_MU) / 2.0);
|
||||
d = min(max(dhdH.b, d * dhdH.a), dhdH.a * 0.999);
|
||||
*mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
|
||||
*mu = min(*mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
|
||||
}
|
||||
else
|
||||
{
|
||||
double d = (y - (double)(RES_MU) / 2.0) / ((double)(RES_MU) / 2.0 - 1.0);
|
||||
double d = (y - (double)(RES_MU) / 2.0) / ((double)(RES_MU) / 2.0);
|
||||
d = min(max(dhdH.r, d * dhdH.g), dhdH.g * 0.999);
|
||||
*mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
|
||||
}
|
||||
*muS = fmod(x, (double)(RES_MU_S)) / ((double)(RES_MU_S) - 1.0);
|
||||
*muS = fmod(x, (double)(RES_MU_S)) / ((double)(RES_MU_S));
|
||||
/* paper formula :
|
||||
* muS = -(0.6 + log(1.0 - muS * (1.0 - exp(-3.6)))) / 3.0; */
|
||||
/* better formula */
|
||||
*muS = tan((2.0 * (*muS) - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
|
||||
*nu = -1.0 + floor(x / (double)(RES_MU_S)) / ((double)(RES_NU) - 1.0) * 2.0;
|
||||
*nu = -1.0 + floor(x / (double)(RES_MU_S)) / ((double)(RES_NU)) * 2.0;
|
||||
#else
|
||||
mu = -1.0 + 2.0 * y / (float(RES_MU) - 1.0);
|
||||
muS = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
|
||||
|
@ -400,6 +402,19 @@ static void _getMuMuSNu(double x, double y, double r, Color dhdH, double* mu, do
|
|||
#endif
|
||||
}
|
||||
|
||||
static void _getIrradianceUV(double r, double muS, double* uMuS, double* uR)
|
||||
{
|
||||
*uR = (r - Rg) / (Rt - Rg);
|
||||
*uMuS = (muS + 0.2) / (1.0 + 0.2);
|
||||
}
|
||||
|
||||
static Color _irradiance(Texture2D* sampler, double r, double muS)
|
||||
{
|
||||
double u, v;
|
||||
_getIrradianceUV(r, muS, &u, &v);
|
||||
return texture2DGetLinear(sampler, u, v);
|
||||
}
|
||||
|
||||
/*********************** Texture precomputing ***********************/
|
||||
|
||||
static void _precomputeTransmittanceTexture()
|
||||
|
@ -439,14 +454,13 @@ static void _precomputeIrrDeltaETexture()
|
|||
trans = _transmittance(r, muS);
|
||||
|
||||
_getTransmittanceUV(r, muS, &u, &v);
|
||||
//printf("%d %d -> %f %f -> %f %f %f\n", x, y, u, v, trans.r, trans.g, trans.b);
|
||||
|
||||
irr.r = trans.r * max(muS, 0.0);
|
||||
irr.g = trans.g * max(muS, 0.0);
|
||||
irr.b = trans.b * max(muS, 0.0);
|
||||
irr.a = 1.0;
|
||||
|
||||
texture2DSetPixel(_irrDeltaETexture, x, y, irr);
|
||||
texture2DSetPixel(_deltaETexture, x, y, irr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -544,7 +558,7 @@ static void _inscatter1Prog(Texture3D* tex_rayleigh, Texture3D* tex_mie)
|
|||
Color ray = COLOR_BLACK;
|
||||
Color mie = COLOR_BLACK;
|
||||
double mu, muS, nu;
|
||||
_getMuMuSNu((double)x + 0.5, (double)y + 0.5, _r, _dhdH, &mu, &muS, &nu);
|
||||
_getMuMuSNu((double)x, (double)y, _r, _dhdH, &mu, &muS, &nu);
|
||||
_inscatter1(_r, mu, muS, nu, &ray, &mie);
|
||||
/* store separately Rayleigh and Mie contributions, WITHOUT the phase function factor
|
||||
* (cf "Angular precision") */
|
||||
|
@ -552,7 +566,177 @@ static void _inscatter1Prog(Texture3D* tex_rayleigh, Texture3D* tex_mie)
|
|||
texture3DSetPixel(tex_mie, x, y, _layer, mie);
|
||||
}
|
||||
}
|
||||
/* TODO Iterate texture */
|
||||
}
|
||||
|
||||
/*********************** inscatterS.glsl ***********************/
|
||||
|
||||
static Color _inscatterS(double r, double mu, double muS, double nu, int first)
|
||||
{
|
||||
Color raymie = COLOR_BLACK;
|
||||
|
||||
double dphi = M_PI / (double)(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
double dtheta = M_PI / (double)(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
|
||||
r = clamp(r, Rg, Rt);
|
||||
mu = clamp(mu, -1.0, 1.0);
|
||||
muS = clamp(muS, -1.0, 1.0);
|
||||
double var = sqrt(1.0 - mu * mu) * sqrt(1.0 - muS * muS);
|
||||
nu = clamp(nu, muS * mu - var, muS * mu + var);
|
||||
|
||||
double cthetamin = -sqrt(1.0 - (Rg / r) * (Rg / r));
|
||||
|
||||
Vector3 v = vec3(sqrt(1.0 - mu * mu), 0.0, mu);
|
||||
double sx = v.x == 0.0 ? 0.0 : (nu - muS * mu) / v.x;
|
||||
Vector3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - muS * muS)), muS);
|
||||
|
||||
/* integral over 4.PI around x with two nested loops over w directions (theta,phi) -- Eq (7) */
|
||||
int itheta;
|
||||
for (itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta)
|
||||
{
|
||||
double theta = ((double)(itheta) + 0.5) * dtheta;
|
||||
double ctheta = cos(theta);
|
||||
|
||||
double greflectance = 0.0;
|
||||
double dground = 0.0;
|
||||
Color gtransp = {0.0, 0.0, 0.0, 0.0};
|
||||
if (ctheta < cthetamin)
|
||||
{
|
||||
/* if ground visible in direction w
|
||||
* compute transparency gtransp between x and ground */
|
||||
greflectance = AVERAGE_GROUND_REFLECTANCE / M_PI;
|
||||
dground = -r * ctheta - sqrt(r * r * (ctheta * ctheta - 1.0) + Rg * Rg);
|
||||
gtransp = _transmittance3(Rg, -(r * ctheta + dground) / Rg, dground);
|
||||
}
|
||||
|
||||
int iphi;
|
||||
for (iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi)
|
||||
{
|
||||
double phi = ((double)(iphi) + 0.5) * dphi;
|
||||
double dw = dtheta * dphi * sin(theta);
|
||||
Vector3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), ctheta);
|
||||
|
||||
double nu1 = v3Dot(s, w);
|
||||
double nu2 = v3Dot(v, w);
|
||||
double pr2 = _phaseFunctionR(nu2);
|
||||
double pm2 = _phaseFunctionM(nu2);
|
||||
|
||||
/* compute irradiance received at ground in direction w (if ground visible) =deltaE */
|
||||
Vector3 gnormal;
|
||||
gnormal.x = dground * w.x / Rg;
|
||||
gnormal.y = dground * w.y / Rg;
|
||||
gnormal.z = r + dground * w.z / Rg;
|
||||
Color girradiance = _irradiance(_deltaETexture, Rg, v3Dot(gnormal, s));
|
||||
|
||||
Color raymie1; /* light arriving at x from direction w */
|
||||
|
||||
/* first term = light reflected from the ground and attenuated before reaching x, =T.alpha/PI.deltaE */
|
||||
raymie1.r = greflectance * girradiance.r * gtransp.r;
|
||||
raymie1.g = greflectance * girradiance.g * gtransp.g;
|
||||
raymie1.b = greflectance * girradiance.b * gtransp.b;
|
||||
|
||||
/* second term = inscattered light, =deltaS */
|
||||
if (first)
|
||||
{
|
||||
/* first iteration is special because Rayleigh and Mie were stored separately,
|
||||
* without the phase functions factors; they must be reintroduced here */
|
||||
double pr1 = _phaseFunctionR(nu1);
|
||||
double pm1 = _phaseFunctionM(nu1);
|
||||
Color ray1 = _texture4D(_deltaSRTexture, r, w.z, muS, nu1);
|
||||
Color mie1 = _texture4D(_deltaSMTexture, r, w.z, muS, nu1);
|
||||
raymie.r += ray1.r * pr1 + mie1.r + pm1;
|
||||
raymie.g += ray1.g * pr1 + mie1.g + pm1;
|
||||
raymie.b += ray1.b * pr1 + mie1.b + pm1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Color col = _texture4D(_deltaSRTexture, r, w.z, muS, nu1);
|
||||
raymie1.r += col.r;
|
||||
raymie1.g += col.g;
|
||||
raymie1.b += col.b;
|
||||
}
|
||||
|
||||
/* light coming from direction w and scattered in direction v
|
||||
= light arriving at x from direction w (raymie1) * SUM(scattering coefficient * phaseFunction)
|
||||
see Eq (7) */
|
||||
raymie.r += raymie1.r * (betaR.r * exp(-(r - Rg) / HR) * pr2 + betaMSca.x * exp(-(r - Rg) / HM) * pm2) * dw;
|
||||
raymie.g += raymie1.g * (betaR.g * exp(-(r - Rg) / HR) * pr2 + betaMSca.y * exp(-(r - Rg) / HM) * pm2) * dw;
|
||||
raymie.b += raymie1.b * (betaR.b * exp(-(r - Rg) / HR) * pr2 + betaMSca.z * exp(-(r - Rg) / HM) * pm2) * dw;
|
||||
}
|
||||
}
|
||||
|
||||
/* output raymie = J[T.alpha/PI.deltaE + deltaS] (line 7 in algorithm 4.1) */
|
||||
return raymie;
|
||||
}
|
||||
|
||||
static void _jProg(Texture3D* result, int first)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < RES_MU_S * RES_NU; x++)
|
||||
{
|
||||
for (y = 0; y < RES_MU; y++)
|
||||
{
|
||||
Color raymie;
|
||||
double mu, muS, nu;
|
||||
_getMuMuSNu((double)x, (double)y, _r, _dhdH, &mu, &muS, &nu);
|
||||
raymie = _inscatterS(_r, mu, muS, nu, first);
|
||||
texture3DSetPixel(result, x, y, _layer, raymie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************** irradianceN.glsl ***********************/
|
||||
|
||||
void _irradianceNProg(Texture2D* tex, int first)
|
||||
{
|
||||
int x, y;
|
||||
double dphi = M_PI / (double)(IRRADIANCE_INTEGRAL_SAMPLES);
|
||||
double dtheta = M_PI / (double)(IRRADIANCE_INTEGRAL_SAMPLES);
|
||||
for (x = 0; x < SKY_W; x++)
|
||||
{
|
||||
for (y = 0; y < SKY_H; y++)
|
||||
{
|
||||
double r, muS;
|
||||
int iphi;
|
||||
_getIrradianceRMuS((double)x / SKY_W, (double)y / SKY_H, &r, &muS);
|
||||
Vector3 s = vec3(max(sqrt(1.0 - muS * muS), 0.0), 0.0, muS);
|
||||
|
||||
Color result = COLOR_BLACK;
|
||||
/* integral over 2.PI around x with two nested loops over w directions (theta,phi) -- Eq (15) */
|
||||
for (iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi)
|
||||
{
|
||||
double phi = ((double)(iphi) + 0.5) * dphi;
|
||||
int itheta;
|
||||
for (itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta)
|
||||
{
|
||||
double theta = ((double)(itheta) + 0.5) * dtheta;
|
||||
double dw = dtheta * dphi * sin(theta);
|
||||
Vector3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
|
||||
double nu = v3Dot(s, w);
|
||||
if (first)
|
||||
{
|
||||
/* first iteration is special because Rayleigh and Mie were stored separately,
|
||||
without the phase functions factors; they must be reintroduced here */
|
||||
double pr1 = _phaseFunctionR(nu);
|
||||
double pm1 = _phaseFunctionM(nu);
|
||||
Color ray1 = _texture4D(_deltaSRTexture, r, w.z, muS, nu);
|
||||
Color mie1 = _texture4D(_deltaSMTexture, r, w.z, muS, nu);
|
||||
result.r += (ray1.r * pr1 + mie1.r * pm1) * w.z * dw;
|
||||
result.g += (ray1.g * pr1 + mie1.g * pm1) * w.z * dw;
|
||||
result.b += (ray1.b * pr1 + mie1.b * pm1) * w.z * dw;
|
||||
}
|
||||
else
|
||||
{
|
||||
Color col = _texture4D(_deltaSRTexture, r, w.z, muS, nu);
|
||||
result.r += col.r * w.z * dw;
|
||||
result.g += col.g * w.z * dw;
|
||||
result.b += col.b * w.z * dw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
texture2DSetPixel(tex, x, y, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************** Final getters ***********************/
|
||||
|
@ -717,25 +901,25 @@ static Color _sunColor(Vector3 x, double t, Vector3 v, Vector3 s, double r, doub
|
|||
}
|
||||
else
|
||||
{
|
||||
Color transmittance = r <= Rt ? _transmittanceWithShadow(r, mu) : COLOR_WHITE; // T(x,xo)
|
||||
double isun = step(cos(M_PI / 180.0), v3Dot(v, s)) * ISun; // Lsun
|
||||
Color transmittance = r <= Rt ? _transmittanceWithShadow(r, mu) : COLOR_WHITE; /* T(x,xo) */
|
||||
double isun = step(cos(M_PI / 180.0), v3Dot(v, s)) * ISun; /* Lsun */
|
||||
transmittance.r *= isun;
|
||||
transmittance.g *= isun;
|
||||
transmittance.b *= isun;
|
||||
transmittance.a *= isun;
|
||||
return transmittance; // Eq (9)
|
||||
return transmittance; /* Eq (9) */
|
||||
}
|
||||
}
|
||||
|
||||
/*********************** Cache methods ***********************/
|
||||
|
||||
static int _tryLoadCache2D(Texture2D* tex, const char* tag)
|
||||
static int _tryLoadCache2D(Texture2D* tex, const char* tag, int order)
|
||||
{
|
||||
CacheFile* cache;
|
||||
int xsize, ysize;
|
||||
|
||||
texture2DGetSize(tex, &xsize, &ysize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, 0);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, 0, order);
|
||||
if (cacheFileIsReadable(cache))
|
||||
{
|
||||
texture2DLoadFromFile(tex, cacheFileGetPath(cache));
|
||||
|
@ -749,13 +933,13 @@ static int _tryLoadCache2D(Texture2D* tex, const char* tag)
|
|||
}
|
||||
}
|
||||
|
||||
static void _saveCache2D(Texture2D* tex, const char* tag)
|
||||
static void _saveCache2D(Texture2D* tex, const char* tag, int order)
|
||||
{
|
||||
CacheFile* cache;
|
||||
int xsize, ysize;
|
||||
|
||||
texture2DGetSize(tex, &xsize, &ysize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, 0);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, 0, order);
|
||||
if (cacheFileIsWritable(cache))
|
||||
{
|
||||
texture2DSaveToFile(tex, cacheFileGetPath(cache));
|
||||
|
@ -763,13 +947,13 @@ static void _saveCache2D(Texture2D* tex, const char* tag)
|
|||
cacheFileDeleteAccessor(cache);
|
||||
}
|
||||
|
||||
static int _tryLoadCache3D(Texture3D* tex, const char* tag)
|
||||
static int _tryLoadCache3D(Texture3D* tex, const char* tag, int order)
|
||||
{
|
||||
CacheFile* cache;
|
||||
int xsize, ysize, zsize;
|
||||
|
||||
texture3DGetSize(tex, &xsize, &ysize, &zsize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, zsize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, zsize, order);
|
||||
if (cacheFileIsReadable(cache))
|
||||
{
|
||||
texture3DLoadFromFile(tex, cacheFileGetPath(cache));
|
||||
|
@ -783,13 +967,13 @@ static int _tryLoadCache3D(Texture3D* tex, const char* tag)
|
|||
}
|
||||
}
|
||||
|
||||
static void _saveCache3D(Texture3D* tex, const char* tag)
|
||||
static void _saveCache3D(Texture3D* tex, const char* tag, int order)
|
||||
{
|
||||
CacheFile* cache;
|
||||
int xsize, ysize, zsize;
|
||||
|
||||
texture3DGetSize(tex, &xsize, &ysize, &zsize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, zsize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, zsize, order);
|
||||
if (cacheFileIsWritable(cache))
|
||||
{
|
||||
texture3DSaveToFile(tex, cacheFileGetPath(cache));
|
||||
|
@ -809,34 +993,34 @@ void brunetonInit()
|
|||
|
||||
/* computes transmittance texture T (line 1 in algorithm 4.1) */
|
||||
_transmittanceTexture = texture2DCreate(TRANSMITTANCE_W, TRANSMITTANCE_H);
|
||||
if (!_tryLoadCache2D(_transmittanceTexture, "transmittance"))
|
||||
if (!_tryLoadCache2D(_transmittanceTexture, "transmittance", 0))
|
||||
{
|
||||
_precomputeTransmittanceTexture();
|
||||
_saveCache2D(_transmittanceTexture, "transmittance");
|
||||
_saveCache2D(_transmittanceTexture, "transmittance", 0);
|
||||
}
|
||||
|
||||
/* computes irradiance texture deltaE (line 2 in algorithm 4.1) */
|
||||
_irrDeltaETexture = texture2DCreate(SKY_W, SKY_H);
|
||||
if (!_tryLoadCache2D(_irrDeltaETexture, "irradianceDeltaE"))
|
||||
_deltaETexture = texture2DCreate(SKY_W, SKY_H);
|
||||
if (!_tryLoadCache2D(_deltaETexture, "irradianceDeltaE", 0))
|
||||
{
|
||||
_precomputeIrrDeltaETexture();
|
||||
_saveCache2D(_irrDeltaETexture, "irradianceDeltaE");
|
||||
_saveCache2D(_deltaETexture, "irradianceDeltaE", 0);
|
||||
}
|
||||
|
||||
/* computes single scattering texture deltaS (line 3 in algorithm 4.1)
|
||||
* Rayleigh and Mie separated in deltaSR + deltaSM */
|
||||
_deltaSRTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
||||
_deltaSMTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
||||
if (!_tryLoadCache3D(_deltaSRTexture, "deltaSR") || !_tryLoadCache3D(_deltaSMTexture, "deltaSM"))
|
||||
if (!_tryLoadCache3D(_deltaSRTexture, "deltaSR", 0) || !_tryLoadCache3D(_deltaSMTexture, "deltaSM", 0))
|
||||
{
|
||||
for (layer = 0; layer < RES_R; ++layer)
|
||||
{
|
||||
printf("%d\n", layer);
|
||||
printf("deltaS %d\n", layer);
|
||||
_setLayer(layer);
|
||||
_inscatter1Prog(_deltaSRTexture, _deltaSMTexture);
|
||||
}
|
||||
_saveCache3D(_deltaSRTexture, "deltaSR");
|
||||
_saveCache3D(_deltaSMTexture, "deltaSM");
|
||||
_saveCache3D(_deltaSRTexture, "deltaSR", 0);
|
||||
_saveCache3D(_deltaSMTexture, "deltaSM", 0);
|
||||
}
|
||||
|
||||
/* copies deltaE into irradiance texture E (line 4 in algorithm 4.1) */
|
||||
|
@ -846,7 +1030,7 @@ void brunetonInit()
|
|||
|
||||
/* copies deltaS into inscatter texture S (line 5 in algorithm 4.1) */
|
||||
_inscatterTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
||||
if (!_tryLoadCache3D(_inscatterTexture, "inscatter"))
|
||||
if (!_tryLoadCache3D(_inscatterTexture, "inscatter", 0))
|
||||
{
|
||||
for (x = 0; x < RES_MU_S * RES_NU; x++)
|
||||
{
|
||||
|
@ -861,35 +1045,31 @@ void brunetonInit()
|
|||
}
|
||||
}
|
||||
}
|
||||
_saveCache3D(_inscatterTexture, "inscatter");
|
||||
_saveCache3D(_inscatterTexture, "inscatter", 0);
|
||||
}
|
||||
|
||||
/* loop for each scattering order (line 6 in algorithm 4.1) */
|
||||
for (order = 2; order <= 4; ++order) {
|
||||
|
||||
for (order = 2; order <= 4; ++order)
|
||||
{
|
||||
/* computes deltaJ (line 7 in algorithm 4.1) */
|
||||
/*glFramebufferTextureEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, deltaJTexture, 0);
|
||||
glViewport(0, 0, RES_MU_S * RES_NU, RES_MU);
|
||||
glUseProgram(jProg);
|
||||
glUniform1f(glGetUniformLocation(jProg, "first"), order == 2 ? 1.0 : 0.0);
|
||||
glUniform1i(glGetUniformLocation(jProg, "transmittanceSampler"), transmittanceUnit);
|
||||
glUniform1i(glGetUniformLocation(jProg, "deltaESampler"), deltaEUnit);
|
||||
glUniform1i(glGetUniformLocation(jProg, "deltaSRSampler"), deltaSRUnit);
|
||||
glUniform1i(glGetUniformLocation(jProg, "deltaSMSampler"), deltaSMUnit);
|
||||
for (int layer = 0; layer < RES_R; ++layer) {
|
||||
setLayer(jProg, layer);
|
||||
drawQuad();
|
||||
}*/
|
||||
_deltaJTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
||||
if (!_tryLoadCache3D(_deltaJTexture, "deltaJ", order))
|
||||
{
|
||||
for (layer = 0; layer < RES_R; ++layer)
|
||||
{
|
||||
_setLayer(layer);
|
||||
_jProg(_deltaJTexture, order == 2);
|
||||
}
|
||||
_saveCache3D(_deltaJTexture, "deltaJ", order);
|
||||
}
|
||||
|
||||
/* computes deltaE (line 8 in algorithm 4.1) */
|
||||
/*glFramebufferTextureEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, deltaETexture, 0);
|
||||
glViewport(0, 0, SKY_W, SKY_H);
|
||||
glUseProgram(irradianceNProg);
|
||||
glUniform1f(glGetUniformLocation(irradianceNProg, "first"), order == 2 ? 1.0 : 0.0);
|
||||
glUniform1i(glGetUniformLocation(irradianceNProg, "transmittanceSampler"), transmittanceUnit);
|
||||
glUniform1i(glGetUniformLocation(irradianceNProg, "deltaSRSampler"), deltaSRUnit);
|
||||
glUniform1i(glGetUniformLocation(irradianceNProg, "deltaSMSampler"), deltaSMUnit);
|
||||
drawQuad();*/
|
||||
_deltaETexture = texture2DCreate(SKY_W, SKY_H);
|
||||
if (!_tryLoadCache2D(_deltaETexture, "deltaE", order))
|
||||
{
|
||||
_irradianceNProg(_deltaETexture, order == 2);
|
||||
_saveCache2D(_deltaETexture, "deltaE", order);
|
||||
}
|
||||
|
||||
/* computes deltaS (line 9 in algorithm 4.1) */
|
||||
/*glFramebufferTextureEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, deltaSRTexture, 0);
|
||||
|
@ -925,11 +1105,11 @@ void brunetonInit()
|
|||
drawQuad();
|
||||
}
|
||||
glDisable(GL_BLEND);*/
|
||||
|
||||
/* DEBUG */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* DEBUG */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position)
|
||||
|
|
|
@ -18,6 +18,8 @@ typedef struct
|
|||
LightDefinition lights[MAX_SKYDOME_LIGHTS];
|
||||
} AtmosphereRendererCache;
|
||||
|
||||
static int _inited = 0;
|
||||
|
||||
/******************** Definition ********************/
|
||||
static void _validateDefinition(AtmosphereDefinition* definition)
|
||||
{
|
||||
|
@ -28,7 +30,12 @@ static AtmosphereDefinition* _createDefinition()
|
|||
{
|
||||
AtmosphereDefinition* result;
|
||||
|
||||
//brunetonInit(); /* DEBUG */
|
||||
/* TODO Find a better place for this */
|
||||
if (!_inited)
|
||||
{
|
||||
_inited = 1;
|
||||
brunetonInit();
|
||||
}
|
||||
|
||||
result = malloc(sizeof(AtmosphereDefinition));
|
||||
result->model = ATMOSPHERE_MODEL_PREETHAM;
|
||||
|
|
|
@ -11,14 +11,14 @@ struct CacheFile
|
|||
char* filepath;
|
||||
};
|
||||
|
||||
CacheFile* cacheFileCreateAccessor(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4)
|
||||
CacheFile* cacheFileCreateAccessor(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4, int tag5)
|
||||
{
|
||||
CacheFile* result;
|
||||
|
||||
result = (CacheFile*)malloc(sizeof(CacheFile));
|
||||
result->filepath = malloc(sizeof(char) * 501);
|
||||
|
||||
snprintf(result->filepath, 500, "./cache/%s-%s-%d-%d-%d.%s", module, tag1, tag2, tag3, tag4, ext);
|
||||
snprintf(result->filepath, 500, "./cache/%s-%s-%d-%d-%d-%d.%s", module, tag1, tag2, tag3, tag4, tag5, ext);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ extern "C" {
|
|||
|
||||
typedef struct CacheFile CacheFile;
|
||||
|
||||
CacheFile* cacheFileCreateAccessor(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4);
|
||||
CacheFile* cacheFileCreateAccessor(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4, int tag5);
|
||||
void cacheFileDeleteAccessor(CacheFile* cache);
|
||||
int cacheFileIsReadable(CacheFile* cache);
|
||||
int cacheFileIsWritable(CacheFile* cache);
|
||||
|
|
|
@ -89,7 +89,7 @@ Color texture2DGetLinear(Texture2D* tex, double dx, double dy)
|
|||
Color texture2DGetCubic(Texture2D* tex, double dx, double dy)
|
||||
{
|
||||
/* TODO */
|
||||
return texture2DGetNearest(tex, dx, dy);
|
||||
return texture2DGetLinear(tex, dx, dy);
|
||||
}
|
||||
|
||||
void texture2DSaveToFile(Texture2D* tex, const char* filepath)
|
||||
|
@ -188,7 +188,7 @@ Color texture3DGetLinear(Texture3D* tex, double dx, double dy, double dz)
|
|||
Color texture3DGetCubic(Texture3D* tex, double dx, double dy, double dz)
|
||||
{
|
||||
/* TODO */
|
||||
return texture3DGetNearest(tex, dx, dy, dz);
|
||||
return texture3DGetLinear(tex, dx, dy, dz);
|
||||
}
|
||||
|
||||
static Color _callbackTex3dSave(Texture3D* tex, int x, int y)
|
||||
|
|
Loading…
Reference in a new issue