paysages: Heavy lighting refactoring (WIP - Broken).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@231 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-01-22 22:06:11 +00:00 committed by ThunderK
parent e265be6105
commit 0685f21716
17 changed files with 187 additions and 127 deletions

View file

@ -28,7 +28,7 @@ static void _cbLoad(GtkWidget* widget, gpointer data)
{
char *filename;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
autoLoad(filename);
paysagesLoad(filename);
g_free(filename);
}
@ -52,7 +52,7 @@ static void _cbSaveAs(GtkWidget* widget, gpointer data)
{
char *filename;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
autoSave(filename);
paysagesSave(filename);
g_free(filename);
}
gtk_widget_destroy(dialog);

View file

@ -27,12 +27,10 @@ static void _revertCurrentLayer()
guiPreviewRedraw(_preview);
}
static void _applyCurrentLayer()
/*static void _applyCurrentLayer()
{
/* TODO Apply layer config */
guiUpdate();
}
}*/
static void _revertAll()
{

View file

@ -93,7 +93,6 @@ static Color _cbPreviewRender(SmallPreview* preview, double x, double y, double
environment.reflection_function = _rayCastFromWater;
environment.refraction_function = _rayCastFromWater;
environment.toggle_fog = 0;
environment.toggle_shadows = 0;
quality.force_detail = 0.0001;
return waterGetColorCustom(location, look, &definition, &quality, &environment).final;

View file

@ -83,7 +83,8 @@ protected:
environment.reflection_function = (RayCastingFunction)(&this->rayCastFromWater);
environment.refraction_function = (RayCastingFunction)(&this->rayCastFromWater);
environment.toggle_fog = 0;
environment.toggle_shadows = 0;
environment.lighting_definition = NULL;
environment.lighting_environment = NULL;
quality.force_detail = 0.0001;
quality.detail_boost = 1.0;

View file

@ -70,7 +70,7 @@ void MainWindow::fileSave()
QString filepath = QFileDialog::getSaveFileName(this);
if (!filepath.isNull())
{
autoSave((char*)filepath.toStdString().c_str());
paysagesSave((char*)filepath.toStdString().c_str());
}
}
@ -79,7 +79,7 @@ void MainWindow::fileLoad()
QString filepath = QFileDialog::getOpenFileName(this);
if (!filepath.isNull())
{
autoLoad((char*)filepath.toStdString().c_str());
paysagesLoad((char*)filepath.toStdString().c_str());
refreshAll();
}
}

View file

@ -84,6 +84,8 @@ void autoSetDaytimeFraction(double daytime)
sky.daytime = daytime;
skySetDefinition(sky);
lightingValidateDefinition(NULL);
fogSetColor(colorGradationGet(&sky.haze_color, daytime));
}

View file

@ -407,9 +407,9 @@ static Color _lightFilter(Color light, Vector3 location, Vector3 light_location,
inside_depth = 1.0;
}
result.r = data.base.r * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.r * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
result.g = data.base.g * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.g * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
result.b = data.base.b * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.b * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
result.r = data.base.r * - 0.2 * inside_depth;
result.g = data.base.g * - 0.2 * inside_depth;
result.b = data.base.b * - 0.2 * inside_depth;
return result;
}

View file

