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 "Utility/BsModule.h"
7#include "Renderer/BsRendererMaterial.h"
8#include "BsRendererLight.h"
9#include "BsRendererReflectionProbe.h"
10
11namespace bs { namespace ct {
12 class RendererLight;
13
14 BS_PARAM_BLOCK_BEGIN(PerLightParamDef)
15 BS_PARAM_BLOCK_ENTRY(Vector4, gLightPositionAndSrcRadius)
16 BS_PARAM_BLOCK_ENTRY(Vector4, gLightColorAndLuminance)
17 BS_PARAM_BLOCK_ENTRY(Vector4, gLightSpotAnglesAndSqrdInvAttRadius)
18 BS_PARAM_BLOCK_ENTRY(Vector4, gLightDirectionAndBoundRadius)
19 BS_PARAM_BLOCK_ENTRY(Vector4, gShiftedLightPositionAndType)
20 BS_PARAM_BLOCK_ENTRY(Vector4, gLightGeometry)
21 BS_PARAM_BLOCK_ENTRY(Matrix4, gMatConeTransform)
22 BS_PARAM_BLOCK_END
23
24 extern PerLightParamDef gPerLightParamDef;
25
26 /** Shader that renders directional light sources during deferred rendering light pass. */
27 class DeferredDirectionalLightMat : public RendererMaterial<DeferredDirectionalLightMat>
28 {
29 RMAT_DEF("DeferredDirectionalLight.bsl");
30
31 /** Helper method used for initializing variations of this material. */
32 template<bool msaa, bool singleSampleMSAA>
33 static const ShaderVariation& getVariation()
34 {
35 static ShaderVariation variation = ShaderVariation(
36 {
37 ShaderVariation::Param("MSAA", msaa),
38 ShaderVariation::Param("MSAA_RESOLVE_0TH", singleSampleMSAA)
39 });
40
41 return variation;
42 }
43 public:
44 DeferredDirectionalLightMat();
45
46 /** Binds the material for rendering and sets up any parameters. */
47 void bind(const GBufferTextures& gBufferInput, const SPtr<Texture>& lightOcclusion,
48 const SPtr<GpuParamBlockBuffer>& perCamera, const SPtr<GpuParamBlockBuffer>& perLight);
49
50 /**
51 * Returns the material variation matching the provided parameters.
52 *
53 * @param[in] msaa True if the shader will operate on a multisampled surface.
54 * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be
55 * evaluated. Otherwise all samples will be evaluated.
56 * @return Requested variation of the material.
57 */
58 static DeferredDirectionalLightMat* getVariation(bool msaa, bool singleSampleMSAA = false);
59 private:
60 GBufferParams mGBufferParams;
61 GpuParamTexture mLightOcclusionTexParam;
62 };
63
64 /** Shader that renders point (radial & spot) light sources during deferred rendering light pass. */
65 class DeferredPointLightMat : public RendererMaterial<DeferredPointLightMat>
66 {
67 RMAT_DEF("DeferredPointLight.bsl");
68
69 /** Helper method used for initializing variations of this material. */
70 template<bool inside, bool msaa, bool singleSampleMSAA>
71 static const ShaderVariation& getVariation()
72 {
73 static ShaderVariation variation = ShaderVariation(
74 {
75 ShaderVariation::Param("MSAA", msaa),
76 ShaderVariation::Param("INSIDE_GEOMETRY", inside),
77 ShaderVariation::Param("MSAA_RESOLVE_0TH", singleSampleMSAA)
78 });
79
80 return variation;
81 }
82 public:
83 DeferredPointLightMat();
84
85 /** Binds the material for rendering and sets up any parameters. */
86 void bind(const GBufferTextures& gBufferInput, const SPtr<Texture>& lightOcclusion,
87 const SPtr<GpuParamBlockBuffer>& perCamera, const SPtr<GpuParamBlockBuffer>& perLight);
88
89 /**
90 * Returns the material variation matching the provided parameters.
91 *
92 * @param[in] inside Set to true if viewer is inside the light's stencil geometry.
93 * @param[in] msaa True if the shader will operate on a multisampled surface.
94 * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be
95 * evaluated. Otherwise all samples will be evaluated.
96 * @return Requested variation of the material.
97 */
98 static DeferredPointLightMat* getVariation(bool inside, bool msaa, bool singleSampleMSAA = false);
99 private:
100 GBufferParams mGBufferParams;
101 GpuParamTexture mLightOcclusionTexParam;
102 };
103
104 BS_PARAM_BLOCK_BEGIN(PerProbeParamDef)
105 BS_PARAM_BLOCK_ENTRY(Vector3, gPosition)
106 BS_PARAM_BLOCK_ENTRY(Vector3, gExtents)
107 BS_PARAM_BLOCK_ENTRY(float, gTransitionDistance)
108 BS_PARAM_BLOCK_ENTRY(Matrix4, gInvBoxTransform)
109 BS_PARAM_BLOCK_ENTRY(INT32, gCubemapIdx)
110 BS_PARAM_BLOCK_ENTRY(INT32, gType)
111 BS_PARAM_BLOCK_END
112
113 extern PerProbeParamDef gPerProbeParamDef;
114
115 /**
116 * Shader that prepares the surface for image based lighting.
117 *
118 * This is an alternative to TiledDeferredImageBasedLighting for cases when compute shaders are not usable or suitable.
119 * Needs to be followed by execution of all other DeferredIBL* materials.
120 */
121 class DeferredIBLSetupMat : public RendererMaterial<DeferredIBLSetupMat>
122 {
123 RMAT_DEF("DeferredIBLSetup.bsl");
124
125 /** Helper method used for initializing variations of this material. */
126 template<bool msaa, bool singleSampleMSAA>
127 static const ShaderVariation& getVariation()
128 {
129 static ShaderVariation variation = ShaderVariation(
130 {
131 ShaderVariation::Param("MSAA", msaa),
132 ShaderVariation::Param("MSAA_RESOLVE_0TH", singleSampleMSAA)
133 });
134
135 return variation;
136 }
137 public:
138 DeferredIBLSetupMat();
139
140 /** Binds the material for rendering and sets up any parameters. */
141 void bind(const GBufferTextures& gBufferInput, const SPtr<GpuParamBlockBuffer>& perCamera,
142 const SPtr<Texture>& ssr, const SPtr<Texture>& ao, const SPtr<GpuParamBlockBuffer>& reflProbeParams);
143
144 /**
145 * Returns the material variation matching the provided parameters.
146 *
147 * @param[in] msaa True if the shader will operate on a multisampled surface.
148 * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be
149 * evaluated. Otherwise all samples will be evaluated.
150 * @return Requested variation of the material.
151 */
152 static DeferredIBLSetupMat* getVariation(bool msaa, bool singleSampleMSAA = false);
153 private:
154 GBufferParams mGBufferParams;
155 ImageBasedLightingParams mIBLParams;
156 };
157
158 /**
159 * Shader that renders an individual reflection probe for image based lighting.
160 *
161 * This is an alternative to TiledDeferredImageBasedLighting for cases when compute shaders are not usable or suitable.
162 * Must be preceeded by DeferredIBLSetupMat and followed by DeferredIBLSkyMat and DeferredIBLFinalizeMat.
163 */
164 class DeferredIBLProbeMat : public RendererMaterial<DeferredIBLProbeMat>
165 {
166 RMAT_DEF("DeferredIBLProbe.bsl");
167
168 /** Helper method used for initializing variations of this material. */
169 template<bool inside, bool msaa, bool singleSampleMSAA>
170 static const ShaderVariation& getVariation()
171 {
172 static ShaderVariation variation = ShaderVariation(
173 {
174 ShaderVariation::Param("MSAA", msaa),
175 ShaderVariation::Param("INSIDE_GEOMETRY", inside),
176 ShaderVariation::Param("MSAA_RESOLVE_0TH", singleSampleMSAA)
177 });
178
179 return variation;
180 }
181 public:
182 DeferredIBLProbeMat();
183
184 /** Binds the material for rendering and sets up any parameters. */
185 void bind(const GBufferTextures& gBufferInput, const SPtr<GpuParamBlockBuffer>& perCamera,
186 const SceneInfo& sceneInfo, const ReflProbeData& probeData, const SPtr<GpuParamBlockBuffer>& reflProbeParams);
187
188 /**
189 * Returns the material variation matching the provided parameters.
190 *
191 * @param[in] inside Set to true if viewer is inside the probe's stencil geometry.
192 * @param[in] msaa True if the shader will operate on a multisampled surface.
193 * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be
194 * evaluated. Otherwise all samples will be evaluated.
195 * @return Requested variation of the material.
196 */
197 static DeferredIBLProbeMat* getVariation(bool inside, bool msaa, bool singleSampleMSAA = false);
198 private:
199 SPtr<GpuParamBlockBuffer> mParamBuffer;
200 GBufferParams mGBufferParams;
201 ImageBasedLightingParams mIBLParams;
202 };
203
204 /**
205 * Shader that renders the sky reflections. The results are additively blended with the currently bound render target.
206 *
207 * This is an alternative to TiledDeferredImageBasedLighting for cases when compute shaders are not usable or suitable.
208 * Must be preceeded by DeferredIBLSetupMat and followed by DeferredIBLFinalizeMat.
209 */
210 class DeferredIBLSkyMat : public RendererMaterial<DeferredIBLSkyMat>
211 {
212 RMAT_DEF("DeferredIBLSky.bsl");
213
214 /** Helper method used for initializing variations of this material. */
215 template<bool msaa, bool singleSampleMSAA>
216 static const ShaderVariation& getVariation()
217 {
218 static ShaderVariation variation = ShaderVariation(
219 {
220 ShaderVariation::Param("MSAA", msaa),
221 ShaderVariation::Param("MSAA_RESOLVE_0TH", singleSampleMSAA)
222 });
223
224 return variation;
225 }
226 public:
227 DeferredIBLSkyMat();
228
229 /** Binds the material for rendering and sets up any parameters. */
230 void bind(const GBufferTextures& gBufferInput, const SPtr<GpuParamBlockBuffer>& perCamera,
231 const Skybox* skybox, const SPtr<GpuParamBlockBuffer>& reflProbeParams);
232
233 /**
234 * Returns the material variation matching the provided parameters.
235 *
236 * @param[in] msaa True if the shader will operate on a multisampled surface.
237 * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be
238 * evaluated. Otherwise all samples will be evaluated.
239 * @return Requested variation of the material.
240 */
241 static DeferredIBLSkyMat* getVariation(bool msaa, bool singleSampleMSAA = false);
242 private:
243 GBufferParams mGBufferParams;
244 ImageBasedLightingParams mIBLParams;
245 };
246
247 /**
248 * Material that finalizes the rendering of reflections. As input it takes the texture output by previous DeferredIBL*
249 * materials, and the resulting output is blended additively with the current render target.
250 *
251 * This is an alternative to TiledDeferredImageBasedLighting for cases when compute shaders are not usable or suitable.
252 */
253 class DeferredIBLFinalizeMat : public RendererMaterial<DeferredIBLFinalizeMat>
254 {
255 RMAT_DEF("DeferredIBLFinalize.bsl");
256
257 /** Helper method used for initializing variations of this material. */
258 template<bool msaa, bool singleSampleMSAA>
259 static const ShaderVariation& getVariation()
260 {
261 static ShaderVariation variation = ShaderVariation(
262 {
263 ShaderVariation::Param("MSAA", msaa),
264 ShaderVariation::Param("MSAA_RESOLVE_0TH", singleSampleMSAA)
265 });
266
267 return variation;
268 }
269 public:
270 DeferredIBLFinalizeMat();
271
272 /** Binds the material for rendering and sets up any parameters. */
273 void bind(const GBufferTextures& gBufferInput, const SPtr<GpuParamBlockBuffer>& perCamera,
274 const SPtr<Texture>& iblRadiance, const SPtr<Texture>& preintegratedBrdf,
275 const SPtr<GpuParamBlockBuffer>& reflProbeParams);
276
277 /**
278 * Returns the material variation matching the provided parameters.
279 *
280 * @param[in] msaa True if the shader will operate on a multisampled surface.
281 * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be
282 * evaluated. Otherwise all samples will be evaluated.
283 * @return Requested variation of the material.
284 */
285 static DeferredIBLFinalizeMat* getVariation(bool msaa, bool singleSampleMSAA = false);
286 private:
287 GBufferParams mGBufferParams;
288 ImageBasedLightingParams mIBLParams;
289 GpuParamTexture mIBLRadiance;
290 };
291
292 /** Provides functionality for standard (non-tiled) deferred rendering. */
293 class StandardDeferred : public Module<StandardDeferred>
294 {
295 public:
296 StandardDeferred();
297
298 /** Calculates lighting for the specified light, using the standard deferred renderer. */
299 void renderLight(LightType type, const RendererLight& light, const RendererView& view,
300 const GBufferTextures& gBufferInput, const SPtr<Texture>& lightOcclusion);
301
302 /**
303 * Evaluates filtered radiance from a single reflection probe and blends it into the current render target.
304 * Alpha value of the render target is used for determining the contribution and will be updated with new
305 * contibution after blending.
306 */
307 void renderReflProbe(const ReflProbeData& probeData, const RendererView& view,
308 const GBufferTextures& gBufferInput, const SceneInfo& sceneInfo,
309 const SPtr<GpuParamBlockBuffer>& reflProbeParams);
310
311 private:
312 SPtr<GpuParamBlockBuffer> mPerLightBuffer;
313 };
314}}
315