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 | |
11 | namespace 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 | |