diff --git a/TODO b/TODO
index 012935b..04b1189 100644
--- a/TODO
+++ b/TODO
@@ -22,6 +22,7 @@ Technology Preview 3 :
- Add basic vegetation system (not sure).
- Improve sky rendering (colors and light halo).
- Add a progress indicator on previews.
+- Multi threaded first pass.
Release Candidate :
- Polish all features and UI.
diff --git a/gui_qt/formclouds.cpp b/gui_qt/formclouds.cpp
index da69bb4..568742f 100644
--- a/gui_qt/formclouds.cpp
+++ b/gui_qt/formclouds.cpp
@@ -158,6 +158,7 @@ FormClouds::FormClouds(QWidget *parent):
addInputColor(tr("Base color"), &_layer.material.base);
addInputDouble(tr("Light reflection"), &_layer.material.reflection, 0.0, 1.0, 0.01, 0.1);
addInputDouble(tr("Light reflection shininess"), &_layer.material.shininess, 0.0, 20.0, 0.1, 1.0);
+ addInputDouble(tr("Hardness to light"), &_layer.hardness, 0.0, 1.0, 0.01, 0.1);
addInputDouble(tr("Transparency depth"), &_layer.transparencydepth, 0.0, 100.0, 0.5, 5.0);
addInputDouble(tr("Light traversal depth"), &_layer.lighttraversal, 0.0, 100.0, 0.5, 5.0);
addInputDouble(tr("Minimum lighting"), &_layer.minimumlight, 0.0, 1.0, 0.01, 0.1);
diff --git a/i18n/paysages_fr.ts b/i18n/paysages_fr.ts
index df8a85e..24915c6 100644
--- a/i18n/paysages_fr.ts
+++ b/i18n/paysages_fr.ts
@@ -309,16 +309,21 @@ Maintenir Ctrl : Plus rapide
+
+
+
+
+
Distance de transparence
-
+
Distance de traversée de la lumière
-
+
Eclairage minimal
diff --git a/lib_paysages/clouds.c b/lib_paysages/clouds.c
index c6b9b7f..c759f7e 100644
--- a/lib_paysages/clouds.c
+++ b/lib_paysages/clouds.c
@@ -47,6 +47,7 @@ void cloudsSave(PackStream* stream, CloudsDefinition* definition)
packWriteDouble(stream, &layer->ymax);
noiseSaveGenerator(stream, layer->noise);
materialSave(stream, &layer->material);
+ packWriteDouble(stream, &layer->hardness);
packWriteDouble(stream, &layer->transparencydepth);
packWriteDouble(stream, &layer->lighttraversal);
packWriteDouble(stream, &layer->minimumlight);
@@ -75,6 +76,7 @@ void cloudsLoad(PackStream* stream, CloudsDefinition* definition)
packReadDouble(stream, &layer->ymax);
noiseLoadGenerator(stream, layer->noise);
materialLoad(stream, &layer->material);
+ packReadDouble(stream, &layer->hardness);
packReadDouble(stream, &layer->transparencydepth);
packReadDouble(stream, &layer->lighttraversal);
packReadDouble(stream, &layer->minimumlight);
@@ -160,6 +162,7 @@ CloudsLayerDefinition cloudsLayerCreateDefinition()
result.material.base.b = 0.7;
result.material.reflection = 0.1;
result.material.shininess = 2.0;
+ result.hardness = 0.1;
result.transparencydepth = 20.0;
result.lighttraversal = 50.0;
result.minimumlight = 0.5;
@@ -482,10 +485,13 @@ static Color _applyLayerLighting(CloudsLayerDefinition* definition, Renderer* re
Vector3 normal;
normal = v3Scale(_getNormal(definition, position, 3.0), 0.25);
- normal = v3Add(normal, v3Scale(_getNormal(definition, position, 2.0), 0.25));
- normal = v3Add(normal, v3Scale(_getNormal(definition, position, 1.0), 0.25));
+ if (renderer->render_quality > 5)
+ {
+ normal = v3Add(normal, v3Scale(_getNormal(definition, position, 2.0), 0.25));
+ normal = v3Add(normal, v3Scale(_getNormal(definition, position, 1.0), 0.25));
+ }
normal = v3Add(normal, v3Scale(_getNormal(definition, position, 0.5), 0.25));
- normal = v3Scale(v3Normalize(normal), 0.1);
+ normal = v3Scale(v3Normalize(normal), definition->hardness);
return renderer->applyLightingToSurface(renderer, position, normal, definition->material);
}
diff --git a/lib_paysages/clouds.h b/lib_paysages/clouds.h
index a58d0ff..f8da51a 100644
--- a/lib_paysages/clouds.h
+++ b/lib_paysages/clouds.h
@@ -23,6 +23,7 @@ struct CloudsLayerDefinition
double ymax;
NoiseGenerator* noise;
SurfaceMaterial material;
+ double hardness;
double transparencydepth;
double lighttraversal;
double minimumlight;
diff --git a/lib_paysages/textures.c b/lib_paysages/textures.c
index 239b543..83b34fb 100644
--- a/lib_paysages/textures.c
+++ b/lib_paysages/textures.c
@@ -191,40 +191,82 @@ void texturesDeleteLayer(TexturesDefinition* definition, int layer)
}
}
-static inline Vector3 _getNormal(TextureLayerDefinition* definition, Renderer* renderer, Vector3 point, double scale)
+static inline Vector3 _getPoint(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, Vector3 prenormal, double scale)
+{
+ Vector3 point;
+
+ point.x = x;
+ point.z = z;
+ point.y = renderer->getTerrainHeight(renderer, point.x, point.z);
+
+ return v3Add(point, v3Scale(prenormal, noiseGet2DTotal(definition->bump_noise, point.x / definition->bump_scaling, point.z / definition->bump_scaling) * definition->bump_height));
+}
+
+static inline Vector3 _getPreNormal(TextureLayerDefinition* definition, Renderer* renderer, Vector3 point, double scale)
{
Vector3 dpoint, ref, normal;
+
+ /* TODO This method is better suited in terrain.c */
- ref.x = 0.0;
ref.y = 0.0;
- point.y = renderer->getTerrainHeight(renderer, point.x, point.z) + noiseGet2DTotal(definition->bump_noise, point.x / definition->bump_scaling, point.z / definition->bump_scaling) * definition->bump_height;
-
- dpoint.x = point.x - scale;
- dpoint.z = point.z;
- dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x / definition->bump_scaling, dpoint.z / definition->bump_scaling) * definition->bump_height;
- ref.z = -1.0;
- normal = v3Normalize(v3Cross(ref, v3Sub(dpoint, point)));
+ point.y = renderer->getTerrainHeight(renderer, point.x, point.z);
dpoint.x = point.x + scale;
dpoint.z = point.z;
- dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x / definition->bump_scaling, dpoint.z / definition->bump_scaling) * definition->bump_height;
+ dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z);
+ ref.x = 0.0;
ref.z = 1.0;
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
- ref.z = 0.0;
-
- dpoint.x = point.x;
- dpoint.z = point.z - scale;
- dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x / definition->bump_scaling, dpoint.z / definition->bump_scaling) * definition->bump_height;
- ref.x = 1.0;
- normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
-
dpoint.x = point.x;
dpoint.z = point.z + scale;
- dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x / definition->bump_scaling, dpoint.z / definition->bump_scaling) * definition->bump_height;
+ dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z);
ref.x = -1.0;
+ ref.z = 0.0;
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
+ if (renderer->render_quality > 5)
+ {
+ dpoint.x = point.x;
+ dpoint.z = point.z - scale;
+ dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z);
+ ref.x = 1.0;
+ ref.z = 0.0;
+ normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
+
+ dpoint.x = point.x - scale;
+ dpoint.z = point.z;
+ dpoint.y = renderer->getTerrainHeight(renderer, dpoint.x, dpoint.z);
+ ref.x = 0.0;
+ ref.z = -1.0;
+ normal = v3Normalize(v3Cross(ref, v3Sub(dpoint, point)));
+ }
+
+ return v3Normalize(normal);
+}
+
+static inline Vector3 _getPostNormal(TextureLayerDefinition* definition, Renderer* renderer, Vector3 point, Vector3 prenormal, double scale)
+{
+ Vector3 p0, d1, d2, d3, d4, normal;
+
+ p0 = _getPoint(definition, renderer, point.x, point.z, prenormal, scale);
+
+ d1 = v3Normalize(v3Sub(_getPoint(definition, renderer, point.x + scale, point.z, prenormal, scale), p0));
+ d3 = v3Normalize(v3Sub(_getPoint(definition, renderer, point.x, point.z + scale, prenormal, scale), p0));
+ if (renderer->render_quality > 5)
+ {
+ d2 = v3Normalize(v3Sub(_getPoint(definition, renderer, point.x - scale, point.z, prenormal, scale), p0));
+ d4 = v3Normalize(v3Sub(_getPoint(definition, renderer, point.x, point.z - scale, prenormal, scale), p0));
+ }
+
+ normal = v3Cross(d3, d1);
+ if (renderer->render_quality > 5)
+ {
+ normal = v3Add(normal, v3Cross(d1, d4));
+ normal = v3Add(normal, v3Cross(d4, d2));
+ normal = v3Add(normal, v3Cross(d2, d3));
+ }
+
return v3Normalize(normal);
}
@@ -232,7 +274,7 @@ double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* re
{
Vector3 normal;
- normal = _getNormal(definition, renderer, location, detail * 0.1);
+ normal = _getPreNormal(definition, renderer, location, detail * 0.1);
return zoneGetValue(definition->zone, location, normal);
}
@@ -244,11 +286,12 @@ Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* render
double coverage;
result = COLOR_TRANSPARENT;
- normal = _getNormal(definition, renderer, location, detail * 0.1);
+ normal = _getPreNormal(definition, renderer, location, detail * 0.1);
coverage = zoneGetValue(definition->zone, location, normal);
if (coverage > 0.0)
{
+ normal = _getPostNormal(definition, renderer, location, normal, detail * 0.1);
result = renderer->applyLightingToSurface(renderer, location, normal, definition->material);
result.a = coverage;
}