11 #ifndef hifi_render_utils_LightClusters_h
12 #define hifi_render_utils_LightClusters_h
14 #include <ViewFrustum.h>
15 #include <gpu/Buffer.h>
16 #include <render/Engine.h>
17 #include "LightStage.h"
18 #include "DeferredFrameTransform.h"
19 #include "LightingModel.h"
20 #include "SurfaceGeometryPass.h"
24 float frustumNear { 0.1f };
25 float rangeNear { 0.1f };
26 float rangeFar { 200.0f };
27 float frustumFar { 10000.0f };
29 glm::ivec3 dims { 1, 1, 1 };
32 glm::mat4 eyeToGridProj;
33 glm::mat4 worldToEyeMat;
34 glm::mat4 eyeToWorldMat;
36 FrustumGrid() =
default;
37 FrustumGrid(
const FrustumGrid& source);
39 void updateFrustum(
const ViewFrustum& frustum) {
40 frustumNear = frustum.getNearClip();
41 frustumFar = frustum.getFarClip();
43 eyeToGridProj = frustum.evalProjectionMatrixRange(rangeNear, rangeFar);
46 frustum.evalViewTransform(view);
47 eyeToWorldMat = view.getMatrix();
48 worldToEyeMat = view.getInverseMatrix();
52 using vec3 = glm::vec3;
53 using ivec3 = glm::ivec3;
54 using mat4 = glm::mat4;
55 #define frustumGrid (*this)
56 #include "LightClusterGrid_shared.slh"
59 using Planes = std::vector < glm::vec4 >;
60 void generateGridPlanes(Planes& xPlanes, Planes& yPlanes, Planes& zPlanes);
67 using LightID = LightStage::Index;
69 static const glm::uvec4 MAX_GRID_DIMENSIONS;
73 void setDimensions(glm::uvec3 gridDims, uint32_t listBudget = MAX_GRID_DIMENSIONS.w);
74 void setRangeNearFar(
float rangeNear,
float rangeFar);
76 uint32_t getNumClusters()
const;
78 void updateFrustum(
const ViewFrustum& frustum);
80 void updateLightStage(
const LightStagePointer& lightStage);
82 void updateLightFrame(
const LightStage::FramePointer& lightFrame,
bool points =
true,
bool spots =
true);
84 glm::ivec3 updateClusters();
90 LightStagePointer _lightStage;
94 gpu::StructBuffer<FrustumGrid> _frustumGridBuffer;
96 FrustumGrid::Planes _gridPlanes[3];
98 LightStage::LightIndices _visibleLightIndices;
99 gpu::BufferView _lightIndicesBuffer;
101 const uint32_t EMPTY_CLUSTER { 0x0000FFFF };
102 const LightID INVALID_LIGHT { LightStage::INVALID_INDEX };
104 using LightIndex = uint16_t;
106 std::vector<uint32_t> _clusterGrid;
107 std::vector<LightIndex> _clusterContent;
108 gpu::BufferView _clusterGridBuffer;
109 gpu::BufferView _clusterContentBuffer;
110 uint32_t _clusterContentBudget { 0 };
112 bool _clusterResourcesInvalid {
true };
113 void updateClusterResource();
116 using LightClustersPointer = std::shared_ptr<LightClusters>;
120 class LightClusteringPassConfig :
public render::Job::Config {
122 Q_PROPERTY(
float rangeNear MEMBER rangeNear NOTIFY dirty)
123 Q_PROPERTY(
float rangeFar MEMBER rangeFar NOTIFY dirty)
125 Q_PROPERTY(
int dimX MEMBER dimX NOTIFY dirty)
126 Q_PROPERTY(
int dimY MEMBER dimY NOTIFY dirty)
127 Q_PROPERTY(
int dimZ MEMBER dimZ NOTIFY dirty)
129 Q_PROPERTY(
bool freeze MEMBER freeze NOTIFY dirty)
131 Q_PROPERTY(
int numClusteredLightReferences MEMBER numClusteredLightReferences NOTIFY dirty)
132 Q_PROPERTY(
int numInputLights MEMBER numInputLights NOTIFY dirty)
133 Q_PROPERTY(
int numClusteredLights MEMBER numClusteredLights NOTIFY dirty)
135 Q_PROPERTY(
int numSceneLights MEMBER numSceneLights NOTIFY dirty)
136 Q_PROPERTY(
int numFreeSceneLights MEMBER numFreeSceneLights NOTIFY dirty)
137 Q_PROPERTY(
int numAllocatedSceneLights MEMBER numAllocatedSceneLights NOTIFY dirty)
140 LightClusteringPassConfig() : render::Job::Config(true){}
141 float rangeNear{ 0.1f };
142 float rangeFar{ 200.0f };
149 bool freeze{
false };
151 int numClusteredLightReferences { 0 };
152 int numInputLights { 0 };
153 int numClusteredLights { 0 };
155 void setNumClusteredLightReferences(
int numRefs) { numClusteredLightReferences = numRefs; }
156 void setNumInputLights(
int numLights) { numInputLights = numLights; }
157 void setNumClusteredLights(
int numLights) { numClusteredLights = numLights; }
159 int numSceneLights { 0 };
160 int numFreeSceneLights { 0 };
161 int numAllocatedSceneLights { 0 };
168 class LightClusteringPass {
170 using Input = render::VaryingSet4<DeferredFrameTransformPointer, LightingModelPointer, LightStage::FramePointer, LinearDepthFramebufferPointer>;
171 using Output = LightClustersPointer;
172 using Config = LightClusteringPassConfig;
173 using JobModel = render::Job::ModelIO<LightClusteringPass, Input, Output, Config>;
175 LightClusteringPass();
177 void configure(
const Config& config);
179 void run(
const render::RenderContextPointer& renderContext,
const Input& input, Output& output);
182 LightClustersPointer _lightClusters;
192 class DebugLightClustersConfig :
public render::Job::Config {
194 Q_PROPERTY(
bool doDrawGrid MEMBER doDrawGrid NOTIFY dirty)
195 Q_PROPERTY(
bool doDrawClusterFromDepth MEMBER doDrawClusterFromDepth NOTIFY dirty)
196 Q_PROPERTY(
bool doDrawContent MEMBER doDrawContent NOTIFY dirty)
198 DebugLightClustersConfig() : render::Job::Config(false){}
201 bool doDrawGrid{
false };
202 bool doDrawClusterFromDepth {
false };
203 bool doDrawContent {
false };
212 #include "DeferredFramebuffer.h"
214 class DebugLightClusters {
216 using Inputs = render::VaryingSet4 < DeferredFrameTransformPointer, LightingModelPointer, LinearDepthFramebufferPointer, LightClustersPointer>;
217 using Config = DebugLightClustersConfig;
218 using JobModel = render::Job::ModelI<DebugLightClusters, Inputs, Config>;
220 DebugLightClusters();
222 void configure(
const Config& config);
224 void run(
const render::RenderContextPointer& renderContext,
const Inputs& inputs);
227 gpu::BufferPointer _gridBuffer;
228 gpu::PipelinePointer _drawClusterGrid;
229 gpu::PipelinePointer _drawClusterFromDepth;
230 gpu::PipelinePointer _drawClusterContent;
231 const gpu::PipelinePointer getDrawClusterGridPipeline();
232 const gpu::PipelinePointer getDrawClusterFromDepthPipeline();
233 const gpu::PipelinePointer getDrawClusterContentPipeline();
234 bool doDrawGrid {
false };
235 bool doDrawClusterFromDepth {
false };
236 bool doDrawContent {
false };