@ -9,6 +9,9 @@
#include "shared/functions.h"
#include "shared/constants.h"
#include "shared/globals.h"
#include "sky.h"
#include "water.h"
#include "terrain.h"
static LightingDefinition _definition;
static LightingQuality _quality;
@ -18,8 +21,14 @@ static LightDefinition _LIGHT_NULL;
static Color _standardFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
{
// TODO Find shadows
return light;
Color result;
result = waterLightFilter(light, location, light_location, direction_to_light, custom_data);
result = terrainLightFilter(result, location, light_location, direction_to_light, custom_data);
// TODO atmosphere filter
// TODO clouds filter
return result;
}
void lightingInit()
@ -67,6 +76,7 @@ void lightingCopyDefinition(LightingDefinition source, LightingDefinition* desti
void lightingSetDefinition(LightingDefinition definition)
{
lightingValidateDefinition(&definition);
lightingCopyDefinition(definition, &_definition);
}
@ -80,11 +90,13 @@ void lightingValidateDefinition(LightingDefinition* definition)
if (!definition)
{
lightingValidateDefinition(&_definition);
return;
}
if (definition->autosetfromsky)
{
// TODO Get lights from sky
definition->_nbautolights = skyGetLights(definition->_autolights, MAX_LIGHTS);
}
else
{
@ -144,8 +156,53 @@ LightingQuality lightingGetQuality()
return _quality;
}
static Color _applyLightCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightDefinition* definition, LightingQuality* quality, LightingEnvironment* environment)
{
Color result, light;
double diffuse, specular;
Vector3 view, reflect, direction_inv;
light = definition->color;
direction_inv = v3Scale(definition->direction, -1.0);
light = environment->filter(light, location, v3Add(location, direction_inv), direction_inv, environment->custom_data);
normal = v3Normalize(normal);
view = v3Normalize(v3Sub(location, camera_location)); // TODO Configurable
reflect = v3Sub(v3Scale(normal, 2.0 * v3Dot(direction_inv, normal)), direction_inv);
diffuse = v3Dot(direction_inv, normal);
//diffuse = pow(diffuse * 0.5 + 0.5, 2.0);
if (diffuse > 0.0)
{
if (material.shininess > 0.0)
{
specular = pow(v3Dot(reflect, view) * material.reflection, material.shininess * 10.0 + 1.0);
}
else
{
specular = 0.0;
}
}
else
{
diffuse = 0.0;
specular = 0.0;
}
result.r = material.base.r * diffuse * light.r + material.base.r * specular * light.r;
result.g = material.base.g * diffuse * light.g + material.base.g * specular * light.g;
result.b = material.base.b * diffuse * light.b + material.base.b * specular * light.b;
result.a = material.base.a;
return result;
}
Color lightingApplyCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightingDefinition* definition, LightingQuality* quality, LightingEnvironment* environment)
{
Color result;
int i;
if (!definition)
{
definition = &_definition;
@ -159,72 +216,20 @@ Color lightingApplyCustom(Vector3 location, Vector3 normal, ReceiverMaterial mat
environment = &_environment;
}
return COLOR_RED;
/* TODO Merge lights */
result = material.base;
for (i = 0; i < definition->nblights; i++)
{
result = _applyLightCustom(location, normal, material, definition->lights + i, quality, environment);
}
for (i = 0; i < definition->_nbautolights; i++)
{
result = _applyLightCustom(location, normal, material, definition->_autolights + i, quality, environment);
}
return result;
}
Color lightingApply(Vector3 location, Vector3 normal, ReceiverMaterial material)
{
return lightingApplyCustom(location, normal, material, &_definition, &_quality, &_environment);
}
/*void lightingSetSunDirection(double x, double y, double z)
{
sun_direction.x = x;
sun_direction.y = y;
sun_direction.z = z;
sun_direction = v3Normalize(sun_direction);
sun_direction_inv = v3Scale(sun_direction, -1.0);
}
void lightingSetSunAngle(double hor, double ver)
{
lightingSetSunDirection(cos(hor) * cos(ver), sin(ver), -sin(hor) * cos(ver));
}
void lightingSetSunColor(Color col)
{
sun_color = col;
sun_color_lum = colorGetValue(&col);
}
Color lightingApply(Vector3 location, Vector3 normal, double shadowing, Color base, double reflection, double shininess)
{
Color result, light;
double ambient, diffuse, specular;
Vector3 view, reflect;
light.r = sun_color.r * (1.0 - 0.4 * shadowing);
light.g = sun_color.g * (1.0 - 0.4 * shadowing);
light.b = sun_color.b * (1.0 - 0.4 * shadowing);
normal = v3Normalize(normal);
view = v3Normalize(v3Sub(location, camera_location));
reflect = v3Sub(v3Scale(normal, 2.0 * v3Dot(sun_direction_inv, normal)), sun_direction_inv);
ambient = 0.2;
diffuse = v3Dot(sun_direction_inv, normal);
diffuse = pow(diffuse * 0.5 + 0.5, 2.0) * (1.0 - shadowing) + (diffuse * 0.5 + 0.3) * shadowing;
if (diffuse > 0.0)
{
if (shininess > 0.0)
{
specular = pow(v3Dot(reflect, view) * reflection, shininess * 10.0 + 1.0);
}
else
{
specular = 0.0;
}
}
else
{
diffuse = 0.0;
specular = 0.0;
}
result.r = base.r * ambient + base.r * diffuse * light.r + base.r * specular * light.r;
result.g = base.g * ambient + base.g * diffuse * light.g + base.g * specular * light.g;
result.b = base.b * ambient + base.b * diffuse * light.b + base.b * specular * light.b;
result.a = base.a;
return result;
}*/

View file

@ -13,10 +13,6 @@ extern int render_width;
extern int render_height;
extern int render_quality;
extern double sun_color_lum;
extern Vector3 sun_direction;
extern Vector3 sun_direction_inv;
#ifdef __cplusplus
}
#endif

