Overte C++ Documentation
Light.h
1 //
2 // Light.h
3 // libraries/graphics/src/graphics
4 //
5 // Created by Sam Gateau on 12/10/2014.
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_Light_h
13 #define hifi_model_Light_h
14 
15 #include <bitset>
16 #include <map>
17 
18 #include <glm/glm.hpp>
19 #include "Transform.h"
20 #include "gpu/Resource.h"
21 #include "gpu/Texture.h"
22 
23 namespace graphics {
24 typedef gpu::BufferView UniformBufferView;
25 typedef gpu::TextureView TextureView;
26 typedef glm::vec3 Vec3;
27 typedef glm::vec4 Vec4;
28 typedef glm::quat Quat;
29 
30 
31 class Light {
32 public:
33 
34  struct LightVolume {
35  vec3 position { 0.f };
36  float radius { 1.0f };
37  vec3 direction { 0.f, 0.f, -1.f };
38  float spotCos { -1.f };
39 
40  bool isPoint() const { return bool(spotCos < 0.f); }
41  bool isSpot() const { return bool(spotCos >= 0.f); }
42 
43  vec3 getPosition() const { return position; }
44  float getRadius() const { return radius; }
45  float getRadiusSquare() const { return radius * radius; }
46  vec3 getDirection() const { return direction; }
47 
48  float getSpotAngleCos() const { return spotCos; }
49  vec2 getSpotAngleCosSin() const { return vec2(spotCos, sqrt(1.f - spotCos * spotCos)); }
50  };
51 
52 
53  struct LightIrradiance {
54  vec3 color { 1.f };
55  float intensity { 1.f };
56  float falloffRadius { 0.1f };
57  float cutoffRadius { 0.1f };
58  float falloffSpot { 1.f };
59  float spare1;
60 
61  vec3 getColor() const { return color; }
62  float getIntensity() const { return intensity; }
63  vec3 getIrradiance() const { return color * intensity; }
64  float getFalloffRadius() const { return falloffRadius; }
65  float getCutoffRadius() const { return cutoffRadius; }
66  float getFalloffSpot() const { return falloffSpot; }
67  };
68 
69 
70 
71  enum Type {
72  AMBIENT = 0,
73  SUN,
74  POINT,
75  SPOT,
76 
77  NUM_TYPES,
78  };
79 
80  typedef Vec3 Color;
81 
82  enum FlagBit {
83  COLOR_BIT = 0,
84  INTENSITY_BIT,
85  RANGE_BIT,
86  SPOT_BIT,
87  TRANSFORM_BIT,
88 
89  NUM_FLAGS,
90  };
91  typedef std::bitset<NUM_FLAGS> Flags;
92 
93  Light();
94  Light(const Light& light);
95  Light& operator= (const Light& light);
96  virtual ~Light();
97 
98  void setType(Type type);
99  Type getType() const { return _type; }
100 
101  void setPosition(const Vec3& position);
102  const Vec3& getPosition() const { return _transform.getTranslation(); }
103 
104  void setDirection(const Vec3& direction);
105  const Vec3& getDirection() const;
106 
107  void setCastShadows(const bool castShadows);
108  bool getCastShadows() const;
109 
110  void setShadowsMaxDistance(const float maxDistance);
111  float getShadowsMaxDistance() const;
112 
113  void setShadowBias(float bias);
114  float getShadowBias() const;
115 
116  void setOrientation(const Quat& orientation);
117  const glm::quat& getOrientation() const { return _transform.getRotation(); }
118 
119  const Color& getColor() const { return _lightSchemaBuffer->irradiance.color; }
120  void setColor(const Color& color);
121 
122  float getIntensity() const { return _lightSchemaBuffer->irradiance.intensity; }
123  void setIntensity(float intensity);
124 
125  bool isRanged() const { return (getType() == POINT) || (getType() == SPOT); }
126 
127  // FalloffRradius is the physical radius of the light sphere through which energy shines,
128  // expressed in meters. It is used only to calculate the falloff curve of the light.
129  // Actual rendered lights will all have surface radii approaching 0.
130  void setFalloffRadius(float radius);
131  float getFalloffRadius() const { return _lightSchemaBuffer->irradiance.falloffRadius; }
132 
133  // Maximum radius is the cutoff radius of the light energy, expressed in meters.
134  // It is used to bound light entities, and *will not* affect the falloff curve of the light.
135  // Setting it low will result in a noticeable cutoff.
136  void setMaximumRadius(float radius);
137  float getMaximumRadius() const { return _lightSchemaBuffer->volume.radius; }
138 
139  // Spot properties
140  bool isSpot() const { return getType() == SPOT; }
141  void setSpotAngle(float angle);
142  float getSpotAngle() const { return acos(_lightSchemaBuffer->volume.getSpotAngleCos()); }
143  glm::vec2 getSpotAngleCosSin() const { return _lightSchemaBuffer->volume.getSpotAngleCosSin(); }
144  void setSpotExponent(float exponent);
145  float getSpotExponent() const { return _lightSchemaBuffer->irradiance.falloffSpot; }
146 
147  // If the light has an ambient (Indirect) component, then the AmbientColor and AmbientIntensity can be used to control its contribution to the lighting
148  void setAmbientColor(vec3 color);
149  vec3 getAmbientColor() const { return _ambientSchemaBuffer->color; }
150  void setAmbientIntensity(float intensity);
151  float getAmbientIntensity() const { return _ambientSchemaBuffer->intensity; }
152 
153  // Spherical Harmonics storing the Ambient lighting approximation used for the Sun typed light
154  void setAmbientSphere(const gpu::SphericalHarmonics& sphere);
155  const gpu::SphericalHarmonics& getAmbientSphere() const { return _ambientSchemaBuffer->ambientSphere; }
156  void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset);
157 
158  void setAmbientMap(const gpu::TexturePointer& ambientMap);
159  gpu::TexturePointer getAmbientMap() const { return _ambientMap; }
160 
161  void setAmbientMapNumMips(uint16_t numMips);
162  uint16_t getAmbientMapNumMips() const { return (uint16_t) _ambientSchemaBuffer->mapNumMips; }
163 
164  void setTransform(const glm::mat4& transform);
165 
166  // Light Schema
167  class LightSchema {
168  public:
169  LightVolume volume;
170  LightIrradiance irradiance;
171  };
172 
173  class AmbientSchema {
174  public:
175  vec3 color { 0.0f };
176  float blend { 0.0f };
177 
178  float intensity { 0.0f };
179  float mapNumMips { 0.0f };
180  float spare1;
181  float spare2;
182 
183  gpu::SphericalHarmonics ambientSphere;
184  glm::mat4 transform;
185  };
186 
187  using LightSchemaBuffer = gpu::StructBuffer<LightSchema>;
188  using AmbientSchemaBuffer = gpu::StructBuffer<AmbientSchema>;
189 
190  const LightSchemaBuffer& getLightSchemaBuffer() const { return _lightSchemaBuffer; }
191  const AmbientSchemaBuffer& getAmbientSchemaBuffer(); // This also updates the blend factor to make sure it's current
192 
193 protected:
194 
195  Flags _flags{ 0 };
196 
197  LightSchemaBuffer _lightSchemaBuffer;
198  AmbientSchemaBuffer _ambientSchemaBuffer;
199 
200  Transform _transform;
201 
202  gpu::TexturePointer _ambientMap;
203 
204  Type _type { SUN };
205  float _spotCos { -1.0f }; // stored here to be able to reset the spot angle when turning the type spot on/off
206 
207  float _shadowsMaxDistance { 40.0f };
208  float _shadowBias { 0.5f };
209  bool _castShadows{ false };
210 
211  void updateLightRadius();
212 };
213 typedef std::shared_ptr< Light > LightPointer;
214 
215 };
216 
217 #endif
Provides the Quat scripting interface.
Definition: Quat.h:61
Provides the Vec3 scripting interface.
Definition: Vec3.h:80