1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsRenderBeastPrerequisites.h"
6#include "Renderer/BsRendererMaterial.h"
7#include "Renderer/BsParamBlocks.h"
8#include "Renderer/BsLight.h"
9#include "RenderAPI/BsGpuPipelineParamInfo.h"
10
11namespace bs
12{
13 class Bounds;
14
15namespace ct
16{
17 struct SceneInfo;
18 class RendererViewGroup;
19
20 /** @addtogroup RenderBeast
21 * @{
22 */
23
24 /** Maximum number of lights that can influence an object when basic forward rendering is used. */
25 static constexpr UINT32 STANDARD_FORWARD_MAX_NUM_LIGHTS = 8;
26
27 /** Information about a single light, as seen by the lighting shader. */
28 struct LightData
29 {
30 Vector3 position;
31 float boundsRadius;
32 Vector3 direction;
33 float luminance;
34 Vector3 spotAngles;
35 float attRadiusSqrdInv;
36 Vector3 color;
37 float srcRadius;
38 Vector3 shiftedLightPosition;
39 float padding;
40 };
41
42 /** Renderer information specific to a single light. */
43 class RendererLight
44 {
45 public:
46 RendererLight(Light* light);
47
48 /** Populates the structure with light parameters. */
49 void getParameters(LightData& output) const;
50
51 /**
52 * Populates the provided parameter block buffer with information about the light. Provided buffer's structure
53 * must match PerLightParamDef.
54 */
55 void getParameters(SPtr<GpuParamBlockBuffer>& buffer) const;
56
57 /**
58 * Calculates the light position that is shifted in order to account for area spot lights. For non-spot lights
59 * this method will return normal light position. The position will be shifted back from the light direction,
60 * magnitude of the shift depending on the source radius.
61 */
62 Vector3 getShiftedLightPosition() const;
63
64 Light* internal;
65 };
66
67 /** Container for all GBuffer textures. */
68 struct GBufferTextures
69 {
70 SPtr<Texture> albedo;
71 SPtr<Texture> normals;
72 SPtr<Texture> roughMetal;
73 SPtr<Texture> depth;
74 };
75
76 /** Allows you to easily bind GBuffer textures to some material. */
77 class GBufferParams
78 {
79 public:
80 GBufferParams(GpuProgramType type, const SPtr<GpuParams>& gpuParams);
81
82 /** Binds the GBuffer textures to the pipeline. */
83 void bind(const GBufferTextures& gbuffer);
84 private:
85 SPtr<GpuParams> mParams;
86
87 GpuParamTexture mGBufferA;
88 GpuParamTexture mGBufferB;
89 GpuParamTexture mGBufferC;
90 GpuParamTexture mGBufferDepth;
91 };
92
93 /** Helper struct containing all parameters required for forward lighting. */
94 struct ForwardLightingParams
95 {
96 /**
97 * Initializes the parameters from the provided parameters.
98 *
99 * @param[in] params GPU parameters object to look for the parameters in.
100 * @param[in] clustered If true, set up parameters for clustered forward rendering. If false, set up parameters
101 * for normal forward rendering.
102 */
103 void populate(const SPtr<GpuParams>& params, bool clustered);
104
105 /** Binding indices representing where should lights param block buffer be bound to. */
106 GpuParamBinding gridParamsBindings[GPT_COUNT];
107
108 /**
109 * Parameter to which to bind a buffer containing light grid offsets and size, per grid cell. Used for forward
110 * rendering.
111 */
112 GpuParamBuffer gridLightOffsetsAndSizeParam;
113
114 /** Parameter to which to bind a buffer containing all light indices, as mapped by grid offsets & size. */
115 GpuParamBuffer gridLightIndicesParam;
116
117 /** Parameter to which to bind light buffer used for forward rendering. */
118 GpuParamBuffer lightsBufferParam;
119
120 /**
121 * Parameter to which to bind a buffer containing reflection probe grid offsets and size, per grid cell. Used for
122 * forward rendering.
123 */
124 GpuParamBuffer gridProbeOffsetsAndSizeParam;
125
126 /**
127 * Binding for a parameter block containing a list of lights influencing this object. Only used when standard
128 * (non-clustered) forward rendering is used.
129 */
130 GpuParamBinding lightsParamBlockBinding;
131
132 /**
133 * Binding for a parameter block that contains the number of lights and reflection probes in the light/refl. probe
134 * parameter blocks. Only used when standard (non-clustered) forward rendering is used.
135 */
136 GpuParamBinding lightAndReflProbeParamsParamBlockBinding;
137 };
138
139 /**
140 * Contains lights that are visible from a specific set of views, determined by scene information provided to
141 * setLights().
142 */
143 class VisibleLightData
144 {
145 public:
146 VisibleLightData();
147
148 /**
149 * Updates the internal buffers with a new set of lights. Before calling make sure that light visibility has
150 * been calculated for the provided view group.
151 */
152 void update(const SceneInfo& sceneInfo, const RendererViewGroup& viewGroup);
153
154 /** Returns a GPU bindable buffer containing information about every light. */
155 SPtr<GpuBuffer> getLightBuffer() const { return mLightBuffer; }
156
157 /**
158 * Scans the list of lights visible in the view frustum to find the ones influencing the object described by
159 * the provided bounds. A maximum number of STANDARD_FORWARD_MAX_NUM_LIGHTS will be output. If there are more
160 * influencing lights, only the most important ones will be returned.
161 *
162 * The lights will be output in the following order: directional, radial, spot. @p counts will contain the number
163 * of directional lights (component 'x'), number of radial lights (component 'y') and number of spot lights
164 * (component 'z');
165 *
166 * update() must have been called with most recent scene/view information before calling this method.
167 */
168 void gatherInfluencingLights(const Bounds& bounds, const LightData* (&output)[STANDARD_FORWARD_MAX_NUM_LIGHTS],
169 Vector3I& counts) const;
170
171 /** Returns the number of directional lights in the lights buffer. */
172 UINT32 getNumDirLights() const { return mNumLights[0]; }
173
174 /** Returns the number of radial point lights in the lights buffer. */
175 UINT32 getNumRadialLights() const { return mNumLights[1]; }
176
177 /** Returns the number of spot point lights in the lights buffer. */
178 UINT32 getNumSpotLights() const { return mNumLights[2]; }
179
180 /** Returns the number of visible lights of the specified type. */
181 UINT32 getNumLights(LightType type) const { return mNumLights[(UINT32)type]; }
182
183 /** Returns the number of visible shadowed lights of the specified type. */
184 UINT32 getNumShadowedLights(LightType type) const { return mNumShadowedLights[(UINT32)type]; }
185
186 /** Returns the number of visible unshadowed lights of the specified type. */
187 UINT32 getNumUnshadowedLights(LightType type) const { return mNumLights[(UINT32)type] - mNumShadowedLights[(UINT32)type]; }
188
189 /** Returns a list of all visible lights of the specified type. */
190 const Vector<const RendererLight*>& getLights(LightType type) const { return mVisibleLights[(UINT32)type]; }
191 private:
192 SPtr<GpuBuffer> mLightBuffer;
193
194 UINT32 mNumLights[(UINT32)LightType::Count];
195 UINT32 mNumShadowedLights[(UINT32)LightType::Count];
196
197 // These are rebuilt every call to update()
198 Vector<const RendererLight*> mVisibleLights[(UINT32)LightType::Count];
199 Vector<LightData> mVisibleLightData;
200 };
201
202 BS_PARAM_BLOCK_BEGIN(LightsParamDef)
203 BS_PARAM_BLOCK_ENTRY_ARRAY(LightData, gLights, STANDARD_FORWARD_MAX_NUM_LIGHTS)
204 BS_PARAM_BLOCK_END
205
206 extern LightsParamDef gLightsParamDef;
207
208 BS_PARAM_BLOCK_BEGIN(LightAndReflProbeParamsParamDef)
209 BS_PARAM_BLOCK_ENTRY(Vector4I, gLightOffsets)
210 BS_PARAM_BLOCK_ENTRY(int, gReflProbeCount)
211 BS_PARAM_BLOCK_END
212
213 extern LightAndReflProbeParamsParamDef gLightAndReflProbeParamsParamDef;
214
215 /** @} */
216}}
217