View file

@ -7,12 +7,13 @@
#include "shared/constants.h"
#include "clouds.h"
#include "sky.h"
#include "lighting.h"
#define SPHERE_SIZE 1000.0
SkyDefinition _definition;
SkyQuality _quality;
SkyEnvironment _environment;
static SkyDefinition _definition;
static SkyQuality _quality;
static SkyEnvironment _environment;
void skyInit()
{
@ -97,6 +98,28 @@ SkyDefinition skyGetDefinition()
return _definition;
}
int skyGetLights(LightDefinition* lights, int max_lights)
{
double sun_angle;
Vector3 sun_direction;
int nblights = 0;
sun_angle = (_definition.daytime + 0.75) * M_PI * 2.0;
sun_direction.x = cos(sun_angle);
sun_direction.y = sin(sun_angle);
sun_direction.z = 0.0;
if (max_lights > 0)
{
lights[0].color = colorGradationGet(&_definition.sun_color, _definition.daytime);
lights[0].direction = v3Scale(sun_direction, -1.0);
lights[0].maxshadow = 1.0;
nblights = 1;
}
return nblights;
}
Color skyGetColorCustom(Vector3 eye, Vector3 look, SkyDefinition* definition, SkyQuality* quality, SkyEnvironment* environment)
{
double sun_angle, dist;

View file

@ -2,6 +2,7 @@
#define _PAYSAGES_SKY_H_
#include "shared/types.h"
#include "lighting.h"
#include <stdio.h>
#ifdef __cplusplus
@ -44,6 +45,8 @@ SkyDefinition skyGetDefinition();
void skySetQuality(SkyQuality quality);
SkyQuality skyGetQuality();
int skyGetLights(LightDefinition* lights, int max_lights);
Color skyGetColorCustom(Vector3 eye, Vector3 look, SkyDefinition* definition, SkyQuality* quality, SkyEnvironment* environment);
Color skyGetColor(Vector3 eye, Vector3 look);

View file

@ -22,6 +22,8 @@ void terrainInit()
_max_height = noiseGetMaxValue(_definition.height_noise);
_environment.toggle_fog = 1;
_environment.lighting_definition = NULL;
_environment.lighting_environment = NULL;
}
void terrainSave(FILE* f)
@ -164,31 +166,29 @@ static inline Vector3 _getPoint(TerrainDefinition* definition, double x, double
return result;
}
double terrainGetShadow(Vector3 start, Vector3 direction)
Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
{
Vector3 inc_vector;
double inc_value, inc_base, inc_factor, height, diff, light, smoothing, length, water;
double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length;
direction = v3Normalize(direction);
inc_factor = (double)render_quality;
direction_to_light = v3Normalize(direction_to_light);
inc_factor = (double)render_quality; // TODO Configurable
inc_base = 1.0;
inc_value = inc_base / inc_factor;
smoothing = 0.03 * inc_factor;;
water = waterGetLightFactor(start);
light = 1.0;
light_factor = 1.0;
length = 0.0;
do
{
inc_vector = v3Scale(direction, inc_value);
inc_vector = v3Scale(direction_to_light, inc_value);
length += v3Norm(inc_vector);
start = v3Add(start, inc_vector);
height = _getHeight(&_definition, start.x, start.z, inc_value);
diff = start.y - height;
location = v3Add(location, inc_vector);
height = _getHeight(&_definition, location.x, location.z, inc_value);
diff = location.y - height;
if (diff < 0.0)
{
light += diff / smoothing;
light_factor += diff / smoothing;
}
if (diff < inc_base / inc_factor)
@ -203,24 +203,31 @@ double terrainGetShadow(Vector3 start, Vector3 direction)
{
inc_value = diff;
}
} while (light > 0.0 && length < 50.0 && start.y <= _max_height);
} while (light_factor > 0.0 && length < 50.0 && location.y <= _max_height);
light *= water;
if (light < 0.0)
if (light_factor <= 0.0)
{
return 1.0;
return COLOR_BLACK;
}
else
{
return 1.0 - light;
light.r *= light_factor;
light.g *= light_factor;
light.b *= light_factor;
return light;
}
}
static Color _getColor(TerrainDefinition* definition, TerrainEnvironment* environment, Vector3 point, double precision)
{
Color color;
TextureEnvironment texenv;
color = texturesGetColor(point);
texenv.lighting_definition = environment->lighting_definition;
texenv.lighting_environment = environment->lighting_environment;
color = texturesGetColorCustom(point, precision, NULL, &texenv);
if (environment->toggle_fog)
{
color = fogApplyToLocation(point, color);
@ -341,7 +348,8 @@ Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition
environment = &_environment;
}
return _getColor(definition, environment, _getPoint(definition, x, z, detail), detail);
Vector3 point = _getPoint(definition, x, z, detail);
return _getColor(definition, environment, point, detail);
}
Color terrainGetColor(double x, double z, double detail)

