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:
parent
a02214a72a
commit
7fe0f04128
5 changed files with 97 additions and 63 deletions
1
TODO
1
TODO
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue