From a95c07623ce617d8a0217fa4c91ec1ccd77a2a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Mon, 19 Nov 2012 20:40:57 +0000 Subject: [PATCH] paysages : Added foam to water + auto preset for water. git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@464 b1fd45b6-86a6-48da-8261-f70d1f35bdcc --- ChangeLog | 48 +++++++++++++--------- TODO | 18 +++++---- gui_qt/baseform.cpp | 35 ++++++++++++++++ gui_qt/baseform.h | 6 +++ gui_qt/formwater.cpp | 18 ++++++++- gui_qt/formwater.h | 1 + images/auto.png | Bin 0 -> 4425 bytes lib_paysages/water.c | 94 +++++++++++++++++++++++++++++++++++++++---- lib_paysages/water.h | 4 ++ 9 files changed, 188 insertions(+), 36 deletions(-) create mode 100644 images/auto.png diff --git a/ChangeLog b/ChangeLog index a3a2a4f..11f27ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,27 +1,31 @@ ????-??-?? Technology Preview 2 ------------------------------- -Previews : - * Scaling is now logarithmic (slower when zoomed). - * Drawing now takes advantage of multiple CPU cores. +Global : + * Version handling in saved files. + * Replaced old noise algorithm with Simplex Noise (up to 4 times faster). -3D Explorer: - * Added ground texture and skybox. - * Progressive rendering now takes advantage of multiple CPU cores. +Terrain : + * Added canvases to paint the shape directly. + * Shadows have been improved and are now configurable. -Scenery : - * Added terrain canvases to paint the shape directly. - * Added clouds hardness to light. - * Added sun halo control. - * New cloud model with 2 noises : one for the global shape and one for edges. - * Terrain shadows have been improved and are now configurable. - * New sky model (based on Preetham's work). +Textures : + * New texture model (perpendicular displacement and thickness). * Textures ranges are now using curves. +Water : + * Added foam. + +Sky : + * New sky model (based on Preetham's work). + * Added sun halo control. + +Clouds : + * Added clouds hardness to light. + * New cloud model with 2 noises : one for the global shape and one for edges. + Rendering : - * New texture model (perpendicular displacement and thickness). * Added full scene antialiasing (FSAA). - * Replaced old noise algorithm with Simplex Noise (up to 4 times faster). GUI : * Improved curve rendering. @@ -29,12 +33,18 @@ GUI : * Added render timer. * Previews locations and render params are now saved. * Added grid and axis labels to curve editor. - * Added camera location to previews. - * Added toggles and choices to configure some previews. * Added layer sorting and naming. + * Automatic settings can be loaded from presets. -Misc : - * Version handling in saved files. +Previews : + * Scaling is now logarithmic (slower when zoomed). + * Drawing now takes advantage of multiple CPU cores. + * Added camera location. + * Added toggles and choices to configure some previews. + +3D Explorer: + * Added ground texture and skybox. + * Progressive rendering now takes advantage of multiple CPU cores. 2012-04-20 Technology Preview 1 ------------------------------- diff --git a/TODO b/TODO index 0d1f996..136520f 100644 --- a/TODO +++ b/TODO @@ -1,22 +1,26 @@ Technology Preview 2 : - Fully move layer management from BaseForm to BaseFormLayer. -- Replace math.h methods by optimized ones (fastfloor, fastsin...). -- Add foam to water. +- Replace terrain canvas editor by full sculpting editor. + => Add a generation dialog, with fixed resolution. + => Store local terrain modifications in fully dynamic canvas. + => Add map preview with editor area. + => Allow camera move and zoom. +- Get rid of noise dialogs, for simpler settings. - Finalize Preetham's model usage => Apply model to atmosphere (aerial perspective) => Find a proper model for night sky (maybe Shirley) - Keep skydome lights in cache for a render. - Add buttons to restore "auto" default values in tabs and dialogs (with several auto presets). - Clouds should keep distance to ground. +- Rethink the quality settings and detail smoothing in the distance. + => When quality setting is set to 10, add boost options + => Add detail boost (adds granularity) + => Add step boost (for marching algorithms) +- Waves noise should not change layers offsets each time a setting is changed (layers are reconstructed currently). - Add "hardness to light" and shadow control ("minimum lighting") to material. Technlogy Preview 3 : - Add logarithmic sliders for some float values. -- Replace terrain canvas editor by full sculpting editor. - => Add a generation dialog, with fixed resolution. - => Store local terrain modifications in fully dynamic canvas. - => Add map preview with editor area. - => Allow camera move and zoom. - Improve previews. => Add user markers on OSD. => Add areas marking. diff --git a/gui_qt/baseform.cpp b/gui_qt/baseform.cpp index 718b5ed..11e420a 100644 --- a/gui_qt/baseform.cpp +++ b/gui_qt/baseform.cpp @@ -120,6 +120,10 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget _button_apply->setIcon(QIcon("images/apply.png")); _button_apply->setEnabled(false); connect(_button_apply, SIGNAL(clicked()), this, SLOT(applyConfig())); + _button_preset = addButton(tr("Load preset")); + _button_preset->setIcon(QIcon("images/auto.png")); + _button_preset->hide(); + connect(_button_preset, SIGNAL(clicked()), this, SLOT(presetChoiceClicked())); _auto_update_previews = true; @@ -183,6 +187,16 @@ void BaseForm::configChangeEvent() } } +void BaseForm::autoPresetSelected(int) +{ + for (int i = 0; i < _inputs_list.size(); i++) + { + _inputs_list[i]->revert(); + } + updatePreviews(); + configChangeEvent(); +} + void BaseForm::revertConfig() { for (int i = 0; i < _inputs_list.size(); i++) @@ -322,6 +336,21 @@ void BaseForm::layerListChanged() _button_revert->setEnabled(changed); } +void BaseForm::presetChoiceClicked() +{ + bool ok; + QString item = QInputDialog::getItem(this, tr("Choose a preset"), tr("Preset settings : "), _preset_list, 0, false, &ok); + + if (ok && !item.isEmpty()) + { + int preset = _preset_list.indexOf(item); + if (preset >= 0) + { + autoPresetSelected(preset); + } + } +} + void BaseForm::addPreview(BasePreview* preview, QString label) { QLabel* label_widget; @@ -342,6 +371,12 @@ QPushButton* BaseForm::addButton(QString label) return button; } +void BaseForm::addAutoPreset(QString label) +{ + _preset_list.append(label); + _button_preset->show(); +} + BaseInput* BaseForm::addInput(BaseInput* input) { int row_height = 30; diff --git a/gui_qt/baseform.h b/gui_qt/baseform.h index a4dc393..154b16f 100644 --- a/gui_qt/baseform.h +++ b/gui_qt/baseform.h @@ -36,6 +36,7 @@ public slots: protected slots: virtual void configChangeEvent(); + virtual void autoPresetSelected(int preset); private slots: void rebuildLayerList(); @@ -45,10 +46,12 @@ private slots: void layerDownClicked(); void layerRenameClicked(); void layerListChanged(); + void presetChoiceClicked(); protected: void addPreview(BasePreview* preview, QString label); QPushButton* addButton(QString label); + void addAutoPreset(QString label); BaseInput* addInput(BaseInput* input); BaseInput* addInputInt(QString label, int* value, int min, int max, int small_step, int large_step); BaseInput* addInputDouble(QString label, double* value, double min, double max, double small_step, double large_step); @@ -83,6 +86,7 @@ private: QWidget* _buttons; QPushButton* _button_apply; QPushButton* _button_revert; + QPushButton* _button_preset; QWidget* _previews; QVector _previews_list; @@ -90,6 +94,8 @@ private: QVector _inputs_list; + QStringList _preset_list; + bool _with_layers; QComboBox* _layer_list; int _layer_count; diff --git a/gui_qt/formwater.cpp b/gui_qt/formwater.cpp index 9076fe6..53add78 100644 --- a/gui_qt/formwater.cpp +++ b/gui_qt/formwater.cpp @@ -206,12 +206,14 @@ private: FormWater::FormWater(QWidget *parent): BaseForm(parent) { + addAutoPreset(tr("Standard water")); + _definition = waterCreateDefinition(); previewCoverage = new PreviewWaterCoverage(this); previewColor = new PreviewWaterColor(this); - addPreview(previewCoverage, QString(tr("Coverage preview"))); - addPreview(previewColor, QString(tr("Rendered preview"))); + addPreview(previewCoverage, tr("Coverage preview")); + addPreview(previewColor, tr("Rendered preview")); addInputDouble(tr("Height"), &_definition.height, -10.0, 10.0, 0.1, 1.0); addInputMaterial(tr("Surface material"), &_definition.material); @@ -224,6 +226,8 @@ FormWater::FormWater(QWidget *parent): addInputDouble(tr("Waves height"), &_definition.waves_height, 0.0, 2.0, 0.02, 0.2); addInputDouble(tr("Waves detail"), &_definition.detail_height, 0.0, 0.3, 0.003, 0.03); addInputDouble(tr("Waves turbulence"), &_definition.turbulence, 0.0, 0.5, 0.005, 0.05); + addInputDouble(tr("Foam coverage"), &_definition.foam_coverage, 0.0, 1.0, 0.01, 0.1); + addInputMaterial(tr("Foam material"), &_definition.foam_material); revertConfig(); } @@ -245,3 +249,13 @@ void FormWater::configChangeEvent() waterValidateDefinition(&_definition); BaseForm::configChangeEvent(); } + +void FormWater::autoPresetSelected(int preset) +{ + if (preset == (int)WATER_PRESET_STD) + { + waterAutoPreset(&_definition, WATER_PRESET_STD); + } + BaseForm::autoPresetSelected(preset); +} + diff --git a/gui_qt/formwater.h b/gui_qt/formwater.h index 5bc2a9b..71ed80a 100644 --- a/gui_qt/formwater.h +++ b/gui_qt/formwater.h @@ -18,6 +18,7 @@ public slots: protected slots: virtual void configChangeEvent(); + virtual void autoPresetSelected(int preset); private: BasePreview* previewCoverage; diff --git a/images/auto.png b/images/auto.png new file mode 100644 index 0000000000000000000000000000000000000000..ca5c3bbf904bd73174b2a612e1376f79d4d5c334 GIT binary patch literal 4425 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 packWriteDouble(stream, &definition->detail_height); packWriteDouble(stream, &definition->turbulence); + + packWriteDouble(stream, &definition->foam_coverage); + materialSave(stream, &definition->foam_material); noiseSaveGenerator(stream, definition->_waves_noise); } @@ -43,6 +46,9 @@ void waterLoad(PackStream* stream, WaterDefinition* definition) packReadDouble(stream, &definition->detail_height); packReadDouble(stream, &definition->turbulence); + packReadDouble(stream, &definition->foam_coverage); + materialLoad(stream, &definition->foam_material); + noiseLoadGenerator(stream, definition->_waves_noise); waterValidateDefinition(definition); @@ -85,6 +91,12 @@ void waterAutoPreset(WaterDefinition* definition, WaterPreset preset) definition->waves_height = 1.0; definition->detail_height = 0.05; definition->turbulence = 0.3; + definition->foam_coverage = 0.4; + definition->foam_material.base.r = 0.8; + definition->foam_material.base.g = 0.8; + definition->foam_material.base.b = 0.8; + definition->foam_material.reflection = 0.2; + definition->foam_material.shininess = 1.5; } waterValidateDefinition(definition); @@ -126,11 +138,6 @@ static inline Vector3 _getNormal(WaterDefinition* definition, Vector3 base, doub Vector3 back, right; double x, z; - if (detail < 0.00001) - { - detail = 0.00001; - } - x = base.x; z = base.z; @@ -186,6 +193,9 @@ HeightInfo waterGetHeightInfo(WaterDefinition* definition) Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light) { double factor; + + UNUSED(renderer); + UNUSED(light_location); if (location.y < definition->height) { @@ -215,6 +225,67 @@ Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color li } } +static inline void _applyFoam(WaterDefinition* definition, Vector3 location, Vector3 normal, double detail, SurfaceMaterial* material) +{ + Color result = definition->foam_material.base; + double foam_factor, normal_diff, location_offset; + + location_offset = 2.0 * detail; + + foam_factor = 0.0; + location.x += location_offset; + normal_diff = 1.0 - v3Dot(normal, _getNormal(definition, location, detail)); + if (normal_diff > foam_factor) + { + foam_factor = normal_diff; + } + location.x -= location_offset * 2.0; + normal_diff = 1.0 - v3Dot(normal, _getNormal(definition, location, detail)); + if (normal_diff > foam_factor) + { + foam_factor = normal_diff; + } + location.x += location_offset; + location.z -= location_offset; + normal_diff = 1.0 - v3Dot(normal, _getNormal(definition, location, detail)); + if (normal_diff > foam_factor) + { + foam_factor = normal_diff; + } + location.z += location_offset * 2.0; + normal_diff = 1.0 - v3Dot(normal, _getNormal(definition, location, detail)); + if (normal_diff > foam_factor) + { + foam_factor = normal_diff; + } + + foam_factor *= 10.0; + if (foam_factor > 1.0) + { + foam_factor = 1.0; + } + + if (foam_factor <= 1.0 - definition->foam_coverage) + { + return; + } + foam_factor = (foam_factor - (1.0 - definition->foam_coverage)) * definition->foam_coverage; + + material->reflection = foam_factor * definition->foam_material.reflection + (1.0 - foam_factor) * material->reflection; + material->shininess = foam_factor * definition->foam_material.shininess + (1.0 - foam_factor) * material->shininess; + + /* TODO This should be configurable */ + if (foam_factor > 0.2) + { + result.a = 0.8; + } + else + { + result.a = 0.8 * (foam_factor / 0.2); + } + colorMask(&material->base, &result); +} + WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer, Vector3 location, Vector3 look) { WaterResult result; @@ -225,7 +296,11 @@ WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer, SurfaceMaterial material; double detail, depth; - detail = renderer->getPrecision(renderer, location); + detail = renderer->getPrecision(renderer, location) * 0.1; + if (detail < 0.00001) + { + detail = 0.00001; + } location.y = _getHeight(definition, location.x, location.z); result.location = location; @@ -252,14 +327,17 @@ WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer, color.g = definition->material.base.g * (1.0 - definition->transparency) + result.reflected.g * definition->reflection + result.refracted.g * definition->transparency; color.b = definition->material.base.b * (1.0 - definition->transparency) + result.reflected.b * definition->reflection + result.refracted.b * definition->transparency; color.a = 1.0; - + material = definition->material; material.base = color; + + _applyFoam(definition, location, normal, detail, &material); + renderer->getLightStatus(renderer, &light, location); color = renderer->applyLightStatus(renderer, &light, location, normal, material); color = renderer->applyAtmosphere(renderer, location, color); color = renderer->applyClouds(renderer, color, renderer->camera_location, location); - + result.base = definition->material.base; result.final = color; diff --git a/lib_paysages/water.h b/lib_paysages/water.h index 021d8f8..a136fa0 100644 --- a/lib_paysages/water.h +++ b/lib_paysages/water.h @@ -31,6 +31,9 @@ typedef struct double waves_height; double detail_height; + double foam_coverage; + SurfaceMaterial foam_material; + NoiseGenerator* _waves_noise; } WaterDefinition; @@ -40,6 +43,7 @@ typedef struct Color base; Color reflected; Color refracted; + Color foam; Color final; } WaterResult;