paysages : Lighting refactoring (WIP).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@503 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2013-01-20 21:17:03 +00:00 committed by ThunderK
parent 5ee717b68a
commit a191849cee
9 changed files with 82 additions and 147 deletions

View file

@ -27,7 +27,7 @@ public:
protected:
Color getColor(double x, double y)
{
return atmosphereGetPreview(_renderer, x, -y, M_PI_2);
return atmosphereGetPreview(_renderer, x, -y, -M_PI_2);
}
void updateData()
{
@ -51,7 +51,7 @@ public:
protected:
Color getColor(double x, double y)
{
return atmosphereGetPreview(_renderer, x, -y, -M_PI_2);
return atmosphereGetPreview(_renderer, x, -y, M_PI_2);
}
void updateData()
{

View file

@ -10,7 +10,7 @@ Color basicApplyAerialPerspective(Renderer* renderer, Vector3 location, Color ba
double distance = v3Norm(direction);
AtmosphereDefinition* definition = renderer->atmosphere->definition;
double near = 10.0 - definition->humidity * 10.0;
double far = 200.0 - definition->humidity * 180.0;
double far = 500.0 - definition->humidity * 480.0;
double max = 0.75 + definition->humidity * 0.22;
assert(near < far);

View file

@ -309,20 +309,20 @@ static void _getMuMuSNu(double x, double y, double r, Color dhdH, double* mu, do
if (y < (double)(RES_MU) / 2.0)
{
d = 1.0 - y / ((double)(RES_MU) / 2.0);
d = 1.0 - y / ((double)(RES_MU) / 2.0 - 1.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
{
d = (y - (double)(RES_MU) / 2.0) / ((double)(RES_MU) / 2.0);
d = (y - (double)(RES_MU) / 2.0) / ((double)(RES_MU) / 2.0 - 1.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));
*muS = fmod(x, (double)(RES_MU_S)) / ((double)(RES_MU_S) - 1.0);
*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)) * 2.0;
*nu = -1.0 + floor(x / (double)(RES_MU_S)) / ((double)(RES_NU) - 1.0) * 2.0;
}
static void _getIrradianceUV(double r, double muS, double* uMuS, double* uR)
@ -504,11 +504,8 @@ static int _inscatter1Worker(ParallelWork* work, int layer, void* data)
int x, y;
for (x = 0; x < RES_MU_S * RES_NU; x++)
{
/*double dx = (double)x / (double)(RES_MU_S * RES_NU);*/
for (y = 0; y < RES_MU; y++)
{
/*double dy = (double)y / (double)(RES_MU);*/
Color ray = COLOR_BLACK;
Color mie = COLOR_BLACK;
double mu, muS, nu;
@ -799,7 +796,7 @@ static int _copyInscatterNWorker(ParallelWork* work, int layer, void* data)
{
double mu, muS, nu;
_getMuMuSNu((double)x, (double)y, r, dhdH, &mu, &muS, &nu);
Color col1 = texture3DGetLinear(params->source, x / (double)(RES_MU_S * RES_NU), y / (double)(RES_MU), layer + 0.5 / (double)(RES_R));
Color col1 = texture3DGetPixel(params->source, x, y, layer);
Color col2 = texture3DGetPixel(params->destination, x, y, layer);
col2.r += col1.r / _phaseFunctionR(nu);
col2.g += col1.g / _phaseFunctionR(nu);
@ -913,51 +910,6 @@ static Color _getInscatterColor(Vector3* _x, double* _t, Vector3 v, Vector3 s, d
return result;
}
/*ground radiance at end of ray x+tv, when sun in direction s
*attenuated bewteen ground and viewer (=R[L0]+R[L*]) */
static Color _groundColor(Color base, Vector3 x, double t, Vector3 v, Vector3 s, double r, double mu, Vector3 attenuation)
{
Color result;
#if 0
/* ground reflectance at end of ray, x0 */
Vector3 x0 = v3Add(x, v3Scale(v, t));
float r0 = v3Norm(x0);
Vector3 n = v3Scale(x0, 1.0 / r0);
/* direct sun light (radiance) reaching x0 */
float muS = v3Dot(n, s);
Color sunLight = _transmittanceWithShadow(r0, muS);
/* precomputed sky light (irradiance) (=E[L*]) at x0 */
Color groundSkyLight = _irradiance(_irradianceTexture, r0, muS);
/* light reflected at x0 (=(R[L0]+R[L*])/T(x,x0)) */
Color groundColor;
groundColor.r = base.r * 0.2 * (max(muS, 0.0) * sunLight.r + groundSkyLight.r) * ISun / M_PI;
groundColor.g = base.g * 0.2 * (max(muS, 0.0) * sunLight.g + groundSkyLight.g) * ISun / M_PI;
groundColor.b = base.b * 0.2 * (max(muS, 0.0) * sunLight.b + groundSkyLight.b) * ISun / M_PI;
/* water specular color due to sunLight */
/*if (reflectance.w > 0.0)
{
vec3 h = normalize(s - v);
float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0);
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0);
groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun;
}*/
#else
Color groundColor = base;
#endif
result.r = attenuation.x * groundColor.r; //=R[L0]+R[L*]
result.g = attenuation.y * groundColor.g;
result.b = attenuation.z * groundColor.b;
result.a = 1.0;
return result;
}
/* direct sun light for ray x+tv, when sun in direction s (=L0) */
static Color _sunColor(Vector3 v, Vector3 s, double r, double mu)
{
@ -1204,11 +1156,11 @@ Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3
Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
Color sunColor = _sunColor(v, s, r, mu); /* L0 */
inscatterColor.r += sunColor.r;
inscatterColor.g += sunColor.g;
inscatterColor.b += sunColor.b;
sunColor.r = sunColor.r * attenuation.x + inscatterColor.r;
sunColor.g = sunColor.g * attenuation.y + inscatterColor.g;
sunColor.b = sunColor.b * attenuation.z + inscatterColor.b;
return inscatterColor; /* Eq (16) */
return sunColor; /* Eq (16) */
}
Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
@ -1232,13 +1184,12 @@ Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color
Vector3 attenuation;
Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
Color groundColor = _groundColor(base, x, t, v, s, r, mu, attenuation); /*R[L0]+R[L*]*/
groundColor.r += inscatterColor.r;
groundColor.g += inscatterColor.g;
groundColor.b += inscatterColor.b;
base.r = base.r * attenuation.x + inscatterColor.r;
base.g = base.g * attenuation.y + inscatterColor.g;
base.b = base.b * attenuation.z + inscatterColor.b;
return groundColor; /* Eq (16) */
return base; /* Eq (16) */
}
void brunetonGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque)
@ -1254,19 +1205,19 @@ void brunetonGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3
muS = v3Dot(up, s);
sun.color = _transmittanceWithShadow(r0, muS);
sun.color.r *= 100.0;
/*sun.color.r *= 100.0;
sun.color.g *= 100.0;
sun.color.b *= 100.0;
sun.direction = s;
sun.color.b *= 100.0;*/
sun.direction = v3Scale(s, -1.0);
sun.reflection = 1.0;
sun.altered = 1;
lightingPushLight(status, &sun);
irradiance.color = _irradiance(_irradianceTexture, r0, muS);
irradiance.color.r *= 100.0;
/*irradiance.color.r *= 100.0;
irradiance.color.g *= 100.0;
irradiance.color.b *= 100.0;
irradiance.color.b *= 100.0;*/
irradiance.direction = v3Scale(normal, -1.0);
irradiance.reflection = 0.0;
irradiance.altered = 0;

View file

@ -9,13 +9,6 @@
#define MAX_SKYDOME_LIGHTS 100
typedef struct
{
Mutex* lock;
int nblights;
LightDefinition lights[MAX_SKYDOME_LIGHTS];
} AtmosphereRendererCache;
static int _inited = 0;
/******************** Definition ********************/
@ -159,7 +152,7 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction)
sky_color = COLOR_BLUE;
}
/* Get sun halo */
/* Get sun shape */
if (dist < definition->sun_radius)
{
sun_color = definition->sun_color;
@ -225,7 +218,6 @@ static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vect
static AtmosphereRenderer* _createRenderer()
{
AtmosphereRenderer* result;
AtmosphereRendererCache* cache;
result = malloc(sizeof(AtmosphereRenderer));
result->definition = AtmosphereDefinitionClass.create();
@ -235,28 +227,17 @@ static AtmosphereRenderer* _createRenderer()
result->applyAerialPerspective = _fakeApplyAerialPerspective;
result->getSkyColor = _fakeGetSkyColor;
cache = malloc(sizeof(AtmosphereRendererCache));
cache->lock = mutexCreate();
cache->nblights = -1;
result->_internal_data = cache;
return result;
}
static void _deleteRenderer(AtmosphereRenderer* renderer)
{
AtmosphereRendererCache* cache = (AtmosphereRendererCache*)renderer->_internal_data;
mutexDestroy(cache->lock);
free(cache);
AtmosphereDefinitionClass.destroy(renderer->definition);
free(renderer);
}
static void _bindRenderer(Renderer* renderer, AtmosphereDefinition* definition)
{
AtmosphereRendererCache* cache = (AtmosphereRendererCache*)renderer->atmosphere->_internal_data;
AtmosphereDefinitionClass.copy(definition, renderer->atmosphere->definition);
renderer->atmosphere->getSkyColor = _getSkyColor;
@ -265,17 +246,12 @@ static void _bindRenderer(Renderer* renderer, AtmosphereDefinition* definition)
{
case ATMOSPHERE_MODEL_BRUNETON:
renderer->atmosphere->applyAerialPerspective = brunetonApplyAerialPerspective;
/*renderer->atmosphere->getLightingStatus = brunetonGetLightingStatus;*/
renderer->atmosphere->getLightingStatus = basicGetLightingStatus;
renderer->atmosphere->getLightingStatus = brunetonGetLightingStatus;
break;
default:
renderer->atmosphere->applyAerialPerspective = basicApplyAerialPerspective;
renderer->atmosphere->getLightingStatus = basicGetLightingStatus;
}
mutexAcquire(cache->lock);
cache->nblights = -1;
mutexRelease(cache->lock);
}
StandardRenderer AtmosphereRendererClass = {

View file

@ -15,35 +15,33 @@ static inline double _angleBetween(double thetav, double phiv, double theta, dou
static inline Color _xyYToRGB(double x, double y, double Y)
{
double fX, fY, fZ;
Color result;
double fX, fY, fZ;
Color result;
fY = Y;
fX = x / y * Y;
fZ = ((1.0 - x - y) / y) * Y;
fY = Y;
fX = x / y * Y;
fZ = ((1.0 - x - y) / y) * Y;
double r, g, b;
r = 3.2404 * fX - 1.5371 * fY - 0.4985 * fZ;
g = -0.9692 * fX + 1.8759 * fY + 0.0415 * fZ;
b = 0.0556 * fX - 0.2040 * fY + 1.0573 * fZ;
double r, g, b;
r = 3.2404 * fX - 1.5371 * fY - 0.4985 * fZ;
g = -0.9692 * fX + 1.8759 * fY + 0.0415 * fZ;
b = 0.0556 * fX - 0.2040 * fY + 1.0573 * fZ;
double expo = -(1.0 / 10000.0);
r = 1.0 - exp(expo * r);
g = 1.0 - exp(expo * g);
b = 1.0 - exp(expo * b);
double expo = -(1.0 / 10000.0);
r = 1.0 - exp(expo * r);
g = 1.0 - exp(expo * g);
b = 1.0 - exp(expo * b);
if (r < 0.0) r = 0.0;
if (g < 0.0) g = 0.0;
if (b < 0.0) b = 0.0;
if (r < 0.0) r = 0.0;
if (g < 0.0) g = 0.0;
if (b < 0.0) b = 0.0;
result.r = r;
result.g = g;
result.b = b;
result.a = 1.0;
result.r = r;
result.g = g;
result.b = b;
result.a = 1.0;
colorNormalize(&result);
return result;
return result;
}
static inline void _directionToThetaPhi(Vector3 direction, double* theta, double* phi)

View file

@ -134,9 +134,9 @@ Color atmosphereGetPreview(Renderer* renderer, double x, double y, double headin
normal = m4Transform(rotation, normal);
hit = m4Transform(rotation, hit);
light = lightingCreateStatus(renderer->lighting, hit, renderer->camera_location);
light = lightingCreateStatus(renderer->lighting, hit, eye);
renderer->atmosphere->getLightingStatus(renderer, light, normal, 1);
lightingApplyStatus(light, normal, &MOUNT_MATERIAL);
color = lightingApplyStatus(light, normal, &MOUNT_MATERIAL);
lightingDeleteStatus(light);
return renderer->atmosphere->applyAerialPerspective(renderer, hit, color);

View file

@ -54,7 +54,7 @@ typedef struct
FuncAtmosphereGetSkyColor getSkyColor;
FuncAtmosphereGetSunDirection getSunDirection;
void* _internal_data;
/*void* _internal_data;*/
} AtmosphereRenderer;
extern StandardDefinition AtmosphereDefinitionClass;

View file

@ -1,6 +1,7 @@
#include "public.h"
#include <stdlib.h>
#include "../tools.h"
#include "../tools/lighting.h"
#include "../renderer.h"
#include "../textures.h"
@ -10,7 +11,6 @@
*/
static TexturesDefinition _textures;
/*static LightingDefinition _lighting;*/
static int _inited = 0;
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
@ -18,12 +18,44 @@ static Color _applyTextures(Renderer* renderer, Vector3 location, double precisi
return texturesGetColor(&_textures, renderer, location.x, location.z, precision);
}
static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque)
{
LightDefinition light;
UNUSED(renderer);
UNUSED(normal);
UNUSED(opaque);
light.color.r = 0.6;
light.color.g = 0.6;
light.color.b = 0.6;
light.direction.x = -1.0;
light.direction.y = -0.5;
light.direction.z = -1.0;
light.direction = v3Normalize(light.direction);
light.altered = 1;
light.reflection = 1.0;
lightingPushLight(status, &light);
light.color.r = 0.2;
light.color.g = 0.2;
light.color.b = 0.2;
light.direction.x = 1.0;
light.direction.y = -0.5;
light.direction.z = 1.0;
light.direction = v3Normalize(light.direction);
light.altered = 0;
light.reflection = 0.0;
lightingPushLight(status, &light);
}
Renderer* terrainCreatePreviewRenderer()
{
Renderer* result = rendererCreate();
result->render_quality = 3;
result->applyTextures = _applyTextures;
result->atmosphere->getLightingStatus = _getLightingStatus;
result->camera_location.x = 0.0;
result->camera_location.y = 50.0;
result->camera_location.z = 0.0;
@ -35,30 +67,6 @@ Renderer* terrainCreatePreviewRenderer()
_inited = 1;
/*_lighting = lightingCreateDefinition();
light.color.r = 0.6;
light.color.g = 0.6;
light.color.b = 0.6;
light.direction.x = -1.0;
light.direction.y = -0.5;
light.direction.z = -1.0;
light.direction = v3Normalize(light.direction);
light.filtered = 0;
light.masked = 1;
light.reflection = 1.0;
lightingAddLight(&_lighting, light);
light.color.r = 0.3;
light.color.g = 0.3;
light.color.b = 0.3;
light.direction.x = 0.5;
light.direction.y = 0.7071;
light.direction.z = 0.5;
light.filtered = 0;
light.masked = 0;
light.reflection = 0.0;
lightingAddLight(&_lighting, light);
lightingValidateDefinition(&_lighting);*/
_textures = texturesCreateDefinition();
texture = (TextureLayerDefinition*)layersGetLayer(_textures.layers, layersAddLayer(_textures.layers, NULL));
texture->material.base = COLOR_WHITE;

View file

@ -354,6 +354,8 @@ WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer,
light = lightingCreateStatus(renderer->lighting, location, renderer->camera_location);
renderer->atmosphere->getLightingStatus(renderer, light, normal, 0);
color = lightingApplyStatus(light, normal, &material);
lightingDeleteStatus(light);
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
color = renderer->applyClouds(renderer, color, renderer->camera_location, location);