Browse Source

Move atmosphere-related functions out of the astronomy system and into the atmosphere system

master
C. J. Howard 2 years ago
parent
commit
57b0c9ebe8
8 changed files with 197 additions and 176 deletions
  1. +27
    -24
      src/entity/components/atmosphere.hpp
  2. +9
    -26
      src/entity/systems/astronomy.cpp
  3. +59
    -31
      src/entity/systems/atmosphere.cpp
  4. +10
    -3
      src/entity/systems/atmosphere.hpp
  5. +1
    -0
      src/game/state/boot.cpp
  6. +56
    -58
      src/render/passes/sky-pass.cpp
  7. +18
    -21
      src/render/passes/sky-pass.hpp
  8. +17
    -13
      src/resources/entity-archetype-loader.cpp

+ 27
- 24
src/entity/components/atmosphere.hpp View File

@ -28,53 +28,56 @@ namespace component {
/// Atmosphere /// Atmosphere
struct atmosphere struct atmosphere
{ {
/// Altitude of the outer atmosphere, in meters.
double exosphere_altitude;
/// Elevation of the upper limit of the atmosphere, in meters.
double upper_limit;
/// Atmospheric index of refraction at sea level.
/// Index of refraction of air at sea level.
double index_of_refraction; double index_of_refraction;
/// Molar concentration of air at sea level, in mol/m-3.
double air_concentration;
/// Scale height of the exponential distribution of Rayleigh particles, in meters.
double rayleigh_scale_height;
/// Molecular density of Rayleigh particles at sea level. /// Molecular density of Rayleigh particles at sea level.
double rayleigh_density; double rayleigh_density;
/// (Dependent) Rayleigh scattering coefficients.
double3 rayleigh_scattering;
/// Scale height of the exponential distribution of Mie particles, in meters.
double mie_scale_height;
/// Molecular density of Mie particles at sea level. /// Molecular density of Mie particles at sea level.
double mie_density; double mie_density;
/// Rayleigh scale height, in meters.
double rayleigh_scale_height;
/// (Dependent) Mie scattering coefficient.
double mie_scattering;
/// Mie scale height, in meters.
double mie_scale_height;
/// (Dependent) Mie absorption coefficient.
double mie_absorption;
/// Mie phase function anisotropy factor. /// Mie phase function anisotropy factor.
double mie_anisotropy; double mie_anisotropy;
/// Airglow, in lux.
double airglow;
/// Molar concentration of air at sea level, in mol/m-3.
double air_concentration;
/// Concentration of ozone in the atmosphere, unitless.
double ozone_concentration;
/// Elevation of the lower limit of the ozone triangular distribution, in meters.
/// Elevation of the lower limit of the triangular distribution of ozone particles, in meters.
double ozone_lower_limit; double ozone_lower_limit;
/// Elevation of the upper limit of the ozone triangular distribution, in meters.
/// Elevation of the upper limit of the triangular distribution of ozone particles, in meters.
double ozone_upper_limit; double ozone_upper_limit;
/// Elevation of the mode of the ozone triangular distribution, in meters.
/// Elevation of the mode of the triangular distribution of ozone particles, in meters.
double ozone_mode; double ozone_mode;
/// (Dependent) Rayleigh scattering coefficients.
double3 rayleigh_scattering;
/// (Dependent) Mie scattering coefficients.
double3 mie_scattering;
/// Concentration of ozone in the atmosphere, unitless.
double ozone_concentration;
/// (Dependent) Ozone absorption coefficients. /// (Dependent) Ozone absorption coefficients.
double3 ozone_absorption; double3 ozone_absorption;
/// Airglow, in lux.
double airglow;
}; };
} // namespace component } // namespace component

+ 9
- 26
src/entity/systems/astronomy.cpp View File