View file

@ -3,6 +3,7 @@
#include "shared/types.h"
#include "modifiers.h"
#include "lighting.h"
#include <stdio.h>
#ifdef __cplusplus
@ -27,6 +28,8 @@ typedef struct
typedef struct
{
int toggle_fog;
LightingDefinition* lighting_definition;
LightingEnvironment* lighting_environment;
} TerrainEnvironment;
void terrainInit();
@ -45,7 +48,7 @@ void terrainDelModifier(TerrainDefinition* definition, int modifier_position);
void terrainSetQuality(TerrainQuality quality);
TerrainQuality terrainGetQuality();
double terrainGetShadow(Vector3 start, Vector3 direction);
Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data);
int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color);
double terrainGetHeightCustom(double x, double z, TerrainDefinition* definition);
double terrainGetHeight(double x, double z);

View file

@ -10,6 +10,7 @@
#include "textures.h"
#include "terrain.h"
#include "lighting.h"
#define TEXTURES_MAX 50
static TextureQuality _quality;
@ -20,6 +21,9 @@ static TextureDefinition _textures[TEXTURES_MAX];
void texturesInit()
{
_textures_count = 0;
_environment.lighting_definition = NULL;
_environment.lighting_environment = NULL;
}
void texturesSave(FILE* f)
@ -179,34 +183,48 @@ static inline Vector3 _getNormal(TextureDefinition* definition, Vector3 point, d
return v3Normalize(normal);
}
Color texturesGetLayerColorCustom(Vector3 location, double shadowing, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment)
Color texturesGetLayerColorCustom(Vector3 location, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment)
{
Color result;
Vector3 normal;
double coverage;
ReceiverMaterial material;
result.a = 0.0;
result = COLOR_TRANSPARENT;
normal = _getNormal(definition, location, detail * 0.3);
coverage = zoneGetValue(definition->zone, location, normal);
if (coverage > 0.0)
{
result = lightingApply(location, normal, shadowing, definition->color, 0.1, 0.1);
material.base = definition->color;
material.reflection = 0.1;
material.shininess = 0.1;
result = lightingApplyCustom(location, normal, material, environment->lighting_definition, NULL, environment->lighting_environment);
result.a = coverage;
}
return result;
}
Color texturesGetColorCustom(Vector3 location, double shadowing, double detail, TextureQuality* quality, TextureEnvironment* environment)
Color texturesGetColorCustom(Vector3 location, double detail, TextureQuality* quality, TextureEnvironment* environment)
{
Color result, tex_color;
int i;
/*if (!quality)
{
quality = &_quality;
}
if (!environment)
{
environment = &_environment;
}*/
result = COLOR_GREEN;
for (i = 0; i < _textures_count; i++)
{
/* TODO Do not compute layers fully covered */
tex_color = texturesGetLayerColorCustom(location, shadowing, detail, _textures + i, quality, environment);
tex_color = texturesGetLayerColorCustom(location, detail, _textures + i, quality, environment);
if (tex_color.a > 0.0001)
{
colorMask(&result, &tex_color);
@ -218,10 +236,5 @@ Color texturesGetColorCustom(Vector3 location, double shadowing, double detail,
Color texturesGetColor(Vector3 location)
{
double shadowing;
/* TODO Use environment to get lights to apply */
shadowing = terrainGetShadow(location, sun_direction_inv);
return texturesGetColorCustom(location, shadowing, renderGetPrecision(location), &_quality, &_environment);
return texturesGetColorCustom(location, renderGetPrecision(location), &_quality, &_environment);
}

View file

@ -2,6 +2,7 @@
#define _PAYSAGES_TEXTURES_H_
#include "shared/types.h"
#include "lighting.h"
#include <stdio.h>
#ifdef __cplusplus
@ -22,7 +23,8 @@ typedef struct
typedef struct
{
int unused;
LightingDefinition* lighting_definition;
LightingEnvironment* lighting_environment;
} TextureEnvironment;
void texturesInit();
@ -42,8 +44,8 @@ TextureDefinition texturesGetDefinition(int layer);
void texturesSetQuality(TextureQuality quality);
TextureQuality texturesGetQuality();
Color texturesGetLayerColorCustom(Vector3 location, double shadowing, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment);
Color texturesGetColorCustom(Vector3 location, double shadowing, double detail, TextureQuality* quality, TextureEnvironment* environment);
Color texturesGetLayerColorCustom(Vector3 location, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment);
Color texturesGetColorCustom(Vector3 location, double detail, TextureQuality* quality, TextureEnvironment* environment);
Color texturesGetColor(Vector3 location);
#ifdef __cplusplus

View file

@ -45,7 +45,8 @@ void waterInit()
_environment.reflection_function = _reflectionFunction;
_environment.refraction_function = _refractionFunction;
_environment.toggle_fog = 1;
_environment.toggle_shadows = 1;
_environment.lighting_definition = NULL;
_environment.lighting_environment = NULL;
}
void waterSave(FILE* f)
@ -292,29 +293,35 @@ static void _renderQuad(double x, double z, double size)
renderPushQuad(&v1, &v2, &v3, &v4);
}
double waterGetLightFactor(Vector3 location)
Color waterLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
{
double factor;
if (location.y < _definition.height)
{
if (sun_direction_inv.y > 0.00001)
if (direction_to_light.y > 0.00001)
{
factor = (_definition.height - location.y) / (sun_direction_inv.y * 3.0);
factor = (_definition.height - location.y) / (direction_to_light.y * 5.0); // TODO Configurable
if (factor > 1.0)
{
factor = 1.0;
}
return 1.0 - 0.8 * factor;
factor = 1.0 - 0.8 * factor;
light.r *= factor;
light.g *= factor;
light.b *= factor;
return light;
}
else
{
return 0.0;
return COLOR_BLACK;
}
}
else
{
return 1.0;
return light;
}
}

View file

@ -58,7 +58,7 @@ WaterDefinition waterGetDefinition();
void waterSetQuality(WaterQuality quality);
WaterQuality waterGetQuality();
double waterGetLightFactor(Vector3 location);
Color waterLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data);
WaterResult waterGetColorCustom(Vector3 location, Vector3 look, WaterDefinition* definition, WaterQuality* quality, WaterEnvironment* environment);
Color waterGetColor(Vector3 location, Vector3 look);
void waterRender(RenderProgressCallback callback);