paysages : Fixed water depth color + fixed blue haze at night.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@536 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2013-03-09 11:06:39 +00:00 committed by ThunderK
parent a02214a72a
commit 7fe0f04128
5 changed files with 97 additions and 63 deletions

1
TODO
View file

@ -7,7 +7,6 @@ Technology Preview 2 :
- Get rid of noise dialogs, for simpler settings. - Get rid of noise dialogs, for simpler settings.
- Finalize Bruneton's model - Finalize Bruneton's model
=> Fix artifacts on aerial perspective (mostly when sun is near horizon) => Fix artifacts on aerial perspective (mostly when sun is near horizon)
=> Fix blue appearance at night
- Finalize lighting refactoring - Finalize lighting refactoring
=> Restore cloud lighting => Restore cloud lighting
- Hide Preetham's model. - Hide Preetham's model.

View file

@ -162,7 +162,7 @@ static Color _texture4D(Texture4D* tex, double r, double mu, double muS, double
double uMu = cst.a + (rmu * cst.r + sqrt(delta + cst.g)) / (rho + cst.b) * (0.5 - 1.0 / (double)(RES_MU)); double uMu = cst.a + (rmu * cst.r + sqrt(delta + cst.g)) / (rho + cst.b) * (0.5 - 1.0 / (double)(RES_MU));
double uMuS = 0.5 / (double)(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / (double)(RES_MU_S)); double uMuS = 0.5 / (double)(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / (double)(RES_MU_S));
return texture4DGetLinear(tex, uR, uMu, uMuS, nu); return texture4DGetLinear(tex, uMu, uMuS, nu, uR);
} }
/*********************** Physics functions ***********************/ /*********************** Physics functions ***********************/
@ -295,30 +295,29 @@ static Color _transmittanceWithShadow(double r, double mu)
return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? COLOR_BLACK : _transmittance(r, mu); return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? COLOR_BLACK : _transmittance(r, mu);
} }
static void _texCoordToMuMuSNu(double x, double y, double z, double w, Color dhdH, double* mu, double* muS, double* nu) static void _texCoordToMuMuSNu(double x, double y, double z, double r, Color dhdH, double* mu, double* muS, double* nu)
{ {
/*double d; double d;
if (y < (double)(RES_MU) / 2.0) x /= (double)RES_MU;
y /= (double)RES_MU_S;
z /= (double)RES_NU;
if (x < 0.5)
{ {
d = 1.0 - y / ((double)(RES_MU) / 2.0 - 1.0); d = 1.0 - x / 0.5;
d = min(max(dhdH.b, d * dhdH.a), dhdH.a * 0.999); d = min(max(dhdH.b, d * dhdH.a), dhdH.a * 0.999);
*mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d); *mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
*mu = min(*mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001); *mu = min(*mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
} }
else else
{ {
d = (y - (double)(RES_MU) / 2.0) / ((double)(RES_MU) / 2.0 - 1.0); d = (x - 0.5) / 0.5;
d = min(max(dhdH.r, d * dhdH.g), dhdH.g * 0.999); d = min(max(dhdH.r, d * dhdH.g), dhdH.g * 0.999);
*mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d); *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 = tan((2.0 * y - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
*muS = tan((2.0 * (*muS) - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); *nu = -1.0 + z / 2.0;
*nu = -1.0 + floor(x / (double)(RES_MU_S)) / ((double)(RES_NU) - 1.0) * 2.0;*/
*mu = -1.0 + 2.0 * x / (float(RES_MU) - 1.0);
*muS = -0.2 + y * 1.2;
*nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
} }
static void _getIrradianceUV(double r, double muS, double* uMuS, double* uR) static void _getIrradianceUV(double r, double muS, double* uMuS, double* uR)
@ -497,20 +496,23 @@ static int _inscatter1Worker(ParallelWork* work, int layer, void* data)
Color dhdH; Color dhdH;
_getLayerParams(layer, &r, &dhdH); _getLayerParams(layer, &r, &dhdH);
int x, y; int x, y, z;
for (x = 0; x < RES_MU_S * RES_NU; x++) for (x = 0; x < RES_MU; x++)
{ {
for (y = 0; y < RES_MU; y++) for (y = 0; y < RES_MU_S; y++)
{
for (z = 0; z < RES_NU; z++)
{ {
Color ray = COLOR_BLACK; Color ray = COLOR_BLACK;
Color mie = COLOR_BLACK; Color mie = COLOR_BLACK;
double mu, muS, nu; double mu, muS, nu;
_texCoordToMuMuSNu((double)x, (double)y, r, dhdH, &mu, &muS, &nu); _texCoordToMuMuSNu((double)x, (double)y, (double)z, r, dhdH, &mu, &muS, &nu);
_inscatter1(r, mu, muS, nu, &ray, &mie); _inscatter1(r, mu, muS, nu, &ray, &mie);
/* store separately Rayleigh and Mie contributions, WITHOUT the phase function factor /* store separately Rayleigh and Mie contributions, WITHOUT the phase function factor
* (cf "Angular precision") */ * (cf "Angular precision") */
texture3DSetPixel(params->ray, x, y, layer, ray); texture4DSetPixel(params->ray, x, y, z, layer, ray);
texture3DSetPixel(params->mie, x, y, layer, mie); texture4DSetPixel(params->mie, x, y, z, layer, mie);
}
} }
} }
return 1; return 1;
@ -634,16 +636,19 @@ static int _jWorker(ParallelWork* work, int layer, void* data)
Color dhdH; Color dhdH;
_getLayerParams(layer, &r, &dhdH); _getLayerParams(layer, &r, &dhdH);
int x, y; int x, y, z;
for (x = 0; x < RES_MU_S * RES_NU; x++) for (x = 0; x < RES_MU; x++)
{ {
for (y = 0; y < RES_MU; y++) for (y = 0; y < RES_MU_S; y++)
{
for (z = 0; z < RES_NU; z++)
{ {
Color raymie; Color raymie;
double mu, muS, nu; double mu, muS, nu;
_texCoordToMuMuSNu((double)x, (double)y, r, dhdH, &mu, &muS, &nu); _texCoordToMuMuSNu((double)x, (double)y, (double)z, r, dhdH, &mu, &muS, &nu);
raymie = _inscatterS(r, mu, muS, nu, params->first, params->deltaE, params->deltaSR, params->deltaSM); raymie = _inscatterS(r, mu, muS, nu, params->first, params->deltaE, params->deltaSR, params->deltaSM);
texture3DSetPixel(params->result, x, y, layer, raymie); texture4DSetPixel(params->result, x, y, z, layer, raymie);
}
} }
} }
return 1; return 1;
@ -755,14 +760,17 @@ static int _inscatterNWorker(ParallelWork* work, int layer, void* data)
Color dhdH; Color dhdH;
_getLayerParams(layer, &r, &dhdH); _getLayerParams(layer, &r, &dhdH);
int x, y; int x, y, z;
for (x = 0; x < RES_MU_S * RES_NU; x++) for (x = 0; x < RES_MU; x++)
{ {
for (y = 0; y < RES_MU; y++) for (y = 0; y < RES_MU_S; y++)
{
for (z = 0; z < RES_NU; z++)
{ {
double mu, muS, nu; double mu, muS, nu;
_texCoordToMuMuSNu((double)x, (double)y, r, dhdH, &mu, &muS, &nu); _texCoordToMuMuSNu((double)x, (double)y, (double)z, r, dhdH, &mu, &muS, &nu);
texture3DSetPixel(params->destination, x, y, layer, _inscatterN(params->deltaJ, r, mu, muS, nu)); texture4DSetPixel(params->destination, x, y, z, layer, _inscatterN(params->deltaJ, r, mu, muS, nu));
}
} }
} }
return 1; return 1;
@ -785,19 +793,22 @@ static int _copyInscatterNWorker(ParallelWork* work, int layer, void* data)
Color dhdH; Color dhdH;
_getLayerParams(layer, &r, &dhdH); _getLayerParams(layer, &r, &dhdH);
int x, y; int x, y, z;
for (x = 0; x < RES_MU_S * RES_NU; x++) for (x = 0; x < RES_MU; x++)
{ {
for (y = 0; y < RES_MU; y++) for (y = 0; y < RES_MU_S; y++)
{
for (z = 0; z < RES_NU; z++)
{ {
double mu, muS, nu; double mu, muS, nu;
_texCoordToMuMuSNu((double)x, (double)y, r, dhdH, &mu, &muS, &nu); _texCoordToMuMuSNu((double)x, (double)y, (double)z, r, dhdH, &mu, &muS, &nu);
Color col1 = texture3DGetPixel(params->source, x, y, layer); Color col1 = texture4DGetPixel(params->source, x, y, z, layer);
Color col2 = texture3DGetPixel(params->destination, x, y, layer); Color col2 = texture4DGetPixel(params->destination, x, y, z, layer);
col2.r += col1.r / _phaseFunctionR(nu); col2.r += col1.r / _phaseFunctionR(nu);
col2.g += col1.g / _phaseFunctionR(nu); col2.g += col1.g / _phaseFunctionR(nu);
col2.b += col1.b / _phaseFunctionR(nu); col2.b += col1.b / _phaseFunctionR(nu);
texture3DSetPixel(params->destination, x, y, layer, col2); texture4DSetPixel(params->destination, x, y, z, layer, col2);
}
} }
} }
return 1; return 1;
@ -1042,7 +1053,7 @@ void brunetonInit()
/* TODO Deletes */ /* TODO Deletes */
_transmittanceTexture = texture2DCreate(TRANSMITTANCE_W, TRANSMITTANCE_H); _transmittanceTexture = texture2DCreate(TRANSMITTANCE_W, TRANSMITTANCE_H);
_irradianceTexture = texture2DCreate(SKY_W, SKY_H); _irradianceTexture = texture2DCreate(SKY_W, SKY_H);
_inscatterTexture = texture4DCreate(RES_R, RES_MU, RES_MU_S, RES_NU); _inscatterTexture = texture4DCreate(RES_MU, RES_MU_S, RES_NU, RES_R);
/* try loading from cache */ /* try loading from cache */
if (_tryLoadCache2D(_transmittanceTexture, "transmittance", 0) if (_tryLoadCache2D(_transmittanceTexture, "transmittance", 0)
@ -1053,9 +1064,9 @@ void brunetonInit()
} }
Texture2D* _deltaETexture = texture2DCreate(SKY_W, SKY_H); Texture2D* _deltaETexture = texture2DCreate(SKY_W, SKY_H);
Texture4D* _deltaSMTexture = texture4DCreate(RES_R, RES_MU, RES_MU_S, RES_NU); Texture4D* _deltaSMTexture = texture4DCreate(RES_MU, RES_MU_S, RES_NU, RES_R);
Texture4D* _deltaSRTexture = texture4DCreate(RES_R, RES_MU, RES_MU_S, RES_NU); Texture4D* _deltaSRTexture = texture4DCreate(RES_MU, RES_MU_S, RES_NU, RES_R);
Texture4D* _deltaJTexture = texture4DCreate(RES_R, RES_MU, RES_MU_S, RES_NU); Texture4D* _deltaJTexture = texture4DCreate(RES_MU, RES_MU_S, RES_NU, RES_R);
/* computes transmittance texture T (line 1 in algorithm 4.1) */ /* computes transmittance texture T (line 1 in algorithm 4.1) */
_precomputeTransmittanceTexture(); _precomputeTransmittanceTexture();
@ -1079,13 +1090,13 @@ void brunetonInit()
texture2DFill(_irradianceTexture, COLOR_BLACK); texture2DFill(_irradianceTexture, COLOR_BLACK);
/* copies deltaS into inscatter texture S (line 5 in algorithm 4.1) */ /* copies deltaS into inscatter texture S (line 5 in algorithm 4.1) */
for (x = 0; x < RES_R; x++) for (x = 0; x < RES_MU; x++)
{ {
for (y = 0; y < RES_MU; y++) for (y = 0; y < RES_MU_S; y++)
{ {
for (z = 0; z < RES_MU_S; z++) for (z = 0; z < RES_NU; z++)
{ {
for (w = 0; w < RES_NU; w++) for (w = 0; w < RES_R; w++)
{ {
Color result = texture4DGetPixel(_deltaSRTexture, x, y, z, w); Color result = texture4DGetPixel(_deltaSRTexture, x, y, z, w);
Color mie = texture4DGetPixel(_deltaSMTexture, x, y, z, w); Color mie = texture4DGetPixel(_deltaSMTexture, x, y, z, w);

View file

@ -179,6 +179,25 @@ double colorGetValue(Color* col)
return max; return max;
} }
double colorGetPower(Color* col)
{
return col->r + col->g + col->b;
}
void colorLimitPower(Color* col, double max_power)
{
double power = colorGetPower(col);
if (power > max_power)
{
double factor = max_power / power;
col->r *= factor;
col->g *= factor;
col->b *= factor;
}
}
/******************************** ColorProfile ********************************/ /******************************** ColorProfile ********************************/
struct ColorProfile struct ColorProfile
{ {

View file

@ -42,6 +42,9 @@ void colorMask(Color* base, Color* mask);
double colorNormalize(Color* col); double colorNormalize(Color* col);
double colorGetValue(Color* col); double colorGetValue(Color* col);
double colorGetPower(Color* col);
void colorLimitPower(Color* col, double max_power);
/* HDR profile for tone-mapping */ /* HDR profile for tone-mapping */
typedef struct ColorProfile ColorProfile; typedef struct ColorProfile ColorProfile;
typedef enum typedef enum

View file

@ -253,18 +253,20 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z)
} }
else else
{ {
Color depth_color = definition->depth_color;
refracted = renderer->rayWalking(renderer, location, _refractRay(look_direction, normal), 1, 0, 1, 1); refracted = renderer->rayWalking(renderer, location, _refractRay(look_direction, normal), 1, 0, 1, 1);
depth = v3Norm(v3Sub(location, refracted.hit_location)); depth = v3Norm(v3Sub(location, refracted.hit_location));
colorLimitPower(&depth_color, colorGetPower(&refracted.hit_color));
if (depth > definition->transparency_depth) if (depth > definition->transparency_depth)
{ {
result.refracted = definition->depth_color; result.refracted = depth_color;
} }
else else
{ {
depth /= definition->transparency_depth; depth /= definition->transparency_depth;
result.refracted.r = refracted.hit_color.r * (1.0 - depth) + definition->depth_color.r * depth; result.refracted.r = refracted.hit_color.r * (1.0 - depth) + depth_color.r * depth;
result.refracted.g = refracted.hit_color.g * (1.0 - depth) + definition->depth_color.g * depth; result.refracted.g = refracted.hit_color.g * (1.0 - depth) + depth_color.g * depth;
result.refracted.b = refracted.hit_color.b * (1.0 - depth) + definition->depth_color.b * depth; result.refracted.b = refracted.hit_color.b * (1.0 - depth) + depth_color.b * depth;
result.refracted.a = 1.0; result.refracted.a = 1.0;
} }
} }