@ -41,11 +41,11 @@ namespace entity {
namespace system { namespace system {
template <class T> template <class T>
math::vector3<T> transmittance(T depth_r, T depth_m, T depth_o, const math::vector3<T>& beta_r, const math::vector3<T>& beta_m, const math::vector3<T>& beta_o)
math::vector3<T> transmittance(T depth_r, T depth_m, T depth_o, const math::vector3<T>& extinction_r, T extinction_m, const math::vector3<T>& extinction_o)
{ {
math::vector3<T> transmittance_r = beta_r * depth_r;
math::vector3<T> transmittance_m = beta_m * (T(10)/T(9)) * depth_m;
math::vector3<T> transmittance_o = beta_o * depth_o;
math::vector3<T> transmittance_r = extinction_r * depth_r;
math::vector3<T> transmittance_m = math::vector3<T>{extinction_m, extinction_m, extinction_m} * depth_m;
math::vector3<T> transmittance_o = extinction_o * depth_o;
math::vector3<T> t = transmittance_r + transmittance_m + transmittance_o; math::vector3<T> t = transmittance_r + transmittance_m + transmittance_o;
t.x = std::exp(-t.x); t.x = std::exp(-t.x);
@ -225,7 +225,7 @@ void astronomy::update(double t, double dt)
geom::sphere<double> exosphere; geom::sphere<double> exosphere;
exosphere.center = {0, 0, 0}; exosphere.center = {0, 0, 0};
exosphere.radius = reference_body.radius + reference_atmosphere.exosphere_altitude;
exosphere.radius = reference_body.radius + reference_atmosphere.upper_limit;
auto intersection_result = geom::ray_sphere_intersection(sample_ray, exosphere); auto intersection_result = geom::ray_sphere_intersection(sample_ray, exosphere);
@ -238,7 +238,7 @@ void astronomy::update(double t, double dt)
double optical_depth_m = physics::gas::atmosphere::optical_depth_exp(sample_start, sample_end, reference_body.radius, reference_atmosphere.mie_scale_height, 16); double optical_depth_m = physics::gas::atmosphere::optical_depth_exp(sample_start, sample_end, reference_body.radius, reference_atmosphere.mie_scale_height, 16);
double optical_depth_o = physics::gas::atmosphere::optical_depth_tri(sample_start, sample_end, reference_body.radius, reference_atmosphere.ozone_lower_limit, reference_atmosphere.ozone_upper_limit, reference_atmosphere.ozone_mode, 16); double optical_depth_o = physics::gas::atmosphere::optical_depth_tri(sample_start, sample_end, reference_body.radius, reference_atmosphere.ozone_lower_limit, reference_atmosphere.ozone_upper_limit, reference_atmosphere.ozone_mode, 16);
atmospheric_transmittance = transmittance(optical_depth_r, optical_depth_m, optical_depth_o, reference_atmosphere.rayleigh_scattering, reference_atmosphere.mie_scattering, reference_atmosphere.ozone_absorption);
atmospheric_transmittance = transmittance(optical_depth_r, optical_depth_m, optical_depth_o, reference_atmosphere.rayleigh_scattering, reference_atmosphere.mie_scattering + reference_atmosphere.mie_absorption, reference_atmosphere.ozone_absorption);
} }
// Add airglow to sky light illuminance // Add airglow to sky light illuminance
@ -411,27 +411,10 @@ void astronomy::update(double t, double dt)
} }
); );
// Upload observer altitude to sky pass
sky_pass->set_observer_altitude(observer_location[0]);
// Upload observer elevation to sky pass
sky_pass->set_observer_elevation(observer_location[0]);
// Upload atmosphere params to sky pass
if (registry.has<entity::component::atmosphere>(reference_entity))
{
const entity::component::atmosphere& reference_atmosphere = registry.get<entity::component::atmosphere>(reference_entity);
sky_pass->set_particle_distributions
(
static_cast<float>(reference_atmosphere.rayleigh_scale_height),
static_cast<float>(reference_atmosphere.mie_scale_height),
static_cast<float>(reference_atmosphere.ozone_lower_limit),
static_cast<float>(reference_atmosphere.ozone_upper_limit),
static_cast<float>(reference_atmosphere.ozone_mode)
);
sky_pass->set_scattering_coefficients(math::type_cast<float>(reference_atmosphere.rayleigh_scattering), math::type_cast<float>(reference_atmosphere.mie_scattering));
sky_pass->set_mie_anisotropy(reference_atmosphere.mie_anisotropy);
sky_pass->set_absorption_coefficients(math::type_cast<float>(reference_atmosphere.ozone_absorption));
sky_pass->set_atmosphere_radii(reference_body.radius, reference_body.radius + reference_atmosphere.exosphere_altitude);
}
sky_pass->set_planet_radius(static_cast<float>(reference_body.radius));
} }
// Auto-exposure // Auto-exposure

+ 59
- 31
src/entity/systems/atmosphere.cpp View File

