From 5ee717b68a0a566f60d769e01873eae131eb4f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sun, 20 Jan 2013 17:00:17 +0000 Subject: [PATCH] paysages : Lighting refactoring (WIP). git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@502 b1fd45b6-86a6-48da-8261-f70d1f35bdcc --- TODO | 13 +++- gui_qt/formwater.cpp | 40 ++++------ gui_qt/previewmaterial.cpp | 23 ++---- gui_qt/previewmaterial.h | 2 +- lib_paysages/atmosphere/bruneton.c | 2 + lib_paysages/atmosphere/main.c | 120 +++++------------------------ lib_paysages/tools/lighting.c | 15 ++-- lib_paysages/water.c | 2 +- 8 files changed, 66 insertions(+), 151 deletions(-) diff --git a/TODO b/TODO index 8d096b2..9ed0a40 100644 --- a/TODO +++ b/TODO @@ -5,7 +5,13 @@ Technology Preview 2 : => Add map preview with editor area. => Allow camera move and zoom. - Get rid of noise dialogs, for simpler settings. -- Apply HDR to 3D explorer. +- Finalize Bruneton's model + => Fix artifacts on aerial perspective + => Fix blue appearance at night +- Finalize lighting refactoring + => Restore water and cloud filters + => Restore cloud lighting + => Restore and improve skydome lighting - Apply Preetham's model usage => Convert to HDR rendering. => Apply model's aerial perspective. @@ -15,16 +21,17 @@ Technology Preview 2 : => Covering texture height should inpact terrain height. => Add texture shadowing. - Clouds should keep distance to ground. -- Add fresnel effect to specular lighting. -- Add "hardness to light" and shadow control ("minimum lighting") to material. - Waves noise should not change layers offsets each time a setting is changed (layers are reconstructed currently). - Fix rendering when inside a cloud layer, with other upper or lower layers. +- Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)). Technlogy Preview 3 : - Fully move layer management from BaseForm to BaseFormLayer. - Start vegetation system. - Allow render saving in HDR compatible format. - Add clouds to explorer with 3d textures. +- Add fresnel effect to specular lighting. +- Add "hardness to light" and shadow control ("minimum lighting") to material. - Start using OpenCL to optimize rendering. - Restore render progress. - Rethink the quality settings and detail smoothing in the distance. diff --git a/gui_qt/formwater.cpp b/gui_qt/formwater.cpp index e5151f3..d080121 100644 --- a/gui_qt/formwater.cpp +++ b/gui_qt/formwater.cpp @@ -93,30 +93,15 @@ class PreviewWaterColor:public BasePreview public: PreviewWaterColor(QWidget* parent):BasePreview(parent) { - LightDefinition light; - _background = 0; _lighting_enabled = false; _water = waterCreateDefinition(); - /*_lighting = lightingCreateDefinition(); - light.color = COLOR_WHITE; - light.direction.x = 0.0; - light.direction.y = -0.4794; - light.direction.z = 0.8776; - light.filtered = 0; - light.masked = 0; - light.reflection = 1.0; - lightingAddLight(&_lighting, light); - lightingValidateDefinition(&_lighting);*/ - _renderer = rendererCreate(); + _renderer->atmosphere->getLightingStatus = _getLightingStatus; _renderer->rayWalking = _rayWalking; - /*_renderer->getLightStatus = _getLightStatus; - _renderer->applyLightStatus = _applyLightStatus;*/ _renderer->customData[0] = &_water; - //_renderer->customData[1] = &_lighting; _renderer->customData[2] = this; configScaling(10.0, 1000.0, 10.0, 250.0); @@ -126,6 +111,7 @@ public: addToggle("light", tr("Lighting"), true); } int _background; + bool _lighting_enabled; protected: Color getColor(double x, double y) { @@ -180,8 +166,6 @@ protected: private: Renderer* _renderer; WaterDefinition _water; - //LightingDefinition _lighting; - bool _lighting_enabled; static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int, int, int, int) { @@ -218,21 +202,25 @@ private: return result; } - /*static Color _applyLightStatus(Renderer* renderer, LightStatus* status, Vector3 location, Vector3 normal, SurfaceMaterial material) + static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3, int) { - if (((PreviewWaterColor*)renderer->customData[2])->_lighting_enabled) + LightDefinition light; + PreviewWaterColor* preview = (PreviewWaterColor*)renderer->customData[2]; + light.color = COLOR_WHITE; + light.direction.x = 0.0; + light.direction.y = -0.4794; + light.direction.z = 0.8776; + light.altered = 0; + if (preview->_lighting_enabled) { - return lightingApplyStatusToSurface(renderer, status, location, normal, material); + light.reflection = 1.0; } else { - return material.base; + light.reflection = 0.0; } + lightingPushLight(status, &light); } - static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location) - { - lightingGetStatus((LightingDefinition*)renderer->customData[1], renderer, location, status); - }*/ }; /**************** Form ****************/ diff --git a/gui_qt/previewmaterial.cpp b/gui_qt/previewmaterial.cpp index f9a6549..535d2d8 100644 --- a/gui_qt/previewmaterial.cpp +++ b/gui_qt/previewmaterial.cpp @@ -11,19 +11,13 @@ SmallMaterialPreview::SmallMaterialPreview(QWidget* parent, SurfaceMaterial* material) : QWidget(parent) { - LightDefinition light; - - /*_lighting = lightingCreateDefinition(); - light.color = COLOR_WHITE; - light.direction.x = -0.5; - light.direction.y = -0.5; - light.direction.z = -0.5; - light.direction = v3Normalize(light.direction); - light.filtered = 0; - light.masked = 0; - light.reflection = 1.0; - lightingAddLight(&_lighting, light); - lightingValidateDefinition(&_lighting);*/ + _light.color = COLOR_WHITE; + _light.direction.x = -0.5; + _light.direction.y = -0.5; + _light.direction.z = -0.5; + _light.direction = v3Normalize(_light.direction); + _light.altered = 0; + _light.reflection = 1.0; _material = material; @@ -62,8 +56,7 @@ Color SmallMaterialPreview::getColor(double x, double y) } point = v3Normalize(point); - //color = lightingApplyToSurface(&_lighting, &_renderer, point, point, *_material); - color = COLOR_RED; + color = lightingApplyOneLight(&_light, _renderer->camera_location, point, point, _material); if (dist > 0.95) { color.a = (1.0 - dist) / 0.05; diff --git a/gui_qt/previewmaterial.h b/gui_qt/previewmaterial.h index a6479e4..4b963f4 100644 --- a/gui_qt/previewmaterial.h +++ b/gui_qt/previewmaterial.h @@ -19,7 +19,7 @@ protected: private: SurfaceMaterial* _material; - LightStatus* _light; + LightDefinition _light; Renderer* _renderer; }; diff --git a/lib_paysages/atmosphere/bruneton.c b/lib_paysages/atmosphere/bruneton.c index b1a2333..ae443fc 100644 --- a/lib_paysages/atmosphere/bruneton.c +++ b/lib_paysages/atmosphere/bruneton.c @@ -1190,6 +1190,8 @@ void brunetonInit() Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position) { + UNUSED(definition); + Vector3 x = {0.0, Rg + (max(eye.y, 0.0) + GROUND_OFFSET) * WORLD_SCALING, 0.0}; Vector3 v = v3Normalize(direction); Vector3 s = v3Normalize(v3Sub(sun_position, x)); diff --git a/lib_paysages/atmosphere/main.c b/lib_paysages/atmosphere/main.c index bd02782..e8d16e9 100644 --- a/lib_paysages/atmosphere/main.c +++ b/lib_paysages/atmosphere/main.c @@ -193,110 +193,32 @@ static Vector3 _getSunDirection(Renderer* renderer) return result; } -#if 0 -static inline void _addDomeLight(Renderer* renderer, LightDefinition* light, Vector3 direction, double factor) -{ - light->direction = v3Scale(direction, -1.0); - light->color = renderer->atmosphere->getSkyColor(renderer, direction); - light->color.r *= factor; - light->color.g *= factor; - light->color.b *= factor; - light->reflection = 0.0; - light->filtered = 0; - light->masked = 0; -} - -static int _getSkydomeLights(Renderer* renderer, LightDefinition* lights, int max_lights) -{ - AtmosphereRendererCache* cache = (AtmosphereRendererCache*)renderer->atmosphere->_internal_data; - AtmosphereDefinition* definition; - double sun_angle; - Vector3 sun_direction; - int nblights = 0; - - mutexAcquire(cache->lock); - if (cache->nblights < 0) - { - definition = renderer->atmosphere->definition; - - 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; - - /* TODO Moon light */ - - if (max_lights > MAX_SKYDOME_LIGHTS) - { - max_lights = MAX_SKYDOME_LIGHTS; - } - - if (max_lights > 0) - { - /* Direct light from the sun */ - cache->lights[0].direction = v3Scale(sun_direction, -1.0); - cache->lights[0].color = definition->sun_color; - cache->lights[0].reflection = 1.0; - cache->lights[0].filtered = 1; - cache->lights[0].masked = 1; - nblights = 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 = definition->dome_lighting / (double)samples; - - _addDomeLight(renderer, cache->lights + nblights, VECTOR_UP, factor); - nblights++; - samples--; - - if (samples >= 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(renderer, cache->lights + nblights, direction, factor); - nblights++; - } - } - } - } - - cache->nblights = nblights; - } - mutexRelease(cache->lock); - - memcpy(lights, cache->lights, sizeof(LightDefinition) * cache->nblights); - return cache->nblights; -} -#endif - static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque) { + LightDefinition light; + UNUSED(renderer); - UNUSED(status); UNUSED(normal); UNUSED(opaque); + + light.color.r = 0.8; + light.color.g = 0.8; + light.color.b = 0.8; + light.direction.x = -0.7; + light.direction.y = -0.7; + light.direction.z = -0.7; + light.altered = 0; + light.reflection = 0.0; + lightingPushLight(status, &light); + light.color.r = 0.3; + light.color.g = 0.31; + light.color.b = 0.34; + light.direction.x = 0.7; + light.direction.y = -0.7; + light.direction.z = 0.7; + light.altered = 0; + light.reflection = 0.0; + lightingPushLight(status, &light); } /******************** Renderer ********************/ diff --git a/lib_paysages/tools/lighting.c b/lib_paysages/tools/lighting.c index a6b83c5..276e6b9 100644 --- a/lib_paysages/tools/lighting.c +++ b/lib_paysages/tools/lighting.c @@ -134,7 +134,7 @@ Color lightingApplyOneLight(LightDefinition* light, Vector3 eye, Vector3 locatio Vector3 direction_inv; light_color = light->color; - direction_inv = v3Scale(light->direction, -1.0); + direction_inv = v3Scale(v3Normalize(light->direction), -1.0); normal_norm = v3Norm(normal); if (normal_norm > 1.0) @@ -146,7 +146,7 @@ Color lightingApplyOneLight(LightDefinition* light, Vector3 eye, Vector3 locatio result = COLOR_BLACK; /* diffused light */ - double diffuse = v3Dot(direction_inv, normal) / M_PI; + double diffuse = v3Dot(direction_inv, normal); if (diffuse > 0.0) { result.r += diffuse * material->base.r * light_color.r; @@ -162,10 +162,13 @@ Color lightingApplyOneLight(LightDefinition* light, Vector3 eye, Vector3 locatio double specular = v3Dot(reflect, view); if (specular > 0.0) { - specular = pow(specular, material->shininess) * material->reflection; - result.r += specular * light_color.r; - result.g += specular * light_color.g; - result.b += specular * light_color.b; + specular = pow(specular, material->shininess) * material->reflection * light->reflection; + if (specular > 0.0) + { + result.r += specular * light_color.r; + result.g += specular * light_color.g; + result.b += specular * light_color.b; + } } } diff --git a/lib_paysages/water.c b/lib_paysages/water.c index 65d6e48..81636f6 100644 --- a/lib_paysages/water.c +++ b/lib_paysages/water.c @@ -108,7 +108,7 @@ void waterAutoPreset(WaterDefinition* definition, WaterPreset preset) definition->depth_color.a = 1.0; definition->material.base.a = 1.0; - definition->material.reflection = 0.4; + definition->material.reflection = 1.0; definition->material.shininess = 16.0; definition->foam_material.base.r = 0.8; definition->foam_material.base.g = 0.8;