paysages : Preetham approximation for sky (WIP) - New indirect lighting by skydome.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@360 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-06-24 16:04:01 +00:00 committed by ThunderK
parent 394ba7d4c5
commit b6555f822c
21 changed files with 247 additions and 177 deletions

2
TODO
View file

@ -1,10 +1,10 @@
Technology Preview 2 :
- Finalize Preetham's model usage
=> Update all fields when "auto from daytime" is selected
=> Apply the skydome lighting by directly sampling it (no more amplitude in lights)
=> Apply model to atmosphere (aerial perspective)
=> Find a proper model for night sky (maybe Shirley)
- InputInt doesn't honor small_step.
- Keep skydome lights in cache for a render.
- Disable form fields when no layer is selected.
- Add buttons to restore "auto" default values in tabs and dialogs.
- Remove color gradations (replace with automatic boolean and simple colors).

View file

@ -68,7 +68,6 @@ public:
_lighting = lightingCreateDefinition();
light.color = COLOR_WHITE;
light.amplitude = 0.0;
light.direction.x = -1.0;
light.direction.y = -1.0;
light.direction.z = 1.0;

View file

@ -19,6 +19,7 @@ public:
_renderer.getTerrainHeight = _getTerrainHeight;
_renderer.alterLight = _alterLight;
_renderer.getLightStatus = _getLightStatus;
_renderer.getSkyDomeLights = _getSkyDomeLights;
_renderer.camera_location.x = 0.0;
_renderer.camera_location.y = 50.0;
_renderer.camera_location.z = 0.0;
@ -27,11 +28,13 @@ public:
_textures = texturesCreateDefinition();
_lighting = lightingCreateDefinition();
_water = waterCreateDefinition();
_sky = skyCreateDefinition();
_renderer.customData[0] = &_terrain;
_renderer.customData[1] = &_textures;
_renderer.customData[2] = &_lighting;
_renderer.customData[3] = &_water;
_renderer.customData[4] = &_sky;
configScaling(0.5, 200.0, 3.0, 50.0);
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
@ -61,6 +64,7 @@ protected:
sceneryGetLighting(&_lighting);
sceneryGetTextures(&_textures);
sceneryGetWater(&_water);
sceneryGetSky(&_sky);
}
private:
Renderer _renderer;
@ -68,6 +72,7 @@ private:
WaterDefinition _water;
TexturesDefinition _textures;
LightingDefinition _lighting;
SkyDefinition _sky;
static double _getTerrainHeight(Renderer* renderer, double x, double z)
{
@ -78,6 +83,11 @@ private:
{
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
}
static int _getSkyDomeLights(Renderer* renderer, LightDefinition* array, int max_lights)
{
return skyGetLights((SkyDefinition*)(renderer->customData[4]), renderer, array, max_lights);
}
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
{

View file

@ -112,6 +112,7 @@ FormSky::FormSky(QWidget *parent):
addInputDouble(tr("Sun radius"), &_definition.sun_radius, 0.0, 0.4, 0.004, 0.04);
addInputDouble(tr("Sun halo radius"), &_definition.sun_halo_size, 0.0, 0.4, 0.004, 0.04);
addInputCurve(tr("Sun halo profile"), _definition.sun_halo_profile, 0.0, 1.0, 0.0, 1.0);
addInputDouble(tr("Influence of skydome on lighting"), &_definition.dome_lighting, 0.0, 2.0, 0.01, 0.1);
input = addInputBoolean(tr("Auto colors from daytime"), &_definition.model_custom.auto_from_daytime);
input->setVisibilityCondition((int*)&_definition.model, SKY_MODEL_CUSTOM);
input = addInputColor(tr("Zenith color"), &_definition.model_custom.zenith_color);

View file

@ -60,7 +60,6 @@ public:
light.color.r = 0.6;
light.color.g = 0.6;
light.color.b = 0.6;
light.amplitude = 0.0;
light.direction.x = -1.0;
light.direction.y = -0.5;
light.direction.z = 1.0;
@ -72,7 +71,6 @@ public:
light.color.r = 0.3;
light.color.g = 0.3;
light.color.b = 0.3;
light.amplitude = 0.0;
light.direction.x = 0.5;
light.direction.y = 0.7071;
light.direction.z = -0.5;

View file

@ -77,7 +77,6 @@ public:
_lighting = lightingCreateDefinition();
light.color = COLOR_WHITE;
light.amplitude = 0.0;
light.direction.x = 0.0;
light.direction.y = -0.4794;
light.direction.z = 0.8776;

View file

@ -64,7 +64,6 @@ public:
_lighting = lightingCreateDefinition();
light.color = COLOR_WHITE;
light.amplitude = 0.0;
light.direction.x = 0.0;
light.direction.y = -0.4794;
light.direction.z = 0.8776;

View file

@ -15,7 +15,6 @@ SmallMaterialPreview::SmallMaterialPreview(QWidget* parent, SurfaceMaterial* mat
_lighting = lightingCreateDefinition();
light.color = COLOR_WHITE;
light.amplitude = 0.0;
light.direction.x = -0.5;
light.direction.y = -0.5;
light.direction.z = -0.5;

View file

@ -58,6 +58,11 @@ static Color _applyTextures(Renderer* renderer, Vector3 location, double precisi
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
}
static int _getSkyDomeLights(Renderer* renderer, LightDefinition* array, int max_lights)
{
return skyGetLights((SkyDefinition*)(renderer->customData[4]), renderer, array, max_lights);
}
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
{
light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0));
@ -94,8 +99,10 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
_renderer.customData[1] = &_textures;
_renderer.customData[2] = &_lighting;
_renderer.customData[3] = &_water;
_renderer.customData[4] = &_sky;
_renderer.applyTextures = _applyTextures;
_renderer.getTerrainHeight = _getTerrainHeight;
_renderer.getSkyDomeLights = _getSkyDomeLights;
_renderer.alterLight = _alterLight;
_renderer.getLightStatus = _getLightStatus;

View file

@ -351,12 +351,12 @@ Maintenir Ctrl : Plus rapide</translation>
<context>
<name>FormClouds</name>
<message>
<location filename="../gui_qt/formclouds.cpp" line="155"/>
<location filename="../gui_qt/formclouds.cpp" line="154"/>
<source>Layer coverage (no lighting)</source>
<translation>Couverture de la couche (sans éclairage)</translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="156"/>
<location filename="../gui_qt/formclouds.cpp" line="155"/>
<source>Color and lighting</source>
<translation>Echantillon éclairé</translation>
</message>
@ -373,12 +373,12 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Altitude de fin</translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="158"/>
<location filename="../gui_qt/formclouds.cpp" line="157"/>
<source>Lower altitude</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="159"/>
<location filename="../gui_qt/formclouds.cpp" line="158"/>
<source>Upper altitude</source>
<translation type="unfinished"></translation>
</message>
@ -395,7 +395,7 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Echelle</translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="167"/>
<location filename="../gui_qt/formclouds.cpp" line="166"/>
<source>Material</source>
<translation type="unfinished"></translation>
</message>
@ -412,57 +412,57 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Concentration de la réflexion de lumière</translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="160"/>
<location filename="../gui_qt/formclouds.cpp" line="159"/>
<source>Max coverage</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="161"/>
<location filename="../gui_qt/formclouds.cpp" line="160"/>
<source>Coverage by altitude</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="162"/>
<location filename="../gui_qt/formclouds.cpp" line="161"/>
<source>Shape noise</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="163"/>
<location filename="../gui_qt/formclouds.cpp" line="162"/>
<source>Shape scaling</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="164"/>
<location filename="../gui_qt/formclouds.cpp" line="163"/>
<source>Edge noise</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="165"/>
<location filename="../gui_qt/formclouds.cpp" line="164"/>
<source>Edge scaling</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="166"/>
<location filename="../gui_qt/formclouds.cpp" line="165"/>
<source>Edge length</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="168"/>
<location filename="../gui_qt/formclouds.cpp" line="167"/>
<source>Hardness to light</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="169"/>
<location filename="../gui_qt/formclouds.cpp" line="168"/>
<source>Transparency depth</source>
<translation>Distance de transparence</translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="170"/>
<location filename="../gui_qt/formclouds.cpp" line="169"/>
<source>Light traversal depth</source>
<translation>Distance de traversée de la lumière</translation>
</message>
<message>
<location filename="../gui_qt/formclouds.cpp" line="171"/>
<location filename="../gui_qt/formclouds.cpp" line="170"/>
<source>Minimum lighting</source>
<translation>Eclairage minimal</translation>
</message>
@ -520,62 +520,62 @@ Maintenir Ctrl : Plus rapide</translation>
<context>
<name>FormRender</name>
<message>
<location filename="../gui_qt/formrender.cpp" line="108"/>
<location filename="../gui_qt/formrender.cpp" line="118"/>
<source>Top-down preview</source>
<translation>Aperçu plongeant</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="110"/>
<location filename="../gui_qt/formrender.cpp" line="120"/>
<source>Camera</source>
<translation>Caméra</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="111"/>
<location filename="../gui_qt/formrender.cpp" line="121"/>
<source>Quality</source>
<translation>Qualité de rendu</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="112"/>
<location filename="../gui_qt/formrender.cpp" line="122"/>
<source>Image width</source>
<translation>Largeur de l&apos;image</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="113"/>
<location filename="../gui_qt/formrender.cpp" line="123"/>
<source>Image height</source>
<translation>Hauteur de l&apos;image</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="114"/>
<location filename="../gui_qt/formrender.cpp" line="124"/>
<source>Anti aliasing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="116"/>
<location filename="../gui_qt/formrender.cpp" line="126"/>
<source>Start new render</source>
<translation>Démarrer un rendu</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="118"/>
<location filename="../gui_qt/formrender.cpp" line="128"/>
<source>Show last render</source>
<translation>Voir le dernier rendu</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="120"/>
<location filename="../gui_qt/formrender.cpp" line="130"/>
<source>Save last render</source>
<translation>Sauvegarder le dernier rendu</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="200"/>
<location filename="../gui_qt/formrender.cpp" line="210"/>
<source>Paysages 3D - Choose a filename to save the last render</source>
<translation>Paysages 3D - Choisissez un nom de fichier pour le rendu</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="200"/>
<location filename="../gui_qt/formrender.cpp" line="210"/>
<source>Images (*.png *.jpg)</source>
<translation>Images (*.png *.jpg)</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="213"/>
<location filename="../gui_qt/formrender.cpp" line="223"/>
<source>Can&apos;t write to file : %1</source>
<translation type="unfinished"></translation>
</message>
@ -588,7 +588,7 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Choisissez un nom de fichier pour le rendu</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="209"/>
<location filename="../gui_qt/formrender.cpp" line="219"/>
<source>The picture %1 has been saved.</source>
<translation>L&apos;image %1 a é sauvegardée.</translation>
</message>
@ -651,32 +651,37 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="125"/>
<location filename="../gui_qt/formsky.cpp" line="115"/>
<source>Influence of skydome on lighting</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="126"/>
<source>Turbidity</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="117"/>
<location filename="../gui_qt/formsky.cpp" line="118"/>
<source>Zenith color</source>
<translation>Couleur du ciel au zénith</translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="115"/>
<location filename="../gui_qt/formsky.cpp" line="116"/>
<source>Auto colors from daytime</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="119"/>
<location filename="../gui_qt/formsky.cpp" line="120"/>
<source>Haze color</source>
<translation>Couleur de la brume</translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="121"/>
<location filename="../gui_qt/formsky.cpp" line="122"/>
<source>Haze height</source>
<translation>Hauteur apparente de la brume</translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="123"/>
<location filename="../gui_qt/formsky.cpp" line="124"/>
<source>Haze smoothing</source>
<translation>Facteur de lissage de la brume</translation>
</message>
@ -684,7 +689,7 @@ Maintenir Ctrl : Plus rapide</translation>
<context>
<name>FormTerrain</name>
<message>
<location filename="../gui_qt/formterrain.cpp" line="148"/>
<location filename="../gui_qt/formterrain.cpp" line="146"/>
<source>Height preview (normalized)</source>
<translation>Aperçu de la hauteur (normalisée)</translation>
</message>
@ -693,27 +698,27 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Aperçu du rendu (sans ombres)</translation>
</message>
<message>
<location filename="../gui_qt/formterrain.cpp" line="149"/>
<location filename="../gui_qt/formterrain.cpp" line="147"/>
<source>Lighted preview (no texture)</source>
<translation>Aperçu éclairé (sans texture)</translation>
</message>
<message>
<location filename="../gui_qt/formterrain.cpp" line="151"/>
<location filename="../gui_qt/formterrain.cpp" line="149"/>
<source>Noise</source>
<translation>Bruit</translation>
</message>
<message>
<location filename="../gui_qt/formterrain.cpp" line="152"/>
<location filename="../gui_qt/formterrain.cpp" line="150"/>
<source>Height</source>
<translation>Hauteur</translation>
</message>
<message>
<location filename="../gui_qt/formterrain.cpp" line="153"/>
<location filename="../gui_qt/formterrain.cpp" line="151"/>
<source>Scaling</source>
<translation>Echelle</translation>
</message>
<message>
<location filename="../gui_qt/formterrain.cpp" line="154"/>
<location filename="../gui_qt/formterrain.cpp" line="152"/>
<source>Shadow smoothing</source>
<translation type="unfinished"></translation>
</message>
@ -721,7 +726,7 @@ Maintenir Ctrl : Plus rapide</translation>
<context>
<name>FormTextures</name>
<message>
<location filename="../gui_qt/formtextures.cpp" line="138"/>
<location filename="../gui_qt/formtextures.cpp" line="137"/>
<source>Coverage preview</source>
<translation>Aperçu de la couverture</translation>
</message>
@ -730,22 +735,22 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Rendu en couleur</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="139"/>
<location filename="../gui_qt/formtextures.cpp" line="138"/>
<source>Lighted sample</source>
<translation>Echantillon éclairé</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="141"/>
<location filename="../gui_qt/formtextures.cpp" line="140"/>
<source>Surface noise</source>
<translation>Bruit de surface</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="142"/>
<location filename="../gui_qt/formtextures.cpp" line="141"/>
<source>Surface noise height</source>
<translation>Hauteur du bruit</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="143"/>
<location filename="../gui_qt/formtextures.cpp" line="142"/>
<source>Surface noise scaling</source>
<translation>Echelle du bruit</translation>
</message>
@ -762,47 +767,47 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Concentration de la lumière réfléchie</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="147"/>
<location filename="../gui_qt/formtextures.cpp" line="146"/>
<source>Soft minimal height</source>
<translation>Altitude minimal (adoucie)</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="146"/>
<location filename="../gui_qt/formtextures.cpp" line="145"/>
<source>Hard minimal height</source>
<translation>Altitude minimale</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="144"/>
<location filename="../gui_qt/formtextures.cpp" line="143"/>
<source>Material</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="149"/>
<location filename="../gui_qt/formtextures.cpp" line="148"/>
<source>Hard maximal height</source>
<translation>Altitude maximale</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="148"/>
<location filename="../gui_qt/formtextures.cpp" line="147"/>
<source>Soft maximal height</source>
<translation>Altitude maximale (adoucie)</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="151"/>
<location filename="../gui_qt/formtextures.cpp" line="150"/>
<source>Soft minimal slope</source>
<translation>Pente minimale (adoucie)</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="150"/>
<location filename="../gui_qt/formtextures.cpp" line="149"/>
<source>Hard minimal slope</source>
<translation>Pente minimale</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="153"/>
<location filename="../gui_qt/formtextures.cpp" line="152"/>
<source>Hard maximal slope</source>
<translation>Pente maximale</translation>
</message>
<message>
<location filename="../gui_qt/formtextures.cpp" line="152"/>
<location filename="../gui_qt/formtextures.cpp" line="151"/>
<source>Soft maximal slope</source>
<translation>Pente maximale (adoucie)</translation>
</message>
@ -810,7 +815,7 @@ Maintenir Ctrl : Plus rapide</translation>
<context>
<name>FormWater</name>
<message>
<location filename="../gui_qt/formwater.cpp" line="173"/>
<location filename="../gui_qt/formwater.cpp" line="172"/>
<source>Coverage preview</source>
<translation>Aperçu de la couverture</translation>
</message>
@ -819,7 +824,7 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Aperçu du rendu (sans/avec éclairage)</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="176"/>
<location filename="../gui_qt/formwater.cpp" line="175"/>
<source>Height</source>
<translation>Hauteur</translation>
</message>
@ -836,52 +841,52 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Concentration de la lumière réfléchie</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="177"/>
<location filename="../gui_qt/formwater.cpp" line="176"/>
<source>Surface material</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="179"/>
<location filename="../gui_qt/formwater.cpp" line="178"/>
<source>Transparency</source>
<translation>Transparence</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="180"/>
<location filename="../gui_qt/formwater.cpp" line="179"/>
<source>Reflection</source>
<translation>Reflets</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="181"/>
<location filename="../gui_qt/formwater.cpp" line="180"/>
<source>Transparency distance</source>
<translation>Distance maximale de transparence</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="178"/>
<location filename="../gui_qt/formwater.cpp" line="177"/>
<source>Depth color</source>
<translation>Couleur en profondeur</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="174"/>
<location filename="../gui_qt/formwater.cpp" line="173"/>
<source>Rendered preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="182"/>
<location filename="../gui_qt/formwater.cpp" line="181"/>
<source>Light-through distance</source>
<translation>Distance de filtrage de la lumière</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="183"/>
<location filename="../gui_qt/formwater.cpp" line="182"/>
<source>Waves noise</source>
<translation>Bruit des vagues</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="184"/>
<location filename="../gui_qt/formwater.cpp" line="183"/>
<source>Waves height</source>
<translation>Hauteur des vagues</translation>
</message>
<message>
<location filename="../gui_qt/formwater.cpp" line="185"/>
<location filename="../gui_qt/formwater.cpp" line="184"/>
<source>Waves scaling</source>
<translation>Echelle des vagues</translation>
</message>

View file

@ -64,7 +64,6 @@ void autoGenRealisticLandscape(int seed)
SkyDefinition sky;
TexturesDefinition textures;
TextureLayerDefinition* texture;
LightingDefinition lighting;
if (!seed)
{
@ -114,6 +113,7 @@ void autoGenRealisticLandscape(int seed)
sky.sun_color.a = 1.0;
sky.sun_radius = 0.02;
sky.sun_halo_size = 0.3;
sky.dome_lighting = 0.6;
curveClear(sky.sun_halo_profile);
curveQuickAddPoint(sky.sun_halo_profile, 0.0, 1.0);
curveQuickAddPoint(sky.sun_halo_profile, 0.1, 0.2);
@ -133,12 +133,6 @@ void autoGenRealisticLandscape(int seed)
scenerySetSky(&sky);
skyDeleteDefinition(&sky);
/* Lighting */
lighting = lightingCreateDefinition();
lighting.autosetfromsky = 1;
scenerySetLighting(&lighting);
lightingDeleteDefinition(&lighting);
/* Terrain */
terrain = terrainCreateDefinition();
noiseGenerateBaseNoise(terrain.height_noise, 1048576);

View file

@ -5,6 +5,12 @@
#include "tools.h"
Vector3 VECTOR_ZERO = {0.0, 0.0, 0.0};
Vector3 VECTOR_DOWN = {0.0, -1.0, 0.0};
Vector3 VECTOR_UP = {0.0, 1.0, 0.0};
Vector3 VECTOR_NORTH = {0.0, 0.0, -1.0};
Vector3 VECTOR_SOUTH = {0.0, 0.0, 1.0};
Vector3 VECTOR_WEST = {-1.0, 0.0, 0.0};
Vector3 VECTOR_EAST = {1.0, 0.0, 0.0};
void v3Save(PackStream* stream, Vector3* v)
{

View file

@ -35,6 +35,12 @@ typedef struct
} Matrix4;
extern Vector3 VECTOR_ZERO;
extern Vector3 VECTOR_DOWN;
extern Vector3 VECTOR_UP;
extern Vector3 VECTOR_NORTH;
extern Vector3 VECTOR_SOUTH;
extern Vector3 VECTOR_EAST;
extern Vector3 VECTOR_WEST;
void v3Save(PackStream* stream, Vector3* v);
void v3Load(PackStream* stream, Vector3* v);

View file

@ -26,7 +26,6 @@ void lightingInit()
_LIGHT_NULL.reflection = 0.0;
_LIGHT_NULL.filtered = 0;
_LIGHT_NULL.masked = 0;
_LIGHT_NULL.amplitude = 0.0;
}
void lightingQuit()
@ -37,7 +36,6 @@ void lightingSave(PackStream* stream, LightingDefinition* definition)
{
int i;
packWriteInt(stream, &definition->autosetfromsky);
packWriteInt(stream, &definition->nblights);
for (i = 0; i < definition->nblights; i++)
{
@ -46,7 +44,6 @@ void lightingSave(PackStream* stream, LightingDefinition* definition)
packWriteDouble(stream, &definition->lights[i].reflection);
packWriteInt(stream, &definition->lights[i].filtered);
packWriteInt(stream, &definition->lights[i].masked);
packWriteDouble(stream, &definition->lights[i].amplitude);
}
}
@ -54,7 +51,6 @@ void lightingLoad(PackStream* stream, LightingDefinition* definition)
{
int i;
packReadInt(stream, &definition->autosetfromsky);
packReadInt(stream, &definition->nblights);
for (i = 0; i < definition->nblights; i++)
{
@ -63,7 +59,6 @@ void lightingLoad(PackStream* stream, LightingDefinition* definition)
packReadDouble(stream, &definition->lights[i].reflection);
packReadInt(stream, &definition->lights[i].filtered);
packReadInt(stream, &definition->lights[i].masked);
packReadDouble(stream, &definition->lights[i].amplitude);
}
lightingValidateDefinition(definition);
@ -73,9 +68,7 @@ LightingDefinition lightingCreateDefinition()
{
LightingDefinition definition;
definition.autosetfromsky = 0;
definition.nblights = 0;
definition._nbautolights = 0;
return definition;
}
@ -91,19 +84,6 @@ void lightingCopyDefinition(LightingDefinition* source, LightingDefinition* dest
void lightingValidateDefinition(LightingDefinition* definition)
{
if (definition->autosetfromsky)
{
SkyDefinition sky;
sky = skyCreateDefinition();
sceneryGetSky(&sky);
definition->_nbautolights = skyGetLights(&sky, definition->_autolights, LIGHTING_MAX_LIGHTS);
skyDeleteDefinition(&sky);
}
else
{
definition->_nbautolights = 0;
}
}
int lightingGetLightCount(LightingDefinition* definition)
@ -176,44 +156,6 @@ static Color _applyDirectLight(LightDefinition* definition, Renderer* renderer,
light = definition->color;
direction_inv = v3Scale(definition->direction, -1.0);
if (definition->amplitude > 0.0)
{
/* TODO Sampling around light direction */
int xsamples, ysamples, samples, x, y;
double xstep, ystep, factor;
LightDefinition sublight;
ysamples = renderer->render_quality / 4 + 1;
xsamples = renderer->render_quality / 2 + 1;
samples = xsamples * ysamples + 1;
factor = 1.0 / (double)samples;
xstep = M_PI * 2.0 / (double)xsamples;
ystep = M_PI * 0.5 / (double)(ysamples - 1);
sublight = *definition;
sublight.amplitude = 0.0;
sublight.color.r *= factor;
sublight.color.g *= factor;
sublight.color.b *= factor;
result = _applyDirectLight(&sublight, renderer, location, normal, material);
for (x = 0; x < xsamples; x++)
{
for (y = 0; y < ysamples; y++)
{
sublight.direction.x = cos(x * xstep) * cos(y * ystep);
sublight.direction.y = -sin(y * ystep);
sublight.direction.z = sin(x * xstep) * cos(y * ystep);
light = _applyDirectLight(&sublight, renderer, location, normal, material);
result.r += light.r;
result.g += light.g;
result.b += light.b;
}
}
return result;
}
normal_norm = v3Norm(normal);
if (normal_norm > 1.0)
{
@ -266,10 +208,12 @@ static Color _applyDirectLight(LightDefinition* definition, Renderer* renderer,
void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vector3 location, LightStatus* result)
{
int i;
int i, skydome_lights_count;
LightDefinition skydome_lights[LIGHTING_MAX_LIGHTS];
result->nblights = 0;
/* Apply static lights */
for (i = 0; i < definition->nblights; i++)
{
if (_getLightStatus(definition->lights + i, renderer, location, result->lights + result->nblights))
@ -277,9 +221,13 @@ void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vecto
result->nblights++;
}
}
for (i = 0; i < definition->_nbautolights; i++)
/* Apply skydome lights */
/* TODO Cache skydome lights for same render */
skydome_lights_count = renderer->getSkyDomeLights(renderer, skydome_lights, LIGHTING_MAX_LIGHTS);
for (i = 0; i < skydome_lights_count; i++)
{
if (_getLightStatus(definition->_autolights + i, renderer, location, result->lights + result->nblights))
if (_getLightStatus(skydome_lights + i, renderer, location, result->lights + result->nblights))
{
result->nblights++;
}

View file

@ -9,7 +9,7 @@
extern "C" {
#endif
#define LIGHTING_MAX_LIGHTS 10
#define LIGHTING_MAX_LIGHTS 30
struct LightDefinition
{
@ -18,16 +18,12 @@ struct LightDefinition
double reflection; /* Reflected factor of the light (for specular lighting) */
int filtered; /* Should the light be filtered (by atmosphere, water...) */
int masked; /* Should the light be masked (cast shadows..) */
double amplitude; /* Angle amplitude of the light source (for multi-sampling, pi / 2.0 for skydome) */
};
typedef struct
{
int autosetfromsky;
int nblights;
LightDefinition lights[LIGHTING_MAX_LIGHTS];
int _nbautolights;
LightDefinition _autolights[LIGHTING_MAX_LIGHTS];
} LightingDefinition;
struct LightStatus

View file

@ -2,21 +2,71 @@
#include <math.h>
/*static double _phase(double g, double theta)
{
double g2 = g * g;
double costheta = cos(theta);
return ((3.0 * (1.0 - g2)) / (2.0 * (2.0 + g2))) * ((1.0 + costheta * costheta) / exp(1.0 + g2 - 2.0 * g * costheta, 1.5));
}
static Vector3 _betaR = {5.5e-6, 13.0e-6, 22.4e-6}; /* Rayleigh scattering coefficients at sea level */
static Vector3 _betaM = {21e-6, 0.0, 0.0}; /* Mie scattering coefficients at sea level */
static double _Hr = 7994; /* Rayleigh scale height */
static double _Hm = 1200; /* Mie scale height */
static double _radiusEarth = 6360e3; /* Earth radius */
static double _radiusAtmosphere = 6420e3; /* Atmosphere radius */
static double _sunIntensity = 20.0; /* Sun intensity */
static double _g = 0.76; /* Mean cosine */
static double _intOpticalDepthCallback(double h, double* h0)
/*typedef struct
{
return -h / *h0;
}
double tmin;
double tmax;
} Ray;
static double _opticalDepth(double h0, double lambda, double k, Vector3 start, Vector3 end)
static Vector3 _computeIncidentLight(Ray r)
{
return 4.0 * M_PI * k * toolsIntegrate(_intOpticalDepthCallback);
double t0, t1;
int numSamples = 16;
int numSamplesLight = 8;
int i, j;
if (!intersect<T>(r, radiusAtmosphere, t0, t1) || t1 < 0) return Vec3<T>(0);
if (t0 > r.tmin && t0 > 0) r.tmin = t0;
if (t1 < r.tmax) r.tmax = t1;
double segmentLength = (r.tmax - r.tmin) / (double)numSamples;
double tCurrent = r.tmin;
Vector3 sumR = VECTOR_ZERO;
Vector3 sumM = VECTOR_ZERO;
double opticalDepthR = 0.0;
double opticalDepthM = 0.0;
double mu = r.direction.dot(sunDirection);
double phaseR = 3.0 / (16.0 * M_PI) * (1.0 + mu * mu);
double phaseM = 3.0 / (8.0 * M_PI) * ((1.0 - _g * _g) * (1 + mu * mu)) / ((2 + _g * _g) * pow(1 + _g * _g - 2 * _g * mu, 1.5));
for (i = 0; i < numSamples; ++i)
{
Vector3 samplePosition = r(tCurrent + T(0.5) * segmentLength);
double height = samplePosition.magnitude() - radiusEarth;
double hr = exp(-height / _Hr) * segmentLength;
double hm = exp(-height / _Hm) * segmentLength;
opticalDepthR += hr;
opticalDepthM += hm;
Ray lightRay(samplePosition, sunDirection);
intersect(lightRay, radiusAtmosphere, lightRay.tmin, lightRay.tmax);
double segmentLengthLight = lightRay.tmax / numSamplesLight;
double tCurrentLight = 0.0;
double opticalDepthLightR = 0.0;
double opticalDepthLightM = 0.0;
for (j = 0; j < numSamplesLight; ++j) {
Vector3 samplePositionLight = lightRay(tCurrentLight + T(0.5) * segmentLengthLight);
T heightLight = samplePositionLight.magnitude() - radiusEarth;
if (heightLight < 0) break;
opticalDepthLightR += exp(-heightLight / Hr) * segmentLengthLight;
opticalDepthLightM += exp(-heightLight / Hm) * segmentLengthLight;
tCurrentLight += segmentLengthLight;
}
if (j == numSamplesLight) {
Vec3<T> tau = betaR * (opticalDepthR + opticalDepthLightR) + betaM * 1.1 * (opticalDepthM + opticalDepthLightM);
Vec3<T> attenuation(exp(-tau.x), exp(-tau.y), exp(-tau.z));
sumR += hr * attenuation;
sumM += hm * attenuation;
}
tCurrent += segmentLength;
}
return 20 * (sumR * phaseR * _betaR + sumM * phaseM * _betaM);
}*/
Color rayleighGetSkyColor(Vector3 viewer, Vector3 direction, Vector3 sun_direction)

View file

@ -54,6 +54,11 @@ static void _pushQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Ve
renderer->pushTriangle(renderer, v4, v1, v3, callback, callback_data);
}
static int _getSkyDomeLights(Renderer* renderer, LightDefinition* array, int max_lights)
{
return 0;
}
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
{
}
@ -129,6 +134,7 @@ Renderer rendererCreate()
result.applyAtmosphere = _applyAtmosphere;
result.applyClouds = _applyClouds;
result.getSkyDomeLights = _getSkyDomeLights;
result.alterLight = _alterLight;
result.getLightStatus = _getLightStatus;
result.applyLightStatus = _applyLightStatus;

View file

@ -39,6 +39,7 @@ struct Renderer
Color (*applyClouds)(Renderer* renderer, Color base, Vector3 start, Vector3 end);
/* Lighting related */
int (*getSkyDomeLights)(Renderer* renderer, LightDefinition* array, int max_lights);
void (*alterLight)(Renderer* renderer, LightDefinition* light, Vector3 location);
void (*getLightStatus)(Renderer* renderer, LightStatus* status, Vector3 location);
Color (*applyLightStatus)(Renderer* renderer, LightStatus* status, Vector3 location, Vector3 normal, SurfaceMaterial material);

View file

@ -224,6 +224,11 @@ void sceneryRenderFirstPass(Renderer* renderer)
/******* Standard renderer *********/
static int _getSkyDomeLights(Renderer* renderer, LightDefinition* array, int max_lights)
{
return skyGetLights(&_sky, renderer, array, max_lights);
}
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
{
Vector3 light_location;
@ -330,6 +335,7 @@ Renderer sceneryCreateStandardRenderer()
cameraCopyDefinition(&_camera, &result.render_camera);
result.camera_location = _camera.location;
result.getSkyDomeLights = _getSkyDomeLights;
result.alterLight = _alterLight;
result.getLightStatus = _getLightStatus;
result.applyLightStatus = _applyLightStatus;

View file

@ -32,6 +32,7 @@ void skySave(PackStream* stream, SkyDefinition* definition)
packWriteDouble(stream, &definition->sun_radius);
packWriteDouble(stream, &definition->sun_halo_size);
curveSave(stream, definition->sun_halo_profile);
packWriteDouble(stream, &definition->dome_lighting);
packWriteInt(stream, &definition->model_custom.auto_from_daytime);
colorSave(stream, &definition->model_custom.zenith_color);
@ -50,6 +51,7 @@ void skyLoad(PackStream* stream, SkyDefinition* definition)
packReadDouble(stream, &definition->sun_radius);
packReadDouble(stream, &definition->sun_halo_size);
curveLoad(stream, definition->sun_halo_profile);
packReadDouble(stream, &definition->dome_lighting);
packReadInt(stream, &definition->model_custom.auto_from_daytime);
colorLoad(stream, &definition->model_custom.zenith_color);
@ -72,6 +74,7 @@ SkyDefinition skyCreateDefinition()
def.sun_radius = 1.0;
def.sun_halo_size = 0.0;
def.sun_halo_profile = curveCreate();
def.dome_lighting = 0.0;
def.model_custom.auto_from_daytime = 0;
def.model_custom.zenith_color = COLOR_BLACK;
def.model_custom.haze_color = COLOR_BLACK;
@ -98,6 +101,7 @@ void skyCopyDefinition(SkyDefinition* source, SkyDefinition* destination)
destination->sun_color = source->sun_color;
destination->sun_radius = source->sun_radius;
destination->sun_halo_size = source->sun_halo_size;
destination->dome_lighting = source->dome_lighting;
destination->model_custom.auto_from_daytime = source->model_custom.auto_from_daytime;
destination->model_custom.zenith_color = source->model_custom.zenith_color;
destination->model_custom.haze_color = source->model_custom.haze_color;
@ -156,7 +160,19 @@ void skyValidateDefinition(SkyDefinition* definition)
}
}
int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights)
static inline void _addDomeLight(SkyDefinition* sky, Renderer* renderer, LightDefinition* light, Vector3 direction, double factor)
{
light->direction = v3Scale(direction, -1.0);
light->color = skyGetColor(sky, renderer, VECTOR_ZERO, direction);
light->color.r *= factor;
light->color.g *= factor;
light->color.b *= factor;
light->reflection = 0.0;
light->filtered = 0;
light->masked = 0;
}
int skyGetLights(SkyDefinition* sky, Renderer* renderer, LightDefinition* lights, int max_lights)
{
double sun_angle;
Vector3 sun_direction;
@ -167,33 +183,56 @@ int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights)
sun_direction.y = sin(sun_angle);
sun_direction.z = 0.0;
/* TODO Night lights */
/* TODO Moon light */
if (max_lights > 0)
{
/* Light from the sun */
/* Direct light from the sun */
lights[0].direction = v3Scale(sun_direction, -1.0);
lights[0].color = sky->sun_color;
lights[0].reflection = 1.0;
lights[0].filtered = 1;
lights[0].masked = 1;
lights[0].amplitude = 0.0;
nblights = 1;
if (max_lights > 1)
max_lights--;
}
if (max_lights > 0)
{
/* Indirect lighting by skydome scattering */
int xsamples, ysamples, samples, x, y;
double xstep, ystep, factor;
Vector3 direction;
samples = (renderer->render_quality < 5) ? 9 : (renderer->render_quality * 4 + 1);
samples = samples > max_lights ? max_lights : samples;
factor = sky->dome_lighting / (double)samples;
_addDomeLight(sky, renderer, lights + nblights, VECTOR_UP, factor);
nblights++;
samples--;
if (samples >= 2)
{
/* Skydome lighting */
lights[1].direction.x = 0.0;
lights[1].direction.y = -1.0;
lights[1].direction.z = 0.0;
lights[1].color = skyGetZenithColor(sky);
lights[1].color.r *= 0.6;
lights[1].color.g *= 0.6;
lights[1].color.b *= 0.6;
lights[1].reflection = 0.0;
lights[1].filtered = 1;
lights[1].masked = 0;
lights[1].amplitude = M_PI / 2.0;
nblights = 2;
xsamples = samples / 2;
ysamples = samples / xsamples;
xstep = M_PI * 2.0 / (double)xsamples;
ystep = M_PI * 0.5 / (double)ysamples;
for (x = 0; x < xsamples; x++)
{
for (y = 0; y < ysamples; y++)
{
direction.x = cos(x * xstep) * cos(y * ystep);
direction.y = -sin(y * ystep);
direction.z = sin(x * xstep) * cos(y * ystep);
_addDomeLight(sky, renderer, lights + nblights, direction, factor);
nblights++;
}
}
}
}

View file

@ -25,6 +25,7 @@ typedef struct
double sun_radius;
double sun_halo_size;
Curve* sun_halo_profile;
double dome_lighting;
struct {
int auto_from_daytime;
Color zenith_color;
@ -48,7 +49,7 @@ void skyDeleteDefinition(SkyDefinition* definition);
void skyCopyDefinition(SkyDefinition* source, SkyDefinition* destination);
void skyValidateDefinition(SkyDefinition* definition);
int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights);
int skyGetLights(SkyDefinition* sky, Renderer* renderer, LightDefinition* lights, int max_lights);
Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Vector3 look);
void skyRender(SkyDefinition* definition, Renderer* renderer);
Vector3 skyGetSunDirection(SkyDefinition* definition);