@ -18,8 +18,8 @@
*/ */
#include "entity/systems/atmosphere.hpp" #include "entity/systems/atmosphere.hpp"
#include "physics/gas/ozone.hpp"
#include "physics/gas/atmosphere.hpp" #include "physics/gas/atmosphere.hpp"
#include "physics/gas/ozone.hpp"
#include "physics/number-density.hpp" #include "physics/number-density.hpp"
#include "color/srgb.hpp" #include "color/srgb.hpp"
@ -29,10 +29,13 @@ namespace system {
atmosphere::atmosphere(entity::registry& registry): atmosphere::atmosphere(entity::registry& registry):
updatable(registry), updatable(registry),
rgb_wavelengths{0, 0, 0}, rgb_wavelengths{0, 0, 0},
rgb_ozone_cross_sections{0, 0, 0}
rgb_ozone_cross_sections{0, 0, 0},
atmosphere_component(nullptr),
sky_pass(nullptr)
{ {
registry.on_construct<entity::component::atmosphere>().connect<&atmosphere::on_atmosphere_construct>(this); registry.on_construct<entity::component::atmosphere>().connect<&atmosphere::on_atmosphere_construct>(this);
registry.on_replace<entity::component::atmosphere>().connect<&atmosphere::on_atmosphere_replace>(this); registry.on_replace<entity::component::atmosphere>().connect<&atmosphere::on_atmosphere_replace>(this);
registry.on_destroy<entity::component::atmosphere>().connect<&atmosphere::on_atmosphere_destroy>(this);
} }
void atmosphere::update(double t, double dt) void atmosphere::update(double t, double dt)
@ -41,67 +44,92 @@ void atmosphere::update(double t, double dt)
void atmosphere::set_rgb_wavelengths(const double3& wavelengths) void atmosphere::set_rgb_wavelengths(const double3& wavelengths)
{ {
rgb_wavelengths = wavelengths; rgb_wavelengths = wavelengths;
atmosphere_modified();
} }
void atmosphere::set_rgb_ozone_cross_sections(const double3& cross_sections) void atmosphere::set_rgb_ozone_cross_sections(const double3& cross_sections)
{ {
rgb_ozone_cross_sections = cross_sections; rgb_ozone_cross_sections = cross_sections;
atmosphere_modified();
}
void atmosphere::set_sky_pass(::render::sky_pass* pass)
{
sky_pass = pass;
update_sky_pass();
} }
void atmosphere::update_coefficients(entity::id entity_id)
void atmosphere::atmosphere_modified()
{ {
// Abort if entity has no atmosphere component
if (!registry.has<component::atmosphere>(entity_id))
if (!atmosphere_component)
return; return;
// Get atmosphere component of the entity // Get atmosphere component of the entity
component::atmosphere& atmosphere = registry.get<component::atmosphere>(entity_id);
// Calculate polarization factors
const double rayleigh_polarization = physics::gas::atmosphere::polarization(atmosphere.index_of_refraction, atmosphere.rayleigh_density);
const double mie_polarization = physics::gas::atmosphere::polarization(atmosphere.index_of_refraction, atmosphere.mie_density);
entity::component::atmosphere& component = *atmosphere_component;
// Calculate Rayleigh scattering coefficients for sRGB wavelengths // Calculate Rayleigh scattering coefficients for sRGB wavelengths
const double rayleigh_polarization = physics::gas::atmosphere::polarization(component.index_of_refraction, component.rayleigh_density);
const double3 rayleigh_scattering_srgb = const double3 rayleigh_scattering_srgb =
{ {
physics::gas::atmosphere::scattering_rayleigh(rgb_wavelengths.x, atmosphere.rayleigh_density, rayleigh_polarization),
physics::gas::atmosphere::scattering_rayleigh(rgb_wavelengths.y, atmosphere.rayleigh_density, rayleigh_polarization),
physics::gas::atmosphere::scattering_rayleigh(rgb_wavelengths.z, atmosphere.rayleigh_density, rayleigh_polarization)
physics::gas::atmosphere::scattering_rayleigh(rgb_wavelengths.x, component.rayleigh_density, rayleigh_polarization),
physics::gas::atmosphere::scattering_rayleigh(rgb_wavelengths.y, component.rayleigh_density, rayleigh_polarization),
physics::gas::atmosphere::scattering_rayleigh(rgb_wavelengths.z, component.rayleigh_density, rayleigh_polarization)
}; };
// Transform Rayleigh scattering coefficients from sRGB to ACEScg // Transform Rayleigh scattering coefficients from sRGB to ACEScg
atmosphere.rayleigh_scattering = color::srgb::to_acescg(rayleigh_scattering_srgb);
component.rayleigh_scattering = color::srgb::to_acescg(rayleigh_scattering_srgb);
// Calculate Mie scattering coefficients
const double mie_scattering = physics::gas::atmosphere::scattering_mie(atmosphere.mie_density, mie_polarization);
atmosphere.mie_scattering =
{
mie_scattering,
mie_scattering,
mie_scattering
};
// Calculate Mie scattering coefficient
const double mie_polarization = physics::gas::atmosphere::polarization(component.index_of_refraction, component.mie_density);
component.mie_scattering = physics::gas::atmosphere::scattering_mie(component.mie_density, mie_polarization);
// Calculate Mie absorption coefficient
component.mie_absorption = physics::gas::atmosphere::absorption_mie(component.mie_scattering);
// Calculate ozone absorption coefficients for sRGB wavelengths // Calculate ozone absorption coefficients for sRGB wavelengths
const double n_air = physics::number_density(atmosphere.air_concentration);
const double air_number_density = physics::number_density(component.air_concentration);
const double3 ozone_absorption_srgb = const double3 ozone_absorption_srgb =
{ {
physics::gas::ozone::absorption(rgb_ozone_cross_sections.x, n_air, atmosphere.ozone_concentration),
physics::gas::ozone::absorption(rgb_ozone_cross_sections.y, n_air, atmosphere.ozone_concentration),
physics::gas::ozone::absorption(rgb_ozone_cross_sections.z, n_air, atmosphere.ozone_concentration)
physics::gas::ozone::absorption(rgb_ozone_cross_sections.x, air_number_density, component.ozone_concentration),
physics::gas::ozone::absorption(rgb_ozone_cross_sections.y, air_number_density, component.ozone_concentration),
physics::gas::ozone::absorption(rgb_ozone_cross_sections.z, air_number_density, component.ozone_concentration)
}; };
// Transform ozone absorption coefficients from sRGB to ACEScg // Transform ozone absorption coefficients from sRGB to ACEScg
atmosphere.ozone_absorption = color::srgb::to_acescg(ozone_absorption_srgb);
component.ozone_absorption = color::srgb::to_acescg(ozone_absorption_srgb);
// Pass atmosphere parameters to sky pass
update_sky_pass();
}
void atmosphere::update_sky_pass()
{
if (!sky_pass || !atmosphere_component)
return;
const entity::component::atmosphere& component = *atmosphere_component;
sky_pass->set_atmosphere_upper_limit(static_cast<float>(component.upper_limit));
sky_pass->set_rayleigh_parameters(static_cast<float>(component.rayleigh_scale_height), math::type_cast<float>(component.rayleigh_scattering));
sky_pass->set_mie_parameters(static_cast<float>(component.mie_scale_height), static_cast<float>(component.mie_scattering), static_cast<float>(component.mie_absorption), static_cast<float>(component.mie_anisotropy));
sky_pass->set_ozone_parameters(static_cast<float>(component.ozone_lower_limit), static_cast<float>(component.ozone_upper_limit), static_cast<float>(component.ozone_mode), math::type_cast<float>(component.ozone_absorption));
}
void atmosphere::on_atmosphere_construct(entity::registry& registry, entity::id entity_id, entity::component::atmosphere& component)
{
atmosphere_component = &component;
atmosphere_modified();
} }
void atmosphere::on_atmosphere_construct(entity::registry& registry, entity::id entity_id, entity::component::atmosphere& atmosphere)
void atmosphere::on_atmosphere_replace(entity::registry& registry, entity::id entity_id, entity::component::atmosphere& component)
{ {
update_coefficients(entity_id);
atmosphere_component = &component;
atmosphere_modified();
} }
void atmosphere::on_atmosphere_replace(entity::registry& registry, entity::id entity_id, entity::component::atmosphere& atmosphere)
void atmosphere::on_atmosphere_destroy(entity::registry& registry, entity::id entity_id)
{ {
update_coefficients(entity_id);
atmosphere_component = nullptr;
} }
} // namespace system } // namespace system

+ 10
- 3
src/entity/systems/atmosphere.hpp View File

@ -24,6 +24,7 @@
#include "entity/id.hpp" #include "entity/id.hpp"
#include "utility/fundamental-types.hpp" #include "utility/fundamental-types.hpp"
#include "entity/components/atmosphere.hpp" #include "entity/components/atmosphere.hpp"
#include "render/passes/sky-pass.hpp"
namespace entity { namespace entity {
namespace system { namespace system {
@ -53,14 +54,20 @@ public:
*/ */
void set_rgb_ozone_cross_sections(const double3& cross_sections); void set_rgb_ozone_cross_sections(const double3& cross_sections);
void set_sky_pass(::render::sky_pass* pass);
private: private:
void update_coefficients(entity::id entity_id);
void atmosphere_modified();
void update_sky_pass();
void on_atmosphere_construct(entity::registry& registry, entity::id entity_id, entity::component::atmosphere& atmosphere);
void on_atmosphere_replace(entity::registry& registry, entity::id entity_id, entity::component::atmosphere& atmosphere);
void on_atmosphere_construct(entity::registry& registry, entity::id entity_id, entity::component::atmosphere& component);
void on_atmosphere_replace(entity::registry& registry, entity::id entity_id, entity::component::atmosphere& component);
void on_atmosphere_destroy(entity::registry& registry, entity::id entity_id);
double3 rgb_wavelengths; double3 rgb_wavelengths;
double3 rgb_ozone_cross_sections; double3 rgb_ozone_cross_sections;
entity::component::atmosphere* atmosphere_component;
::render::sky_pass* sky_pass;
}; };
} // namespace system } // namespace system

+ 1
- 0
src/game/state/boot.cpp View File

@ -909,6 +909,7 @@ void boot::setup_systems()
ctx.atmosphere_system = new entity::system::atmosphere(*ctx.entity_registry); ctx.atmosphere_system = new entity::system::atmosphere(*ctx.entity_registry);
ctx.atmosphere_system->set_rgb_wavelengths(rgb_wavelengths_m); ctx.atmosphere_system->set_rgb_wavelengths(rgb_wavelengths_m);
ctx.atmosphere_system->set_rgb_ozone_cross_sections(rgb_ozone_cross_sections_293k); ctx.atmosphere_system->set_rgb_ozone_cross_sections(rgb_ozone_cross_sections_293k);
ctx.atmosphere_system->set_sky_pass(ctx.sky_pass);
// Setup astronomy system // Setup astronomy system
ctx.astronomy_system = new entity::system::astronomy(*ctx.entity_registry); ctx.astronomy_system = new entity::system::astronomy(*ctx.entity_registry);

+ 56
- 58
src/render/passes/sky-pass.cpp View File

@ -68,7 +68,7 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe
clouds_model_vao(nullptr), clouds_model_vao(nullptr),
cloud_material(nullptr), cloud_material(nullptr),
cloud_shader_program(nullptr), cloud_shader_program(nullptr),
observer_altitude_tween(0.0f, math::lerp<float, float>),
observer_elevation_tween(0.0f, math::lerp<float, float>),
sun_position_tween(float3{1.0f, 0.0f, 0.0f}, math::lerp<float3, float>), sun_position_tween(float3{1.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
sun_luminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>), sun_luminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
sun_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>), sun_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
@ -113,8 +113,8 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
float4x4 view_projection = projection * view; float4x4 view_projection = projection * view;
float4x4 model_view_projection = projection * model_view; float4x4 model_view_projection = projection * model_view;
// Interpolate observer altitude
float observer_altitude = observer_altitude_tween.interpolate(ctx.alpha);
// Interpolate observer elevation
float observer_elevation = observer_elevation_tween.interpolate(ctx.alpha);
// Construct tweened ICRF to EUS transformation // Construct tweened ICRF to EUS transformation
math::transformation::se3<float> icrf_to_eus = math::transformation::se3<float> icrf_to_eus =
@ -147,33 +147,26 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
time_input->upload(ctx.t); time_input->upload(ctx.t);
if (exposure_input) if (exposure_input)
exposure_input->upload(ctx.exposure); exposure_input->upload(ctx.exposure);
if (observer_altitude_input)
observer_altitude_input->upload(observer_altitude);
if (sun_direction_input) if (sun_direction_input)
sun_direction_input->upload(sun_direction); sun_direction_input->upload(sun_direction);
if (sun_angular_radius_input)
sun_angular_radius_input->upload(sun_angular_radius * magnification);
if (sun_luminance_input) if (sun_luminance_input)
sun_luminance_input->upload(sun_luminance); sun_luminance_input->upload(sun_luminance);
if (sun_illuminance_input) if (sun_illuminance_input)
sun_illuminance_input->upload(sun_illuminance); sun_illuminance_input->upload(sun_illuminance);
if (distribution_rm_input)
distribution_rm_input->upload(distribution_rm);
if (distribution_o_input)
distribution_o_input->upload(distribution_o);
if (rayleigh_scattering_input)
rayleigh_scattering_input->upload(rayleigh_scattering);
if (mie_scattering_input)
mie_scattering_input->upload(mie_scattering);
if (mie_anisotropy_input)
mie_anisotropy_input->upload(mie_anisotropy);
if (ozone_absorption_input)
ozone_absorption_input->upload(ozone_absorption);
if (sun_angular_radius_input)
sun_angular_radius_input->upload(sun_angular_radius * magnification);
if (atmosphere_radii_input) if (atmosphere_radii_input)
atmosphere_radii_input->upload(atmosphere_radii); atmosphere_radii_input->upload(atmosphere_radii);
if (observer_elevation_input)
observer_elevation_input->upload(observer_elevation);
if (rayleigh_parameters_input)
rayleigh_parameters_input->upload(rayleigh_parameters);
if (mie_parameters_input)
mie_parameters_input->upload(mie_parameters);
if (ozone_distribution_input)
ozone_distribution_input->upload(ozone_distribution);
if (ozone_absorption_input)
ozone_absorption_input->upload(ozone_absorption);
sky_material->upload(ctx.alpha); sky_material->upload(ctx.alpha);
@ -296,20 +289,17 @@ void sky_pass::set_sky_model(const model* model)
mouse_input = sky_shader_program->get_input("mouse"); mouse_input = sky_shader_program->get_input("mouse");
resolution_input = sky_shader_program->get_input("resolution"); resolution_input = sky_shader_program->get_input("resolution");
time_input = sky_shader_program->get_input("time"); time_input = sky_shader_program->get_input("time");
exposure_input = sky_shader_program->get_input("camera.exposure");
observer_altitude_input = sky_shader_program->get_input("observer_altitude");
exposure_input = sky_shader_program->get_input("camera.exposure");
sun_direction_input = sky_shader_program->get_input("sun_direction"); sun_direction_input = sky_shader_program->get_input("sun_direction");
sun_luminance_input = sky_shader_program->get_input("sun_luminance"); sun_luminance_input = sky_shader_program->get_input("sun_luminance");
sun_illuminance_input = sky_shader_program->get_input("sun_illuminance"); sun_illuminance_input = sky_shader_program->get_input("sun_illuminance");
sun_angular_radius_input = sky_shader_program->get_input("sun_angular_radius"); sun_angular_radius_input = sky_shader_program->get_input("sun_angular_radius");
distribution_rm_input = sky_shader_program->get_input("distribution_rm");
distribution_o_input = sky_shader_program->get_input("distribution_o");
rayleigh_scattering_input = sky_shader_program->get_input("rayleigh_scattering");
mie_scattering_input = sky_shader_program->get_input("mie_scattering");
mie_anisotropy_input = sky_shader_program->get_input("mie_anisotropy");
ozone_absorption_input = sky_shader_program->get_input("ozone_absorption");
atmosphere_radii_input = sky_shader_program->get_input("atmosphere_radii"); atmosphere_radii_input = sky_shader_program->get_input("atmosphere_radii");
observer_elevation_input = sky_shader_program->get_input("observer_elevation");
rayleigh_parameters_input = sky_shader_program->get_input("rayleigh_parameters");
mie_parameters_input = sky_shader_program->get_input("mie_parameters");
ozone_distribution_input = sky_shader_program->get_input("ozone_distribution");
ozone_absorption_input = sky_shader_program->get_input("ozone_absorption");
} }
} }
} }
@ -434,7 +424,7 @@ void sky_pass::set_clouds_model(const model* model)
void sky_pass::update_tweens() void sky_pass::update_tweens()
{ {
observer_altitude_tween.update();
observer_elevation_tween.update();
sun_position_tween.update(); sun_position_tween.update();
sun_luminance_tween.update(); sun_luminance_tween.update();
sun_illuminance_tween.update(); sun_illuminance_tween.update();
@ -481,48 +471,56 @@ void sky_pass::set_sun_angular_radius(float radius)
sun_angular_radius = radius; sun_angular_radius = radius;
} }
void sky_pass::set_observer_altitude(float altitude)
void sky_pass::set_planet_radius(float radius)
{ {
observer_altitude_tween[1] = altitude;
atmosphere_radii.x = radius;
atmosphere_radii.y = atmosphere_radii.x + atmosphere_upper_limit;
atmosphere_radii.z = atmosphere_radii.y * atmosphere_radii.y;
} }
void sky_pass::set_particle_distributions(float rayleigh_scale_height, float mie_scale_height, float ozone_lower_limit, float ozone_upper_limit, float ozone_mode)
void sky_pass::set_atmosphere_upper_limit(float limit)
{ {
distribution_rm =
{
-1.0f / rayleigh_scale_height,
-1.0f / mie_scale_height
};
distribution_o =
{
1.0f / (ozone_lower_limit - ozone_mode),
1.0f / (ozone_upper_limit - ozone_mode),
ozone_mode
};
atmosphere_upper_limit = limit;
atmosphere_radii.y = atmosphere_radii.x + atmosphere_upper_limit;
atmosphere_radii.z = atmosphere_radii.y * atmosphere_radii.y;
} }
void sky_pass::set_scattering_coefficients(const float3& r, const float3& m)
void sky_pass::set_observer_elevation(float elevation)
{ {
rayleigh_scattering = r;
mie_scattering = m;
observer_elevation_tween[1] = elevation;
} }
void sky_pass::set_mie_anisotropy(float g)
void sky_pass::set_rayleigh_parameters(float scale_height, const float3& scattering)
{ {
mie_anisotropy = {g, g * g};
rayleigh_parameters =
{
-1.0f / scale_height,
scattering.x,
scattering.y,
scattering.z
};
} }
void sky_pass::set_absorption_coefficients(const float3& o)
void sky_pass::set_mie_parameters(float scale_height, float scattering, float absorption, float anisotropy)
{ {
ozone_absorption = o;
mie_parameters =
{
-1.0f / scale_height,
scattering,
absorption,
anisotropy
};
} }
void sky_pass::set_atmosphere_radii(float inner, float outer)
void sky_pass::set_ozone_parameters(float lower_limit, float upper_limit, float mode, const float3& absorption)
{ {
atmosphere_radii.x = inner;
atmosphere_radii.y = outer;
atmosphere_radii.z = outer * outer;
ozone_distribution =
{
1.0f / (lower_limit - mode),
1.0f / (upper_limit - mode),
mode
};
ozone_absorption = absorption;
} }
void sky_pass::set_moon_position(const float3& position) void sky_pass::set_moon_position(const float3& position)

