12 #ifndef hifi_render_utils_LightStage_h
13 #define hifi_render_utils_LightStage_h
16 #include <unordered_map>
18 #include <gpu/Framebuffer.h>
20 #include <graphics/Light.h>
22 #include <render/IndexedContainer.h>
23 #include <render/Stage.h>
24 #include <render/Engine.h>
29 class LightStage :
public render::Stage {
31 static std::string _stageName;
32 static const std::string& getName() {
return _stageName; }
34 using Index = render::indexed_container::Index;
35 static const Index INVALID_INDEX;
36 static bool isIndexInvalid(Index index) {
return index == INVALID_INDEX; }
38 using LightPointer = graphics::LightPointer;
39 using Lights = render::indexed_container::IndexedPointerVector<graphics::Light>;
40 using LightMap = std::unordered_map<LightPointer, Index>;
42 using LightIndices = std::vector<Index>;
46 using UniformBufferView = gpu::BufferView;
47 static const int MAP_SIZE;
55 gpu::FramebufferPointer framebuffer;
57 const std::shared_ptr<ViewFrustum>& getFrustum()
const {
return _frustum; }
59 const glm::mat4& getView()
const;
60 const glm::mat4& getProjection()
const;
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; }
69 std::shared_ptr<ViewFrustum> _frustum;
73 float computeFarDistance(
const ViewFrustum& viewFrustum,
const Transform& shadowViewInverse,
74 float left,
float right,
float bottom,
float top,
float viewMaxShadowDistance)
const;
77 Shadow(graphics::LightPointer light,
unsigned int cascadeCount = 1);
79 void setLight(graphics::LightPointer light);
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);
88 const UniformBufferView& getBuffer()
const {
return _schemaBuffer; }
90 unsigned int getCascadeCount()
const {
return (
unsigned int)_cascades.size(); }
91 const Cascade& getCascade(
unsigned int index)
const {
return _cascades[index]; }
93 float getMaxDistance()
const {
return _maxDistance; }
94 void setMaxDistance(
float value);
96 const graphics::LightPointer& getLight()
const {
return _light; }
98 gpu::TexturePointer map;
99 #include "Shadows_shared.slh"
100 class Schema :
public ShadowParameters {
108 using Cascades = std::vector<Cascade>;
110 static const glm::mat4 _biasMatrix;
112 graphics::LightPointer _light;
113 float _maxDistance{ 0.0f };
116 UniformBufferView _schemaBuffer =
nullptr;
119 using ShadowPointer = std::shared_ptr<Shadow>;
121 Index findLight(
const LightPointer& light)
const;
122 Index addLight(
const LightPointer& light,
const bool shouldSetAsDefault =
false);
124 Index getDefaultLight() {
return _defaultLightId; }
126 LightPointer removeLight(Index index);
128 bool checkLightId(Index index)
const {
return _lights.checkIndex(index); }
130 Index getNumLights()
const {
return _lights.getNumElements(); }
131 Index getNumFreeLights()
const {
return _lights.getNumFreeIndices(); }
132 Index getNumAllocatedLights()
const {
return _lights.getNumAllocatedIndices(); }
134 LightPointer getLight(Index lightId)
const {
return _lights.get(lightId); }
138 gpu::BufferPointer getLightArrayBuffer()
const {
return _lightArrayBuffer; }
139 void updateLightArrayBuffer(Index lightId);
145 void clear() { _pointLights.clear(); _spotLights.clear(); _sunLights.clear(); _ambientLights.clear(); }
146 void pushLight(LightStage::Index index, graphics::Light::Type 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; }
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); }
160 LightStage::LightIndices _pointLights;
161 LightStage::LightIndices _spotLights;
162 LightStage::LightIndices _sunLights;
163 LightStage::LightIndices _ambientLights;
165 using FramePointer = std::shared_ptr<Frame>;
173 using Object = ShadowPointer;
174 using Objects = std::vector<Object>;
176 void pushShadow(
const ShadowPointer& shadow) {
177 _objects.emplace_back(shadow);
183 using ShadowFramePointer = std::shared_ptr<ShadowFrame>;
187 Index getAmbientOffLight() {
return _ambientOffLightId; }
188 Index getPointOffLight() {
return _pointOffLightId; }
189 Index getSpotOffLight() {
return _spotOffLightId; }
190 Index getSunOffLight() {
return _sunOffLightId; }
192 LightPointer getCurrentKeyLight(
const LightStage::Frame& frame)
const;
193 LightPointer getCurrentAmbientLight(
const LightStage::Frame& frame)
const;
198 Index shadowId{ INVALID_INDEX };
200 using Descs = std::vector<Desc>;
202 gpu::BufferPointer _lightArrayBuffer;
209 Index _ambientOffLightId;
210 Index _pointOffLightId;
211 Index _spotOffLightId;
212 Index _sunOffLightId;
214 Index _defaultLightId;
217 using LightStagePointer = std::shared_ptr<LightStage>;
220 class LightStageSetup {
222 using JobModel = render::Job::Model<LightStageSetup>;
225 void run(
const render::RenderContextPointer& renderContext);