Skip to content

Commit

Permalink
🔀 Merge pull request #395 from cosmoscout/feature/advanced-eclipses
Browse files Browse the repository at this point in the history
  • Loading branch information
Schneegans authored Jan 24, 2025
2 parents 868bef9 + 4b0e48e commit 149e462
Show file tree
Hide file tree
Showing 77 changed files with 3,732 additions and 872 deletions.
9 changes: 7 additions & 2 deletions config/base/scene/simple_desktop.json
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,13 @@
"graphics": {
"enableHDR": true,
"eclipseShadowMaps": {
"Earth": {},
"Earth": {
"texture":"../share/resources/textures/earthShadow.tif"
},
"Moon": {},
"Mars": {},
"Mars": {
"texture":"../share/resources/textures/marsShadow.tif"
},
"Phobos": {},
"Deimos": {},
"Jupiter": {},
Expand Down Expand Up @@ -739,6 +743,7 @@
"atmospheres": {
"Earth": {
"cloudTexture": "../share/resources/textures/earth-clouds.jpg",
"limbLuminanceTexture": "../share/resources/textures/earthLimbLuminance.tif",
"topAltitude": 80000,
"bottomAltitude": -100,
"model": "Bruneton",
Expand Down
4 changes: 3 additions & 1 deletion docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ SPDX-License-Identifier: CC-BY-4.0

#### New Features

- `csp-atmospheres` now supports refraction of light through the atmosphere. This deforms the Sun in Earth's atmosphere when it is close to the horizon. When observed from space, the sunset can turn into a glowing red ring around Earth.
- Eclipse shadows now consider the atmosphere of the occluder. This is used for Earth and Mars. As light is refracted through the atmosphere, the shadow is not completely dark anymore. Instead, some copper-red light is now shed on the Moon during a lunar eclipse.
- `csp-trajectories` now draws proxies for celestial objects when they are smaller than a few pixels in HDR mode. This makes them visible even if they are very small, such as when looking in the sky at night. This also drastically reduces flickering in HDR mode when the bodies are very small on the screen.
- The `csp-stars` plugin now comes with two new rendering modes: Glare Discs and Software-Rasterized Points. The latter is the new default mode and is much faster than the old ones.
- The `csp-trajectories` now draws proxies for celestial objects when they are smaller than a few pixels in HDR mode. This makes them visible even if they are very small, such as when looking in the sky at night. This also drastically reduces flickering in HDR mode when the bodies are very small on the screen.
- The `/capture` endpoint of the `csp-web-api` now supports an optional `restoreState` parameter. If set to `true`, the size of the window and the visibility of the user interface will be restored after capturing the image. Thanks to [@DanielPSchenk](https://github.com/DanielPSchenk) for this contribution!

#### Other Changes
Expand Down
14 changes: 10 additions & 4 deletions plugins/csp-atmospheres/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,21 @@ They are not physically based but provide some plausible results.
The Bruneton model is significantly more advanced.
It precomputes multiple scattering and is based on [this open-source implementation](https://github.com/ebruneton/precomputed_atmospheric_scattering) (see also the corresponding [Paper](https://inria.hal.science/inria-00288758/en)).

Similar to the `CosmoScoutVR` model, the original implementation by Eric Bruneton uses Rayleigh scattering for molecules and the Cornette-Shanks phase function for aerosols.
We generalized this implementation by loading phase functions, extinction coefficients, and particle density distributions from CSV files.
We have significantly extended the original implementation to allow for more flexibility.
See our paper [Physically Based Real-Time Rendering of Atmospheres using Mie Theory](https://onlinelibrary.wiley.com/doi/full/10.1111/cgf.15010) for more details.

As a first change, we now load phase functions, extinction coefficients, and particle density distributions from CSV files.
This allows us to simulate arbitrary particle types.
In particular, we can now use Mie Theory to precompute the scattering behaviour of a wide variety of particle types, including for instance Martian dust.

Next, our implementation can compute refraction.
This allows for displaced horizons and the simulation of astronomical refraction.
This is also used for computing light entering the eclipse shadows of celestial bodies.

Another change to the original implementation is that we put the precomputation of the atmospheric scattering into a separate executable.
This allows us to perform the preprocessing offline with a much higher fidelity than what would be possible during application startup.

As a consequence to the changes mentioned above, **two preprocessing steps are required to use this model**.
There are **two preprocessing steps are required to use this model**.

#### Preprocessing Step 1: Precompute the Particle-Scattering CSV Tables

Expand Down Expand Up @@ -197,7 +203,7 @@ Once the multiple scattering textures are precomputed, the configuration for the
</details>

<details>
<summary>Example Configuration for Mars (Realistic)</summary>
<summary>Example Configuration for Mars</summary>

```javascript
"Mars": {
Expand Down
6 changes: 6 additions & 0 deletions plugins/csp-atmospheres/REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ precedence = "aggregate"
SPDX-FileCopyrightText = "German Aerospace Center (DLR) <cosmoscout@dlr.de>"
SPDX-License-Identifier = "CC0-1.0"

[[annotations]]
path = "scattering-table-generator/ior-settings/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "German Aerospace Center (DLR) <cosmoscout@dlr.de>"
SPDX-License-Identifier = "CC0-1.0"

[[annotations]]
path = "scattering-table-generator/output/**"
precedence = "aggregate"
Expand Down
1 change: 1 addition & 0 deletions plugins/csp-atmospheres/bruneton-preprocessor/Metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ void to_json(nlohmann::json& j, Metadata const& o) {
cs::core::Settings::serialize(j, "sunIlluminance", o.mSunIlluminance);
cs::core::Settings::serialize(j, "scatteringTextureNuSize", o.mScatteringTextureNuSize);
cs::core::Settings::serialize(j, "maxSunZenithAngle", o.mMaxSunZenithAngle);
cs::core::Settings::serialize(j, "refraction", o.mRefraction);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
3 changes: 3 additions & 0 deletions plugins/csp-atmospheres/bruneton-preprocessor/Metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ struct Metadata {

/// The maximum Sun zenith angle for which atmospheric scattering was be precomputed.
float mMaxSunZenithAngle{};

/// Whether refraction was used during preprocessing.
bool mRefraction{};
};

void to_json(nlohmann::json& j, Metadata const& o);
Expand Down
5 changes: 5 additions & 0 deletions plugins/csp-atmospheres/bruneton-preprocessor/Params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ void from_json(nlohmann::json const& j, Params& o) {
cs::core::Settings::deserialize(j, "molecules", o.mMolecules);
cs::core::Settings::deserialize(j, "aerosols", o.mAerosols);
cs::core::Settings::deserialize(j, "ozone", o.mOzone);
cs::core::Settings::deserialize(j, "ior", o.mRefractiveIndex);
cs::core::Settings::deserialize(j, "minAltitude", o.mMinAltitude);
cs::core::Settings::deserialize(j, "maxAltitude", o.mMaxAltitude);
cs::core::Settings::deserialize(j, "refraction", o.mRefraction);
cs::core::Settings::deserialize(j, "groundAlbedo", o.mGroundAlbedo);
cs::core::Settings::deserialize(j, "multiScatteringOrder", o.mMultiScatteringOrder);
cs::core::Settings::deserialize(j, "sampleCountOpticalDepth", o.mSampleCountOpticalDepth);
cs::core::Settings::deserialize(j, "stepSizeOpticalDepth", o.mStepSizeOpticalDepth);
cs::core::Settings::deserialize(j, "sampleCountSingleScattering", o.mSampleCountSingleScattering);
cs::core::Settings::deserialize(j, "stepSizeSingleScattering", o.mStepSizeSingleScattering);
cs::core::Settings::deserialize(j, "sampleCountMultiScattering", o.mSampleCountMultiScattering);
cs::core::Settings::deserialize(j, "stepSizeMultiScattering", o.mStepSizeMultiScattering);
cs::core::Settings::deserialize(
j, "sampleCountScatteringDensity", o.mSampleCountScatteringDensity);
cs::core::Settings::deserialize(
Expand Down
24 changes: 21 additions & 3 deletions plugins/csp-atmospheres/bruneton-preprocessor/Params.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ struct Params {
ScatteringComponent mAerosols;
std::optional<AbsorbingComponent> mOzone;

/// To compute the refraction of light in the atmosphere, the refractive index of the atmosphere
/// is needed. For increased precision, the refractive index is stored as n-1.
float mRefractiveIndex = 0.0002777F;

/// The wavelength values, in nanometers, and sorted in increasing order, for which the
/// phase functions and extinction coefficients in the atmosphere components are given.
std::vector<float> mWavelengths;
Expand All @@ -69,22 +73,36 @@ struct Params {
float mMinAltitude = 6371000.F;
float mMaxAltitude = 6471000.F;

/// Refract the light when it travels through the atmosphere. This will produce an additional
/// look-up texture in the same parameter space as the transmittance texture. For each sample,
/// it contains the wavelength-dependent angular deviation of the light ray due to refraction.
cs::utils::DefaultProperty<bool> mRefraction{true};

/// The average reflectance of the ground used during multiple scattering.
cs::utils::DefaultProperty<float> mGroundAlbedo{0.1F};

/// The number of multiple scattering events to precompute. Use zero for single-scattering only.
cs::utils::DefaultProperty<int32_t> mMultiScatteringOrder{4};

/// The number of samples to evaluate when precomputing the optical depth.
/// The number of samples to evaluate when precomputing the optical depth. If refraction is used,
/// the algorithm uses a fixed step size instead of a fixed number of samples. So if mRefraction
/// is true, mStepSizeOpticalDepth (in meters) will be used instead of mSampleCountOpticalDepth.
cs::utils::DefaultProperty<int32_t> mSampleCountOpticalDepth{500};
cs::utils::DefaultProperty<int32_t> mStepSizeOpticalDepth{10000};

/// The number of samples to evaluate when precomputing the single scattering. Larger values
/// improve the sampling of thin atmospheric layers.
/// improve the sampling of thin atmospheric layers. If refraction is used, the algorithm uses a
/// fixed step size instead of a fixed number of samples. So if mRefraction is true,
/// mStepSizeSingleScattering (in meters) will be used instead of mSampleCountSingleScattering.
cs::utils::DefaultProperty<int32_t> mSampleCountSingleScattering{50};
cs::utils::DefaultProperty<int32_t> mStepSizeSingleScattering{10000};

/// The number of samples to evaluate when precomputing the multiple scattering. Larger values
/// tend to darken the horizon for thick atmospheres.
/// tend to darken the horizon for thick atmospheres. If refraction is used, the algorithm uses a
/// fixed step size instead of a fixed number of samples. So if mRefraction is true,
/// mStepSizeMultiScattering (in meters) will be used instead of mSampleCountMultiScattering.
cs::utils::DefaultProperty<int32_t> mSampleCountMultiScattering{50};
cs::utils::DefaultProperty<int32_t> mStepSizeMultiScattering{10000};

/// The number of samples to evaluate when precomputing the scattering density. Larger values
/// spread out colors in the sky.
Expand Down
Loading

0 comments on commit 149e462

Please sign in to comment.