+ 18
- 21
src/render/passes/sky-pass.hpp View File

@ -68,12 +68,12 @@ public:
void set_sun_luminance(const float3& luminance); void set_sun_luminance(const float3& luminance);
void set_sun_illuminance(const float3& illuminance); void set_sun_illuminance(const float3& illuminance);
void set_sun_angular_radius(float radius); void set_sun_angular_radius(float radius);
void set_observer_altitude(float altitude);
void set_scattering_coefficients(const float3& r, const float3& m);
void set_mie_anisotropy(float g);
void set_absorption_coefficients(const float3& o);
void set_atmosphere_radii(float inner, float outer);
void set_particle_distributions(float rayleigh_scale_height, float mie_scale_height, float ozone_lower_limit, float ozone_upper_limit, float ozone_mode);
void set_planet_radius(float radius);
void set_atmosphere_upper_limit(float limit);
void set_observer_elevation(float elevation);
void set_rayleigh_parameters(float scale_height, const float3& scattering);
void set_mie_parameters(float scale_height, float scattering, float absorption, float anisotropy);
void set_ozone_parameters(float lower_limit, float upper_limit, float mode, const float3& absorption);
void set_moon_position(const float3& position); void set_moon_position(const float3& position);
void set_moon_rotation(const math::quaternion<float>& rotation); void set_moon_rotation(const math::quaternion<float>& rotation);
@ -92,19 +92,16 @@ private:
const gl::shader_input* resolution_input; const gl::shader_input* resolution_input;
const gl::shader_input* time_input; const gl::shader_input* time_input;
const gl::shader_input* exposure_input; const gl::shader_input* exposure_input;
const gl::shader_input* observer_altitude_input;
const gl::shader_input* sun_direction_input; const gl::shader_input* sun_direction_input;
const gl::shader_input* sun_luminance_input; const gl::shader_input* sun_luminance_input;
const gl::shader_input* sun_illuminance_input; const gl::shader_input* sun_illuminance_input;
const gl::shader_input* sun_angular_radius_input; const gl::shader_input* sun_angular_radius_input;
const gl::shader_input* distribution_rm_input;
const gl::shader_input* distribution_o_input;
const gl::shader_input* rayleigh_scattering_input;
const gl::shader_input* mie_scattering_input;
const gl::shader_input* mie_anisotropy_input;
const gl::shader_input* ozone_absorption_input;
const gl::shader_input* atmosphere_radii_input; const gl::shader_input* atmosphere_radii_input;
const gl::shader_input* observer_elevation_input;
const gl::shader_input* rayleigh_parameters_input;
const gl::shader_input* mie_parameters_input;
const gl::shader_input* ozone_distribution_input;
const gl::shader_input* ozone_absorption_input;
gl::shader_program* moon_shader_program; gl::shader_program* moon_shader_program;
const gl::shader_input* moon_model_input; const gl::shader_input* moon_model_input;
@ -161,7 +158,7 @@ private:
const gl::texture_2d* sky_gradient2; const gl::texture_2d* sky_gradient2;
float2 mouse_position; float2 mouse_position;
tween<float> observer_altitude_tween;
tween<float> observer_elevation_tween;
tween<float3> sun_position_tween; tween<float3> sun_position_tween;
tween<float3> sun_luminance_tween; tween<float3> sun_luminance_tween;
tween<float3> sun_illuminance_tween; tween<float3> sun_illuminance_tween;
@ -177,13 +174,13 @@ private:
tween<float3> moon_planetlight_illuminance_tween; tween<float3> moon_planetlight_illuminance_tween;
float sun_angular_radius; float sun_angular_radius;
float3 rayleigh_scattering;
float3 mie_scattering;
float2 mie_anisotropy;
float3 ozone_absorption;
float atmosphere_upper_limit;
float3 atmosphere_radii; float3 atmosphere_radii;
float2 distribution_rm;
float3 distribution_o;
float observer_elevation;
float4 rayleigh_parameters;
float4 mie_parameters;
float3 ozone_distribution;
float3 ozone_absorption;
float magnification; float magnification;
}; };

