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