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 // 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 
13 #ifndef hifi_render_utils_LightStage_h
14 #define hifi_render_utils_LightStage_h
15 
16 #include <gpu/Framebuffer.h>
17 #include <graphics/Light.h>
18 #include <render/Stage.h>
19 #include <render/StageSetup.h>
20 
21 class ViewFrustum;
22 
23 class LightFrame {
24 public:
25  LightFrame() {}
26 
27  using Index = render::indexed_container::Index;
28 
29  void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); _ambientLights.clear(); }
30  void pushLight(Index index, graphics::Light::Type type) {
31  switch (type) {
32  case graphics::Light::POINT: { pushPointLight(index); break; }
33  case graphics::Light::SPOT: { pushSpotLight(index); break; }
34  case graphics::Light::SUN: { pushSunLight(index); break; }
35  case graphics::Light::AMBIENT: { pushAmbientLight(index); break; }
36  default: { break; }
37  }
38  }
39  void pushPointLight(Index index) { _pointLights.emplace_back(index); }
40  void pushSpotLight(Index index) { _spotLights.emplace_back(index); }
41  void pushSunLight(Index index) { _sunLights.emplace_back(index); }
42  void pushAmbientLight(Index index) { _ambientLights.emplace_back(index); }
43 
44  render::ElementIndices _pointLights;
45  render::ElementIndices _spotLights;
46  render::ElementIndices _sunLights;
47  render::ElementIndices _ambientLights;
48 };
49 
50 // Light stage to set up light-related rendering tasks
51 class LightStage : public render::PointerStage<graphics::Light, graphics::LightPointer, LightFrame> {
52 public:
53  using LightPointer = graphics::LightPointer;
54 
55  class Shadow {
56  public:
57  using UniformBufferView = gpu::BufferView;
58  static const int MAP_SIZE;
59 
60  class Cascade {
61  friend Shadow;
62  public:
63 
64  Cascade();
65 
66  gpu::FramebufferPointer framebuffer;
67 
68  const std::shared_ptr<ViewFrustum>& getFrustum() const { return _frustum; }
69 
70  const glm::mat4& getView() const;
71  const glm::mat4& getProjection() const;
72 
73  void setMinDistance(float value) { _minDistance = value; }
74  void setMaxDistance(float value) { _maxDistance = value; }
75  float getMinDistance() const { return _minDistance; }
76  float getMaxDistance() const { return _maxDistance; }
77 
78  private:
79 
80  std::shared_ptr<ViewFrustum> _frustum;
81  float _minDistance;
82  float _maxDistance;
83 
84  float computeFarDistance(const ViewFrustum& viewFrustum, const Transform& shadowViewInverse,
85  float left, float right, float bottom, float top, float viewMaxShadowDistance) const;
86  };
87 
88  Shadow(LightPointer light, unsigned int cascadeCount = 1);
89 
90  void setLight(LightPointer light);
91 
92  void setKeylightFrustum(const ViewFrustum& viewFrustum,
93  float nearDepth = 1.0f, float farDepth = 1000.0f);
94  void setKeylightCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum,
95  float nearDepth = 1.0f, float farDepth = 1000.0f);
96  void setKeylightCascadeBias(unsigned int cascadeIndex, float constantBias, float slopeBias);
97  void setCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& shadowFrustum);
98 
99  const UniformBufferView& getBuffer() const { return _schemaBuffer; }
100 
101  unsigned int getCascadeCount() const { return (unsigned int)_cascades.size(); }
102  const Cascade& getCascade(unsigned int index) const { return _cascades[index]; }
103 
104  float getMaxDistance() const { return _maxDistance; }
105  void setMaxDistance(float value);
106 
107  const LightPointer& getLight() const { return _light; }
108 
109  gpu::TexturePointer map;
110 #include "Shadows_shared.slh"
111  class Schema : public ShadowParameters {
112  public:
113  Schema();
114  };
115 
116  protected:
117 
118  using Cascades = std::vector<Cascade>;
119 
120  static const glm::mat4 _biasMatrix;
121 
122  LightPointer _light;
123  float _maxDistance{ 0.0f };
124  Cascades _cascades;
125 
126  UniformBufferView _schemaBuffer = nullptr;
127  };
128  using ShadowPointer = std::shared_ptr<Shadow>;
129 
130  Index addElement(const LightPointer& light) override { return addElement(light, false); }
131  Index addElement(const LightPointer& light, const bool shouldSetAsDefault);
132  LightPointer removeElement(Index index) override;
133 
134  Index getDefaultLight() { return _defaultLightId; }
135 
136  LightStage();
137 
138  gpu::BufferPointer getLightArrayBuffer() const { return _lightArrayBuffer; }
139  void updateLightArrayBuffer(Index lightId);
140 
141  class ShadowFrame {
142  public:
143  ShadowFrame() {}
144 
145  void clear() {}
146 
147  using Object = ShadowPointer;
148  using Objects = std::vector<Object>;
149 
150  void pushShadow(const ShadowPointer& shadow) {
151  _objects.emplace_back(shadow);
152  }
153 
154  Objects _objects;
155  };
156  using ShadowFramePointer = std::shared_ptr<ShadowFrame>;
157 
158  Index getAmbientOffLight() { return _ambientOffLightId; }
159  Index getPointOffLight() { return _pointOffLightId; }
160  Index getSpotOffLight() { return _spotOffLightId; }
161  Index getSunOffLight() { return _sunOffLightId; }
162 
163  LightPointer getCurrentKeyLight(const LightFrame& frame) const;
164  LightPointer getCurrentAmbientLight(const LightFrame& frame) const;
165 
166 protected:
167 
168  struct Desc {
169  Index shadowId{ INVALID_INDEX };
170  };
171  using Descs = std::vector<Desc>;
172 
173  gpu::BufferPointer _lightArrayBuffer;
174 
175  Descs _descs;
176 
177  // define off lights
178  Index _ambientOffLightId;
179  Index _pointOffLightId;
180  Index _spotOffLightId;
181  Index _sunOffLightId;
182 
183  Index _defaultLightId;
184 
185 };
186 using LightStagePointer = std::shared_ptr<LightStage>;
187 
188 class LightStageSetup : public render::StageSetup<LightStage> {
189 public:
190  using JobModel = render::Job::Model<LightStageSetup>;
191 };
192 
193 #endif