+ 17
- 13
src/resources/entity-archetype-loader.cpp View File

@ -40,33 +40,37 @@ static bool load_component_atmosphere(entity::archetype& archetype, const json&
{ {
entity::component::atmosphere component; entity::component::atmosphere component;
if (element.contains("exosphere_altitude"))
component.exosphere_altitude = element["exosphere_altitude"].get<double>();
if (element.contains("upper_limit"))
component.upper_limit = element["upper_limit"].get<double>();
if (element.contains("index_of_refraction")) if (element.contains("index_of_refraction"))
component.index_of_refraction = element["index_of_refraction"].get<double>(); component.index_of_refraction = element["index_of_refraction"].get<double>();
if (element.contains("rayleigh_density"))
component.rayleigh_density = element["rayleigh_density"].get<double>();
if (element.contains("mie_density"))
component.mie_density = element["mie_density"].get<double>();
if (element.contains("air_concentration"))
component.air_concentration = element["air_concentration"].get<double>();
if (element.contains("rayleigh_scale_height")) if (element.contains("rayleigh_scale_height"))
component.rayleigh_scale_height = element["rayleigh_scale_height"].get<double>(); component.rayleigh_scale_height = element["rayleigh_scale_height"].get<double>();
if (element.contains("rayleigh_density"))
component.rayleigh_density = element["rayleigh_density"].get<double>();
if (element.contains("mie_scale_height")) if (element.contains("mie_scale_height"))
component.mie_scale_height = element["mie_scale_height"].get<double>(); component.mie_scale_height = element["mie_scale_height"].get<double>();
if (element.contains("mie_density"))
component.mie_density = element["mie_density"].get<double>();
if (element.contains("mie_anisotropy")) if (element.contains("mie_anisotropy"))
component.mie_anisotropy = element["mie_anisotropy"].get<double>(); component.mie_anisotropy = element["mie_anisotropy"].get<double>();
if (element.contains("airglow"))
component.airglow = element["airglow"].get<double>();
if (element.contains("air_concentration"))
component.air_concentration = element["air_concentration"].get<double>();
if (element.contains("ozone_concentration"))
component.ozone_concentration = element["ozone_concentration"].get<double>();
if (element.contains("ozone_lower_limit")) if (element.contains("ozone_lower_limit"))
component.ozone_lower_limit = element["ozone_lower_limit"].get<double>(); component.ozone_lower_limit = element["ozone_lower_limit"].get<double>();
if (element.contains("ozone_upper_limit")) if (element.contains("ozone_upper_limit"))
component.ozone_upper_limit = element["ozone_upper_limit"].get<double>(); component.ozone_upper_limit = element["ozone_upper_limit"].get<double>();
if (element.contains("ozone_mode")) if (element.contains("ozone_mode"))
component.ozone_mode = element["ozone_mode"].get<double>(); component.ozone_mode = element["ozone_mode"].get<double>();
if (element.contains("ozone_concentration"))
component.ozone_concentration = element["ozone_concentration"].get<double>();
if (element.contains("airglow"))
component.airglow = element["airglow"].get<double>();
archetype.set<entity::component::atmosphere>(component); archetype.set<entity::component::atmosphere>(component);
return true; return true;

Loading…
Cancel
Save