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: protected:
Color getColor(double x, double y) Color getColor(double x, double y)
{ {
return atmosphereGetPreview(_renderer, x, -y, M_PI_2); return atmosphereGetPreview(_renderer, x, -y, -M_PI_2);
} }
void updateData() void updateData()
{ {
@ -51,7 +51,7 @@ public:
protected: protected:
Color getColor(double x, double y) Color getColor(double x, double y)
{ {
return atmosphereGetPreview(_renderer, x, -y, -M_PI_2); return atmosphereGetPreview(_renderer, x, -y, M_PI_2);
} }
void updateData() void updateData()
{ {

View file

@ -10,7 +10,7 @@ Color basicApplyAerialPerspective(Renderer* renderer, Vector3 location, Color ba
double distance = v3Norm(direction); double distance = v3Norm(direction);
AtmosphereDefinition* definition = renderer->atmosphere->definition; AtmosphereDefinition* definition = renderer->atmosphere->definition;
double near = 10.0 - definition->humidity * 10.0; 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; double max = 0.75 + definition->humidity * 0.22;
assert(near < far); 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) 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); 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); 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); 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)); *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); *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) 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; int x, y;
for (x = 0; x < RES_MU_S * RES_NU; x++) 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++) for (y = 0; y < RES_MU; y++)
{ {
/*double dy = (double)y / (double)(RES_MU);*/
Color ray = COLOR_BLACK; Color ray = COLOR_BLACK;
Color mie = COLOR_BLACK; Color mie = COLOR_BLACK;
double mu, muS, nu; double mu, muS, nu;
@ -799,7 +796,7 @@ static int _copyInscatterNWorker(ParallelWork* work, int layer, void* data)
{ {
double mu, muS, nu; double mu, muS, nu;
_getMuMuSNu((double)x, (double)y, r, dhdH, &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); Color col2 = texture3DGetPixel(params->destination, x, y, 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);
@ -913,51 +910,6 @@ static Color _getInscatterColor(Vector3* _x, double* _t, Vector3 v, Vector3 s, d
return result; 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) */ /* direct sun light for ray x+tv, when sun in direction s (=L0) */
static Color _sunColor(Vector3 v, Vector3 s, double r, double mu) 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 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 */ Color sunColor = _sunColor(v, s, r, mu); /* L0 */
inscatterColor.r += sunColor.r; sunColor.r = sunColor.r * attenuation.x + inscatterColor.r;
inscatterColor.g += sunColor.g; sunColor.g = sunColor.g * attenuation.y + inscatterColor.g;
inscatterColor.b += sunColor.b; sunColor.b = sunColor.b * attenuation.z + inscatterColor.b;
return inscatterColor; /* Eq (16) */ return sunColor; /* Eq (16) */
} }
Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
@ -1232,13 +1184,12 @@ Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color
Vector3 attenuation; Vector3 attenuation;
Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */ 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; base.r = base.r * attenuation.x + inscatterColor.r;
groundColor.g += inscatterColor.g; base.g = base.g * attenuation.y + inscatterColor.g;
groundColor.b += inscatterColor.b; 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) 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); muS = v3Dot(up, s);
sun.color = _transmittanceWithShadow(r0, muS); sun.color = _transmittanceWithShadow(r0, muS);
sun.color.r *= 100.0; /*sun.color.r *= 100.0;
sun.color.g *= 100.0; sun.color.g *= 100.0;
sun.color.b *= 100.0; sun.color.b *= 100.0;*/
sun.direction = s; sun.direction = v3Scale(s, -1.0);
sun.reflection = 1.0; sun.reflection = 1.0;
sun.altered = 1; sun.altered = 1;
lightingPushLight(status, &sun); lightingPushLight(status, &sun);
irradiance.color = _irradiance(_irradianceTexture, r0, muS); irradiance.color = _irradiance(_irradianceTexture, r0, muS);
irradiance.color.r *= 100.0; /*irradiance.color.r *= 100.0;
irradiance.color.g *= 100.0; irradiance.color.g *= 100.0;
irradiance.color.b *= 100.0; irradiance.color.b *= 100.0;*/
irradiance.direction = v3Scale(normal, -1.0); irradiance.direction = v3Scale(normal, -1.0);
irradiance.reflection = 0.0; irradiance.reflection = 0.0;
irradiance.altered = 0; irradiance.altered = 0;

