Overte C++ Documentation
LightStage.h
1 //
2 // LightStage.h
3 // render-utils/src
4 //
5 // Created by Zach Pomerantz on 1/14/2015.
6 // Copyright 2015 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 
12 #ifndef hifi_render_utils_LightStage_h
13 #define hifi_render_utils_LightStage_h
14 
15 #include <set>
16 #include <unordered_map>
17 
18 #include <gpu/Framebuffer.h>
19 
20 #include <graphics/Light.h>
21 
22 #include <render/IndexedContainer.h>
23 #include <render/Stage.h>
24 #include <render/Engine.h>
25 
26 class ViewFrustum;
27 
28 // Light stage to set up light-related rendering tasks
29 class LightStage : public render::Stage {
30 public:
31  static std::string _stageName;
32  static const std::string& getName() { return _stageName; }
33 
34  using Index = render::indexed_container::Index;
35  static const Index INVALID_INDEX;
36  static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; }
37 
38  using LightPointer = graphics::LightPointer;
39  using Lights = render::indexed_container::IndexedPointerVector<graphics::Light>;
40  using LightMap = std::unordered_map<LightPointer, Index>;
41 
42  using LightIndices = std::vector<Index>;
43 
44  class Shadow {
45  public:
46  using UniformBufferView = gpu::BufferView;
47  static const int MAP_SIZE;
48 
49  class Cascade {
50  friend Shadow;
51  public:
52 
53  Cascade();
54 
55  gpu::FramebufferPointer framebuffer;
56 
57  const std::shared_ptr<ViewFrustum>& getFrustum() const { return _frustum; }
58 
59  const glm::mat4& getView() const;
60  const glm::mat4& getProjection() const;
61 
62  void setMinDistance(float value) { _minDistance = value; }
63  void setMaxDistance(float value) { _maxDistance = value; }
64  float getMinDistance() const { return _minDistance; }
65  float getMaxDistance() const { return _maxDistance; }
66 
67  private:
68 
69  std::shared_ptr<ViewFrustum> _frustum;
70  float _minDistance;
71  float _maxDistance;
72 
73  float computeFarDistance(const ViewFrustum& viewFrustum, const Transform& shadowViewInverse,
74  float left, float right, float bottom, float top, float viewMaxShadowDistance) const;
75  };
76 
77  Shadow(graphics::LightPointer light, unsigned int cascadeCount = 1);
78 
79  void setLight(graphics::LightPointer light);
80 
81  void setKeylightFrustum(const ViewFrustum& viewFrustum,
82  float nearDepth = 1.0f, float farDepth = 1000.0f);
83  void setKeylightCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum,
84  float nearDepth = 1.0f, float farDepth = 1000.0f);
85  void setKeylightCascadeBias(unsigned int cascadeIndex, float constantBias, float slopeBias);
86  void setCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& shadowFrustum);
87 
88  const UniformBufferView& getBuffer() const { return _schemaBuffer; }
89 
90  unsigned int getCascadeCount() const { return (unsigned int)_cascades.size(); }
91  const Cascade& getCascade(unsigned int index) const { return _cascades[index]; }
92 
93  float getMaxDistance() const { return _maxDistance; }
94  void setMaxDistance(float value);
95 
96  const graphics::LightPointer& getLight() const { return _light; }
97 
98  gpu::TexturePointer map;
99 #include "Shadows_shared.slh"
100  class Schema : public ShadowParameters {
101  public:
102 
103  Schema();
104 
105  };
106  protected:
107 
108  using Cascades = std::vector<Cascade>;
109 
110  static const glm::mat4 _biasMatrix;
111 
112  graphics::LightPointer _light;
113  float _maxDistance{ 0.0f };
114  Cascades _cascades;
115 
116  UniformBufferView _schemaBuffer = nullptr;
117  };
118 
119  using ShadowPointer = std::shared_ptr<Shadow>;
120 
121  Index findLight(const LightPointer& light) const;
122  Index addLight(const LightPointer& light, const bool shouldSetAsDefault = false);
123 
124  Index getDefaultLight() { return _defaultLightId; }
125 
126  LightPointer removeLight(Index index);
127 
128  bool checkLightId(Index index) const { return _lights.checkIndex(index); }
129 
130  Index getNumLights() const { return _lights.getNumElements(); }
131  Index getNumFreeLights() const { return _lights.getNumFreeIndices(); }
132  Index getNumAllocatedLights() const { return _lights.getNumAllocatedIndices(); }
133 
134  LightPointer getLight(Index lightId) const { return _lights.get(lightId); }
135 
136  LightStage();
137 
138  gpu::BufferPointer getLightArrayBuffer() const { return _lightArrayBuffer; }
139  void updateLightArrayBuffer(Index lightId);
140 
141  class Frame {
142  public:
143  Frame() {}
144 
145  void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); _ambientLights.clear(); }
146  void pushLight(LightStage::Index index, graphics::Light::Type type) {
147  switch (type) {
148  case graphics::Light::POINT: { pushPointLight(index); break; }
149  case graphics::Light::SPOT: { pushSpotLight(index); break; }
150  case graphics::Light::SUN: { pushSunLight(index); break; }
151  case graphics::Light::AMBIENT: { pushAmbientLight(index); break; }
152  default: { break; }
153  }
154  }
155  void pushPointLight(LightStage::Index index) { _pointLights.emplace_back(index); }
156  void pushSpotLight(LightStage::Index index) { _spotLights.emplace_back(index); }
157  void pushSunLight(LightStage::Index index) { _sunLights.emplace_back(index); }
158  void pushAmbientLight(LightStage::Index index) { _ambientLights.emplace_back(index); }
159 
160  LightStage::LightIndices _pointLights;
161  LightStage::LightIndices _spotLights;
162  LightStage::LightIndices _sunLights;
163  LightStage::LightIndices _ambientLights;
164  };
165  using FramePointer = std::shared_ptr<Frame>;
166 
167  class ShadowFrame {
168  public:
169  ShadowFrame() {}
170 
171  void clear() {}
172 
173  using Object = ShadowPointer;
174  using Objects = std::vector<Object>;
175 
176  void pushShadow(const ShadowPointer& shadow) {
177  _objects.emplace_back(shadow);
178  }
179 
180 
181  Objects _objects;
182  };
183  using ShadowFramePointer = std::shared_ptr<ShadowFrame>;
184 
185  Frame _currentFrame;
186 
187  Index getAmbientOffLight() { return _ambientOffLightId; }
188  Index getPointOffLight() { return _pointOffLightId; }
189  Index getSpotOffLight() { return _spotOffLightId; }
190  Index getSunOffLight() { return _sunOffLightId; }
191 
192  LightPointer getCurrentKeyLight(const LightStage::Frame& frame) const;
193  LightPointer getCurrentAmbientLight(const LightStage::Frame& frame) const;
194 
195 protected:
196 
197  struct Desc {
198  Index shadowId{ INVALID_INDEX };
199  };
200  using Descs = std::vector<Desc>;
201 
202  gpu::BufferPointer _lightArrayBuffer;
203 
204  Lights _lights;
205  Descs _descs;
206  LightMap _lightMap;
207 
208  // define off lights
209  Index _ambientOffLightId;
210  Index _pointOffLightId;
211  Index _spotOffLightId;
212  Index _sunOffLightId;
213 
214  Index _defaultLightId;
215 
216 };
217 using LightStagePointer = std::shared_ptr<LightStage>;
218 
219 
220 class LightStageSetup {
221 public:
222  using JobModel = render::Job::Model<LightStageSetup>;
223 
224  LightStageSetup();
225  void run(const render::RenderContextPointer& renderContext);
226 
227 protected:
228 };
229 
230 
231 #endif