paysages : Progress on bruneton atmospheric model (WIP).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@484 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
14fcc1883e
commit
6cd5975316
3 changed files with 114 additions and 24 deletions
|
@ -82,7 +82,7 @@ static const float mieG = 0.65;*/
|
|||
|
||||
/*********************** Shader helpers ***********************/
|
||||
|
||||
#define step(_a_,_b_) ((_a_) < (_b_) ? 0 : 1)
|
||||
#define step(_a_,_b_) ((_b_) < (_a_) ? 0.0 : 1.0)
|
||||
#define sign(_a_) ((_a_) < 0.0 ? -1.0 : ((_a_) > 0.0 ? 1.0 : 0.0))
|
||||
#define mix(_x_,_y_,_a_) ((_x_) * (1.0 - (_a_)) + (_y_) * (_a_))
|
||||
static inline double min(double a, double b)
|
||||
|
@ -158,7 +158,7 @@ static inline Color _texture3D(Texture3D* tex, Vector3 p)
|
|||
|
||||
static Color _texture4D(Texture3D* tex3d, double r, double mu, double muS, double nu)
|
||||
{
|
||||
if (r < Rg + 0.001) r = Rg + 0.001;
|
||||
if (r < Rg + 0.00000001) r = Rg + 0.00000001;
|
||||
double H = sqrt(Rt * Rt - Rg * Rg);
|
||||
double rho = sqrt(r * r - Rg * Rg);
|
||||
double rmu = r * mu;
|
||||
|
@ -170,7 +170,7 @@ static Color _texture4D(Texture3D* tex3d, double r, double mu, double muS, doubl
|
|||
double lerp = (nu + 1.0) / 2.0 * ((double)(RES_NU) - 1.0);
|
||||
double uNu = floor(lerp);
|
||||
lerp = lerp - uNu;
|
||||
return vec4mix(_texture3D(tex3d, vec3((uNu + uMuS + 1.0) / (double)(RES_NU), uMu, uR)), _texture3D(tex3d, vec3((uNu + uMuS) / (double)(RES_NU), uMu, uR)), lerp);
|
||||
return vec4mix(_texture3D(tex3d, vec3((uNu + uMuS) / (double)(RES_NU), uMu, uR)), _texture3D(tex3d, vec3((uNu + uMuS + 1.0) / (double)(RES_NU), uMu, uR)), lerp);
|
||||
}
|
||||
|
||||
/*********************** Physics functions ***********************/
|
||||
|
@ -220,7 +220,7 @@ static double _opticalDepth(double H, double r, double mu, double d)
|
|||
|
||||
static inline void _getTransmittanceUV(double r, double mu, double* u, double* v)
|
||||
{
|
||||
if (r < Rg + 0.001) r = Rg + 0.001;
|
||||
if (r < Rg + 0.00000001) r = Rg + 0.00000001;
|
||||
double dr = (r - Rg) / (Rt - Rg);
|
||||
*v = sqrt(dr);
|
||||
*u = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
|
||||
|
@ -318,15 +318,6 @@ static Vector3 _analyticTransmittance(double r, double mu, double d)
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline Color _applyInscatter(Color inscatter, Color attmod, Color samp)
|
||||
{
|
||||
inscatter.r = inscatter.r - attmod.r * samp.r;
|
||||
inscatter.g = inscatter.g - attmod.g * samp.g;
|
||||
inscatter.b = inscatter.b - attmod.b * samp.b;
|
||||
inscatter.a = inscatter.a - attmod.a * samp.a;
|
||||
return vec4max(inscatter, 0.0);
|
||||
}
|
||||
|
||||
/* transmittance(=transparency) of atmosphere for infinite ray (r,mu)
|
||||
(mu=cos(view zenith angle)), or zero if ray intersects ground */
|
||||
static Color _transmittanceWithShadow(double r, double mu)
|
||||
|
@ -829,6 +820,15 @@ static int _copyInscatterNWorker(ParallelWork* work, int layer, void* data)
|
|||
|
||||
/*********************** Final getters ***********************/
|
||||
|
||||
static inline Color _applyInscatter(Color inscatter, Color attmod, Color samp)
|
||||
{
|
||||
inscatter.r = inscatter.r - attmod.r * samp.r;
|
||||
inscatter.g = inscatter.g - attmod.g * samp.g;
|
||||
inscatter.b = inscatter.b - attmod.b * samp.b;
|
||||
inscatter.a = inscatter.a - attmod.a * samp.a;
|
||||
return vec4max(inscatter, 0.0);
|
||||
}
|
||||
|
||||
/* inscattered light along ray x+tv, when sun in direction s (=S[L]-T(x,x0)S[L]|x0) */
|
||||
static Color _getInscatterColor(Vector3* _x, double* _t, Vector3 v, Vector3 s, double* _r, double* _mu, Vector3* attenuation)
|
||||
{
|
||||
|
@ -903,7 +903,7 @@ static Color _getInscatterColor(Vector3* _x, double* _t, Vector3 v, Vector3 s, d
|
|||
result.r = inscatter.r * phaseR + mie.r * phaseM;
|
||||
result.g = inscatter.g * phaseR + mie.g * phaseM;
|
||||
result.b = inscatter.b * phaseR + mie.b * phaseM;
|
||||
result.a = inscatter.a * phaseR + mie.a * phaseM;
|
||||
result.a = 1.0;
|
||||
_fixVec4Min(&result, 0.0);
|
||||
}
|
||||
else
|
||||
|
@ -918,7 +918,6 @@ static Color _getInscatterColor(Vector3* _x, double* _t, Vector3 v, Vector3 s, d
|
|||
result.g *= ISun;
|
||||
result.b *= ISun;
|
||||
result.a = 1.0;
|
||||
/*printf("%f %f %f\n", result.r, result.g, result.b);*/
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -987,7 +986,7 @@ static Color _sunColor(Vector3 x, double t, Vector3 v, Vector3 s, double r, doub
|
|||
transmittance.r *= isun;
|
||||
transmittance.g *= isun;
|
||||
transmittance.b *= isun;
|
||||
transmittance.a *= isun;
|
||||
transmittance.a = 1.0;
|
||||
return transmittance; /* Eq (9) */
|
||||
}
|
||||
}
|
||||
|
@ -1179,11 +1178,22 @@ void brunetonInit()
|
|||
}
|
||||
}
|
||||
|
||||
static inline void _fixVector(Vector3* v)
|
||||
{
|
||||
double temp = v->y;
|
||||
/*v->x = -v->x;*/
|
||||
v->y = v->z;
|
||||
v->z = temp;
|
||||
}
|
||||
|
||||
Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position)
|
||||
{
|
||||
Vector3 x = {0.0, Rg + eye.y, 0.0};
|
||||
_fixVector(&x);
|
||||
Vector3 v = v3Normalize(direction);
|
||||
_fixVector(&v);
|
||||
Vector3 s = v3Normalize(v3Sub(sun_position, eye));
|
||||
_fixVector(&s);
|
||||
|
||||
double r = v3Norm(x);
|
||||
double mu = v3Dot(x, v) / r;
|
||||
|
@ -1214,6 +1224,5 @@ Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3
|
|||
/*Color groundColor = _groundColor(x, t, v, s, r, mu, attenuation); //R[L0]+R[L*]*/
|
||||
Color groundColor = COLOR_BLACK;
|
||||
Color sunColor = _sunColor(x, t, v, s, r, mu); //L0
|
||||
return inscatterColor;
|
||||
return _hdr(sunColor, groundColor, inscatterColor); // Eq (16)
|
||||
}
|
||||
|
|
|
@ -140,14 +140,16 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction)
|
|||
{
|
||||
AtmosphereDefinition* definition;
|
||||
double dist;
|
||||
Vector3 sun_position;
|
||||
Vector3 sun_direction, sun_position;
|
||||
Color sky_color, sun_color;
|
||||
|
||||
definition = renderer->atmosphere->definition;
|
||||
|
||||
sun_position = renderer->atmosphere->getSunDirection(renderer);
|
||||
sun_direction = renderer->atmosphere->getSunDirection(renderer);
|
||||
direction = v3Normalize(direction);
|
||||
dist = v3Norm(v3Sub(direction, sun_position));
|
||||
dist = v3Norm(v3Sub(direction, sun_direction));
|
||||
|
||||
sun_position = v3Scale(sun_direction, 149597870.0);
|
||||
|
||||
/* Get base scattering*/
|
||||
switch (definition->model)
|
||||
|
|
|
@ -21,6 +21,18 @@ struct Texture3D
|
|||
|
||||
|
||||
|
||||
static inline Color _lerp(Color c1, Color c2, double d)
|
||||
{
|
||||
Color result;
|
||||
|
||||
result.r = c1.r * (1.0 - d) + c2.r * d;
|
||||
result.g = c1.g * (1.0 - d) + c2.g * d;
|
||||
result.b = c1.b * (1.0 - d) + c2.b * d;
|
||||
result.a = c1.a * (1.0 - d) + c2.a * d;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Texture2D* texture2DCreate(int xsize, int ysize)
|
||||
{
|
||||
|
@ -82,8 +94,34 @@ Color texture2DGetNearest(Texture2D* tex, double dx, double dy)
|
|||
|
||||
Color texture2DGetLinear(Texture2D* tex, double dx, double dy)
|
||||
{
|
||||
/* TODO */
|
||||
return texture2DGetNearest(tex, dx, dy);
|
||||
if (dx < 0.0) dx = 0.0;
|
||||
if (dx > 1.0) dx = 1.0;
|
||||
if (dy < 0.0) dy = 0.0;
|
||||
if (dy > 1.0) dy = 1.0;
|
||||
|
||||
dx *= (double)(tex->xsize - 1);
|
||||
dy *= (double)(tex->ysize - 1);
|
||||
|
||||
int ix = (int)floor(dx);
|
||||
if (ix == tex->xsize - 1)
|
||||
{
|
||||
ix--;
|
||||
}
|
||||
int iy = (int)floor(dy);
|
||||
if (iy == tex->ysize - 1)
|
||||
{
|
||||
iy--;
|
||||
}
|
||||
|
||||
dx -= (double)ix;
|
||||
dy -= (double)iy;
|
||||
|
||||
Color* data = tex->data + iy * tex->xsize + ix;
|
||||
|
||||
Color c1 = _lerp(*data, *(data + 1), dx);
|
||||
Color c2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
|
||||
|
||||
return _lerp(c1, c2, dy);
|
||||
}
|
||||
|
||||
Color texture2DGetCubic(Texture2D* tex, double dx, double dy)
|
||||
|
@ -208,8 +246,49 @@ Color texture3DGetNearest(Texture3D* tex, double dx, double dy, double dz)
|
|||
|
||||
Color texture3DGetLinear(Texture3D* tex, double dx, double dy, double dz)
|
||||
{
|
||||
/* TODO */
|
||||
return texture3DGetNearest(tex, dx, dy, dz);
|
||||
if (dx < 0.0) dx = 0.0;
|
||||
if (dx > 1.0) dx = 1.0;
|
||||
if (dy < 0.0) dy = 0.0;
|
||||
if (dy > 1.0) dy = 1.0;
|
||||
if (dz < 0.0) dz = 0.0;
|
||||
if (dz > 1.0) dz = 1.0;
|
||||
|
||||
dx *= (double)(tex->xsize - 1);
|
||||
dy *= (double)(tex->ysize - 1);
|
||||
dz *= (double)(tex->zsize - 1);
|
||||
|
||||
int ix = (int)floor(dx);
|
||||
if (ix == tex->xsize - 1)
|
||||
{
|
||||
ix--;
|
||||
}
|
||||
int iy = (int)floor(dy);
|
||||
if (iy == tex->ysize - 1)
|
||||
{
|
||||
iy--;
|
||||
}
|
||||
int iz = (int)floor(dz);
|
||||
if (iz == tex->zsize - 1)
|
||||
{
|
||||
iz--;
|
||||
}
|
||||
|
||||
dx -= (double)ix;
|
||||
dy -= (double)iy;
|
||||
dz -= (double)iz;
|
||||
|
||||
Color* data = tex->data + iz * tex->xsize * tex->ysize + iy * tex->xsize + ix;
|
||||
|
||||
Color cx1 = _lerp(*data, *(data + 1), dx);
|
||||
Color cx2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
|
||||
Color cy1 = _lerp(cx1, cx2, dy);
|
||||
|
||||
data += tex->xsize * tex->ysize;
|
||||
cx1 = _lerp(*(data), *(data + 1), dx);
|
||||
cx2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
|
||||
Color cy2 = _lerp(cx1, cx2, dy);
|
||||
|
||||
return _lerp(cy1, cy2, dz);
|
||||
}
|
||||
|
||||
Color texture3DGetCubic(Texture3D* tex, double dx, double dy, double dz)
|
||||
|
|
Loading…
Reference in a new issue