View file

@ -9,13 +9,6 @@
#define MAX_SKYDOME_LIGHTS 100 #define MAX_SKYDOME_LIGHTS 100
typedef struct
{
Mutex* lock;
int nblights;
LightDefinition lights[MAX_SKYDOME_LIGHTS];
} AtmosphereRendererCache;
static int _inited = 0; static int _inited = 0;
/******************** Definition ********************/ /******************** Definition ********************/
@ -159,7 +152,7 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction)
sky_color = COLOR_BLUE; sky_color = COLOR_BLUE;
} }
/* Get sun halo */ /* Get sun shape */
if (dist < definition->sun_radius) if (dist < definition->sun_radius)
{ {
sun_color = definition->sun_color; sun_color = definition->sun_color;
@ -225,7 +218,6 @@ static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vect
static AtmosphereRenderer* _createRenderer() static AtmosphereRenderer* _createRenderer()
{ {
AtmosphereRenderer* result; AtmosphereRenderer* result;
AtmosphereRendererCache* cache;
result = malloc(sizeof(AtmosphereRenderer)); result = malloc(sizeof(AtmosphereRenderer));
result->definition = AtmosphereDefinitionClass.create(); result->definition = AtmosphereDefinitionClass.create();
@ -235,28 +227,17 @@ static AtmosphereRenderer* _createRenderer()
result->applyAerialPerspective = _fakeApplyAerialPerspective; result->applyAerialPerspective = _fakeApplyAerialPerspective;
result->getSkyColor = _fakeGetSkyColor; result->getSkyColor = _fakeGetSkyColor;
cache = malloc(sizeof(AtmosphereRendererCache));
cache->lock = mutexCreate();
cache->nblights = -1;
result->_internal_data = cache;
return result; return result;
} }
static void _deleteRenderer(AtmosphereRenderer* renderer) static void _deleteRenderer(AtmosphereRenderer* renderer)
{ {
AtmosphereRendererCache* cache = (AtmosphereRendererCache*)renderer->_internal_data;
mutexDestroy(cache->lock);
free(cache);
AtmosphereDefinitionClass.destroy(renderer->definition); AtmosphereDefinitionClass.destroy(renderer->definition);
free(renderer); free(renderer);
} }
static void _bindRenderer(Renderer* renderer, AtmosphereDefinition* definition) static void _bindRenderer(Renderer* renderer, AtmosphereDefinition* definition)
{ {
AtmosphereRendererCache* cache = (AtmosphereRendererCache*)renderer->atmosphere->_internal_data;
AtmosphereDefinitionClass.copy(definition, renderer->atmosphere->definition); AtmosphereDefinitionClass.copy(definition, renderer->atmosphere->definition);
renderer->atmosphere->getSkyColor = _getSkyColor; renderer->atmosphere->getSkyColor = _getSkyColor;
@ -265,17 +246,12 @@ static void _bindRenderer(Renderer* renderer, AtmosphereDefinition* definition)
{ {
case ATMOSPHERE_MODEL_BRUNETON: case ATMOSPHERE_MODEL_BRUNETON:
renderer->atmosphere->applyAerialPerspective = brunetonApplyAerialPerspective; renderer->atmosphere->applyAerialPerspective = brunetonApplyAerialPerspective;
/*renderer->atmosphere->getLightingStatus = brunetonGetLightingStatus;*/ renderer->atmosphere->getLightingStatus = brunetonGetLightingStatus;
renderer->atmosphere->getLightingStatus = basicGetLightingStatus;
break; break;
default: default:
renderer->atmosphere->applyAerialPerspective = basicApplyAerialPerspective; renderer->atmosphere->applyAerialPerspective = basicApplyAerialPerspective;
renderer->atmosphere->getLightingStatus = basicGetLightingStatus; renderer->atmosphere->getLightingStatus = basicGetLightingStatus;
} }
mutexAcquire(cache->lock);
cache->nblights = -1;
mutexRelease(cache->lock);
} }
StandardRenderer AtmosphereRendererClass = { 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) static inline Color _xyYToRGB(double x, double y, double Y)
{ {
double fX, fY, fZ; double fX, fY, fZ;
Color result; Color result;
fY = Y; fY = Y;
fX = x / y * Y; fX = x / y * Y;
fZ = ((1.0 - x - y) / y) * Y; fZ = ((1.0 - x - y) / y) * Y;
double r, g, b; double r, g, b;
r = 3.2404 * fX - 1.5371 * fY - 0.4985 * fZ; r = 3.2404 * fX - 1.5371 * fY - 0.4985 * fZ;
g = -0.9692 * fX + 1.8759 * fY + 0.0415 * fZ; g = -0.9692 * fX + 1.8759 * fY + 0.0415 * fZ;
b = 0.0556 * fX - 0.2040 * fY + 1.0573 * fZ; b = 0.0556 * fX - 0.2040 * fY + 1.0573 * fZ;
double expo = -(1.0 / 10000.0); double expo = -(1.0 / 10000.0);
r = 1.0 - exp(expo * r); r = 1.0 - exp(expo * r);
g = 1.0 - exp(expo * g); g = 1.0 - exp(expo * g);
b = 1.0 - exp(expo * b); b = 1.0 - exp(expo * b);
if (r < 0.0) r = 0.0; if (r < 0.0) r = 0.0;
if (g < 0.0) g = 0.0; if (g < 0.0) g = 0.0;
if (b < 0.0) b = 0.0; if (b < 0.0) b = 0.0;
result.r = r; result.r = r;
result.g = g; result.g = g;
result.b = b; result.b = b;
result.a = 1.0; result.a = 1.0;
colorNormalize(&result); return result;
return result;
} }
static inline void _directionToThetaPhi(Vector3 direction, double* theta, double* phi) 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); normal = m4Transform(rotation, normal);
hit = m4Transform(rotation, hit); 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); renderer->atmosphere->getLightingStatus(renderer, light, normal, 1);
lightingApplyStatus(light, normal, &MOUNT_MATERIAL); color = lightingApplyStatus(light, normal, &MOUNT_MATERIAL);
lightingDeleteStatus(light); lightingDeleteStatus(light);
return renderer->atmosphere->applyAerialPerspective(renderer, hit, color); return renderer->atmosphere->applyAerialPerspective(renderer, hit, color);

