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:
parent
5ee717b68a
commit
a191849cee
9 changed files with 82 additions and 147 deletions
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -54,7 +54,7 @@ typedef struct
|
|||
FuncAtmosphereGetSkyColor getSkyColor;
|
||||
FuncAtmosphereGetSunDirection getSunDirection;
|
||||
|
||||
void* _internal_data;
|
||||
/*void* _internal_data;*/
|
||||
} AtmosphereRenderer;
|
||||
|
||||
extern StandardDefinition AtmosphereDefinitionClass;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue