albedo/synthetic.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Synthetic albedos: a base colour with noise in hue, saturation and value. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/albedo/albedo.h" | ||
| 6 | #include "terraingen/noise/noise_layers.h" | ||
| 7 | #include "terraingen/util/geometry.h" | ||
| 8 | |||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | namespace terraingen { | ||
| 12 | |||
| 13 | /// The default value of a synthetic albedo: the reflectance of mature mare soil at 750 nm. | ||
| 14 | inline constexpr double kDefaultSyntheticAlbedoValue = 0.110; | ||
| 15 | |||
| 16 | /// The colour of a `SyntheticAlbedo`: a base colour in hue, saturation and value, each | ||
| 17 | /// varied by a stack of noise layers (`EvaluateNoiseLayers`, with amplitudes in the channel's | ||
| 18 | /// units). | ||
| 19 | struct SyntheticAlbedoParams { | ||
| 20 | /// Three bands (red, green, blue) from the colour; otherwise one band, its value. | ||
| 21 | bool rgb = false; | ||
| 22 | double hue = 0.0; ///< Degrees; noise added to it wraps around. | ||
| 23 | double saturation = 0.0; ///< In [0, 1]; 0 is grey. | ||
| 24 | /// In [0, 1]: the brightest band's reflectance (`kDefaultSyntheticAlbedoValue` by default). | ||
| 25 | double value = kDefaultSyntheticAlbedoValue; | ||
| 26 | std::vector<NoiseLayer> hueNoise; ///< Added to the hue, in degrees. | ||
| 27 | std::vector<NoiseLayer> saturationNoise; ///< Added to the saturation. | ||
| 28 | /// Relative: the value is multiplied by 1 + the noise, so its contrast scales with it. | ||
| 29 | std::vector<NoiseLayer> valueNoise; | ||
| 30 | |||
| 31 | bool operator==(const SyntheticAlbedoParams&) const = default; | ||
| 32 | }; | ||
| 33 | |||
| 34 | /// Checks synthetic albedo settings. | ||
| 35 | /// @throws std::invalid_argument for a hue, saturation or value that is not finite, a saturation | ||
| 36 | /// or value outside [0, 1], more than `kMaxNoiseLayers` layers in a stack, or an invalid layer. | ||
| 37 | void ValidateSyntheticAlbedo(const SyntheticAlbedoParams& params); | ||
| 38 | |||
| 39 | /// Converts a colour from hue, saturation and value to red, green and blue in [0, 1] by the | ||
| 40 | /// hexcone model (Smith 1978). | ||
| 41 | /// @param hue Hue in degrees; any value, wrapped. | ||
| 42 | /// @param saturation Saturation in [0, 1]. | ||
| 43 | /// @param value Value in [0, 1]. | ||
| 44 | AlbedoSample HsvToRgb(double hue, double saturation, double value); | ||
| 45 | |||
| 46 | /// An albedo for terrain without data: a base colour with noise in each channel, the | ||
| 47 | /// saturation and value clamped to [0, 1] after it. Noise is measured from `origin`; on a sphere it | ||
| 48 | /// is 3D noise at each point's 3D position (`EvaluateNoiseLayers3`). | ||
| 49 | class SyntheticAlbedo final : public AlbedoSource { | ||
| 50 | public: | ||
| 51 | /// The synthetic albedo with the colour and noise of `params`. | ||
| 52 | /// @param origin Point noise is measured from, keeping single-precision noise accurate where | ||
| 53 | /// coordinates are large. | ||
| 54 | /// @throws std::invalid_argument as `ValidateSyntheticAlbedo`. | ||
| 55 | explicit SyntheticAlbedo(SyntheticAlbedoParams params, Vec2d origin = {}, Surface surface = {}); | ||
| 56 | |||
| 57 | /// 3 bands when `rgb` is set, otherwise 1. | ||
| 58 | 1712 | std::size_t Bands() const override { | |
| 59 | 1712 | return params_.rgb ? kMaxAlbedoBands : 1; | |
| 60 | } | ||
| 61 | |||
| 62 | /// The colour with noise at world point (`x`, `y`). | ||
| 63 | AlbedoSample ValueAt(double x, double y, const AlbedoContext& context) const override; | ||
| 64 | |||
| 65 | /// The colour and its noise. | ||
| 66 | const SyntheticAlbedoParams& Params() const { | ||
| 67 | return params_; | ||
| 68 | } | ||
| 69 | |||
| 70 | private: | ||
| 71 | double Noise(const std::vector<NoiseLayer>& layers, double x, double y) const; | ||
| 72 | |||
| 73 | SyntheticAlbedoParams params_; | ||
| 74 | Vec2d origin_; | ||
| 75 | Surface surface_; | ||
| 76 | }; | ||
| 77 | |||
| 78 | } // namespace terraingen | ||
| 79 |