View file

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

View file

@ -1,6 +1,7 @@
#include "public.h" #include "public.h"
#include <stdlib.h> #include <stdlib.h>
#include "../tools.h"
#include "../tools/lighting.h" #include "../tools/lighting.h"
#include "../renderer.h" #include "../renderer.h"
#include "../textures.h" #include "../textures.h"
@ -10,7 +11,6 @@
*/ */
static TexturesDefinition _textures; static TexturesDefinition _textures;
/*static LightingDefinition _lighting;*/
static int _inited = 0; static int _inited = 0;
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) 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); 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* terrainCreatePreviewRenderer()
{ {
Renderer* result = rendererCreate(); Renderer* result = rendererCreate();
result->render_quality = 3; result->render_quality = 3;
result->applyTextures = _applyTextures; result->applyTextures = _applyTextures;
result->atmosphere->getLightingStatus = _getLightingStatus;
result->camera_location.x = 0.0; result->camera_location.x = 0.0;
result->camera_location.y = 50.0; result->camera_location.y = 50.0;
result->camera_location.z = 0.0; result->camera_location.z = 0.0;
@ -35,30 +67,6 @@ Renderer* terrainCreatePreviewRenderer()
_inited = 1; _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(); _textures = texturesCreateDefinition();
texture = (TextureLayerDefinition*)layersGetLayer(_textures.layers, layersAddLayer(_textures.layers, NULL)); texture = (TextureLayerDefinition*)layersGetLayer(_textures.layers, layersAddLayer(_textures.layers, NULL));
texture->material.base = COLOR_WHITE; 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); light = lightingCreateStatus(renderer->lighting, location, renderer->camera_location);
renderer->atmosphere->getLightingStatus(renderer, light, normal, 0); renderer->atmosphere->getLightingStatus(renderer, light, normal, 0);
color = lightingApplyStatus(light, normal, &material); color = lightingApplyStatus(light, normal, &material);
lightingDeleteStatus(light);
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color); color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
color = renderer->applyClouds(renderer, color, renderer->camera_location, location); color = renderer->applyClouds(renderer, color, renderer->camera_location, location);