diff --git a/TODO b/TODO index c324494..f01c12e 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,6 @@ -- Create a 'scenery' module that will, for each component : - - Hold definitions - - Setup standard Renderer - - Regroup load/save/render (from auto) -- Merge all Quality and Environment, as one Renderer. -- No more _definition, _quality, _environment in components. -- All component methods become custom. - Refactor fog in a new 'atmosphere' module. - In GUI, revertConfig should lock the previews while reverting. - All Save and Load methods should have same signature : void ...Save(FILE*, ...*) - All noises should use the same entropy pool (saved separately), and avoid reallocs. - Remove all global variables (render_quality, render_width...), it should all be set in Renderer. +- Make multi-lights work, to restore lighting from skydome. diff --git a/lib_paysages/clouds.c b/lib_paysages/clouds.c index 9c6cf95..1837a10 100644 --- a/lib_paysages/clouds.c +++ b/lib_paysages/clouds.c @@ -409,57 +409,22 @@ static int _findSegments(CloudsLayerDefinition* definition, Renderer* renderer, return segment_count; } -/*static Color _lightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data) -{ - double inside_depth, total_depth; - CloudSegment segments[20]; - LightFilterData data; - - data = *((LightFilterData*)custom_data); - data.detail = (data.detail < 0.1) ? 0.1 : data.detail; - - // FIXME Dont hard-code max_total_length - _findSegments(data.definition, data.quality, location, direction_to_light, data.detail, 20, 50.0, 300.0, &inside_depth, &total_depth, segments); - - inside_depth *= 0.02; - if (inside_depth > 1.0) - { - inside_depth = 1.0; - } - - light.r = light.r * (1.0 - 0.2 * inside_depth); - light.g = light.g * (1.0 - 0.2 * inside_depth); - light.b = light.b * (1.0 - 0.2 * inside_depth); - - return light; -}*/ - static Color _applyLayerLighting(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 position, Color base, double detail) { - return base; - /*Vector3 normal; - ReceiverMaterial material; - LightingEnvironment lighting_environment; - LightFilterData data; + Vector3 normal; + SurfaceMaterial material; normal = v3Scale(_getNormal(definition, position, 1.0), 0.25); normal = v3Add(normal, v3Scale(_getNormal(definition, position, 0.5), 0.25)); normal = v3Add(normal, v3Scale(_getNormal(definition, position, 0.2), 0.25)); normal = v3Add(normal, v3Scale(_getNormal(definition, position, 0.1), 0.25)); - normal = v3Normalize(normal); - - data.definition = definition; - data.quality = quality; - data.detail = detail; - - lighting_environment.filter = _lightFilter; - lighting_environment.custom_data = &data; + normal = v3Scale(v3Normalize(normal), 0.1); material.base = base; material.reflection = 0.3; material.shininess = 0.1; - return lightingApplyCustom(position, normal, material, NULL, NULL, &lighting_environment);*/ + return renderer->applyLightingToSurface(renderer, position, normal, material); } Color cloudsGetLayerColor(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 start, Vector3 end) @@ -519,3 +484,35 @@ Color cloudsGetColor(CloudsDefinition* definition, Renderer* renderer, Vector3 s return result; } + +Color cloudsLayerFilterLight(CloudsLayerDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light) +{ + double inside_depth, total_depth; + CloudSegment segments[20]; + + _optimizeSearchLimits(definition, &location, &light_location); + + _findSegments(definition, renderer, location, direction_to_light, 0.1, 20, 50.0, v3Norm(v3Sub(light_location, location)), &inside_depth, &total_depth, segments); + + inside_depth *= 0.02; + if (inside_depth > 1.0) + { + inside_depth = 1.0; + } + + light.r = light.r * (1.0 - 0.2 * inside_depth); + light.g = light.g * (1.0 - 0.2 * inside_depth); + light.b = light.b * (1.0 - 0.2 * inside_depth); + + return light; +} + +Color cloudsFilterLight(CloudsDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light) +{ + int i; + for (i = 0; i < definition->nblayers; i++) + { + light = cloudsLayerFilterLight(definition->layers + i, renderer, light, location, light_location, direction_to_light); + } + return light; +} diff --git a/lib_paysages/clouds.h b/lib_paysages/clouds.h index a061d04..fb9dd1a 100644 --- a/lib_paysages/clouds.h +++ b/lib_paysages/clouds.h @@ -50,6 +50,8 @@ void cloudsDeleteLayer(CloudsDefinition* definition, int layer); Color cloudsGetLayerColor(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 start, Vector3 end); Color cloudsGetColor(CloudsDefinition* definition, Renderer* renderer, Vector3 start, Vector3 end); +Color cloudsLayerFilterLight(CloudsLayerDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light); +Color cloudsFilterLight(CloudsDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light); #ifdef __cplusplus } diff --git a/lib_paysages/lighting.c b/lib_paysages/lighting.c index 77edc64..1b4f591 100644 --- a/lib_paysages/lighting.c +++ b/lib_paysages/lighting.c @@ -137,21 +137,27 @@ void lightingDeleteLight(LightingDefinition* definition, int light) static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material) { Color result, light; - double diffuse, specular; + double diffuse, specular, normal_norm; Vector3 view, reflect, direction_inv; light = definition->color; direction_inv = v3Scale(definition->direction, -1.0); - light = renderer->filterLight(renderer, light, location, v3Add(location, direction_inv), direction_inv); + light = renderer->filterLight(renderer, light, location, v3Add(location, v3Scale(direction_inv, 1000.0)), direction_inv); + normal_norm = v3Norm(normal); + if (normal_norm > 1.0) + { + normal_norm = 1.0; + } normal = v3Normalize(normal); + view = v3Normalize(v3Sub(location, renderer->camera_location)); 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); - diffuse = diffuse * 0.5 + 0.5; + diffuse = (diffuse * 0.5 + 0.5); if (diffuse > 0.0) { if (material.shininess > 0.0) @@ -169,6 +175,9 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer, specular = 0.0; } + specular *= normal_norm; + diffuse = 1.0 - normal_norm + diffuse * normal_norm; + 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; diff --git a/lib_paysages/scenery.c b/lib_paysages/scenery.c index 926e6c2..f5217b9 100644 --- a/lib_paysages/scenery.c +++ b/lib_paysages/scenery.c @@ -191,14 +191,12 @@ void sceneryRenderSecondPass(Renderer* renderer) /******* Standard renderer *********/ static Color _filterLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light) { - Color result; - - result = waterLightFilter(&_water, renderer, light_color, at_location, light_location, direction_to_light); - result = terrainLightFilter(&_terrain, renderer, result, at_location, light_location, direction_to_light); + light_color = waterLightFilter(&_water, renderer, light_color, at_location, light_location, direction_to_light); + light_color = terrainLightFilter(&_terrain, renderer, light_color, at_location, light_location, direction_to_light); // TODO atmosphere filter - // TODO clouds filter + light_color = cloudsFilterLight(&_clouds, renderer, light_color, at_location, light_location, direction_to_light); - return result; + return light_color; } static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material) @@ -232,7 +230,7 @@ static Color _applyTextures(Renderer* renderer, Vector3 location, double precisi static Color _applyAtmosphere(Renderer* renderer, Vector3 location, Color base) { - return base; + return fogApplyToLocation(location, base); } static Color _applyClouds(Renderer* renderer, Color base, Vector3 start, Vector3 end)