Overte C++ Documentation
Haze.h
1 //
2 // MakeHaze.h
3 // libraries/graphics/src/graphics
4 //
5 // Created by Nissim Hadar on 9/13/2017.
6 // Copyright 2014 High Fidelity, Inc.
7 // Copyright 2024 Overte e.V.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 #ifndef hifi_model_Haze_h
13 #define hifi_model_Haze_h
14 
15 #include <glm/glm.hpp>
16 #include <gpu/Resource.h>
17 
18 #include "Transform.h"
19 #include "NumericalConstants.h"
20 
21 namespace graphics {
22  // Haze range is defined here as the range the visibility is reduced by 95%
23  // Haze altitude is defined here as the altitude (above 0) that the haze is reduced by 95%
24 
25  class Haze {
26  public:
27  // Initial values
28  static const float INITIAL_HAZE_RANGE;
29  static const float INITIAL_HAZE_HEIGHT;
30 
31  static const float INITIAL_KEY_LIGHT_RANGE;
32  static const float INITIAL_KEY_LIGHT_ALTITUDE;
33 
34  static const float INITIAL_HAZE_BACKGROUND_BLEND;
35 
36  static const glm::vec3 INITIAL_HAZE_COLOR;
37 
38  static const float INITIAL_HAZE_GLARE_ANGLE;
39 
40  static const glm::vec3 INITIAL_HAZE_GLARE_COLOR;
41 
42  static const float INITIAL_HAZE_BASE_REFERENCE;
43 
44  static const float LOG_P_005;
45  static const float LOG_P_05;
46 
47  // Derivation (d is distance, b is haze coefficient, f is attenuation, solve for f = 0.05
48  // f = exp(-d * b)
49  // ln(f) = -d * b
50  // b = -ln(f)/d
51  static inline glm::vec3 convertHazeRangeToHazeRangeFactor(const glm::vec3 hazeRange) {
52  return glm::vec3(
53  -LOG_P_005 / hazeRange.x,
54  -LOG_P_005 / hazeRange.y,
55  -LOG_P_005 / hazeRange.z);
56  }
57 
58  // limit range and altitude to no less than 1.0 metres
59  static inline float convertHazeRangeToHazeRangeFactor(const float hazeRange) { return -LOG_P_005 / glm::max(hazeRange, 1.0f); }
60 
61  static inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeHeight) { return -(LOG_P_005 * glm::sign(hazeHeight)) / glm::max(glm::abs(hazeHeight), 1.0f); }
62 
63  // Derivation (s is the proportion of sun blend, a is the angle at which the blend is 50%, solve for m = 0.5
64  // s = dot(lookAngle, sunAngle) = cos(a)
65  // m = pow(s, p)
66  // log(m) = p * log(s)
67  // p = log(m) / log(s)
68  // limit to 0.1 degrees
69  static inline float convertGlareAngleToPower(const float hazeGlareAngle) {
70  const float GLARE_ANGLE_LIMIT = 0.1f;
71  return LOG_P_05 / logf(cosf(RADIANS_PER_DEGREE * glm::max(GLARE_ANGLE_LIMIT, hazeGlareAngle)));
72  }
73 
74  Haze();
75 
76  void setHazeColor(const glm::vec3 hazeColor);
77  void setHazeGlareBlend(const float hazeGlareBlend);
78 
79  void setHazeGlareColor(const glm::vec3 hazeGlareColor);
80  void setHazeBaseReference(const float hazeBaseReference);
81 
82  void setHazeActive(const bool isHazeActive);
83  void setAltitudeBased(const bool isAltitudeBased);
84  void setHazeAttenuateKeyLight(const bool isHazeAttenuateKeyLight);
85  void setModulateColorActive(const bool isModulateColorActive);
86  void setHazeEnableGlare(const bool isHazeEnableGlare);
87 
88  void setHazeRangeFactor(const float hazeRange);
89  void setHazeAltitudeFactor(const float hazeAltitude);
90 
91  void setHazeKeyLightRangeFactor(const float hazeKeyLightRange);
92  void setHazeKeyLightAltitudeFactor(const float hazeKeyLightAltitude);
93 
94  void setHazeBackgroundBlend(const float hazeBackgroundBlend);
95 
96  using UniformBufferView = gpu::BufferView;
97  UniformBufferView getHazeParametersBuffer() const { return _hazeParametersBuffer; }
98 
99  bool isActive() const;
100 
101  protected:
102  class Parameters {
103  public:
104  // DO NOT CHANGE ORDER HERE WITHOUT UNDERSTANDING THE std140 LAYOUT
105  glm::vec3 hazeColor { INITIAL_HAZE_COLOR };
106  float hazeGlareBlend { convertGlareAngleToPower(INITIAL_HAZE_GLARE_ANGLE) };
107 
108  glm::vec3 hazeGlareColor { INITIAL_HAZE_GLARE_COLOR };
109  float hazeBaseReference { INITIAL_HAZE_BASE_REFERENCE };
110 
111  glm::vec3 colorModulationFactor;
112  int hazeMode { 0 }; // bit 0 - set to activate haze attenuation of fragment color
113  // bit 1 - set to add the effect of altitude to the haze attenuation
114  // bit 2 - set to activate directional light attenuation mode
115  // bit 3 - set to blend between blend-in and blend-out colours
116 
117  // Padding required to align the struct
118 #if defined(__clang__)
119  __attribute__((unused))
120 #endif
121  vec3 __padding;
122 
123  // Amount of background (skybox) to display, overriding the haze effect for the background
124  float hazeBackgroundBlend { INITIAL_HAZE_BACKGROUND_BLEND };
125  // The haze attenuation exponents used by both fragment and directional light attenuation
126  float hazeRangeFactor { convertHazeRangeToHazeRangeFactor(INITIAL_HAZE_RANGE) };
127  float hazeHeightFactor { convertHazeAltitudeToHazeAltitudeFactor(INITIAL_HAZE_HEIGHT) };
128  float hazeKeyLightRangeFactor { convertHazeRangeToHazeRangeFactor(INITIAL_KEY_LIGHT_RANGE) };
129 
130  float hazeKeyLightAltitudeFactor { convertHazeAltitudeToHazeAltitudeFactor(INITIAL_KEY_LIGHT_ALTITUDE) };
131 
132  Parameters() {}
133  };
134 
135  UniformBufferView _hazeParametersBuffer { nullptr };
136  };
137 
138  using HazePointer = std::shared_ptr<Haze>;
139 }
140 #endif // hifi_model_Haze_h