| 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/BsRenderSettings.h" |
| 9 | #include "Renderer/BsGpuResourcePool.h" |
| 10 | #include "BsRendererLight.h" |
| 11 | |
| 12 | namespace bs { namespace ct |
| 13 | { |
| 14 | struct RendererViewTargetData; |
| 15 | |
| 16 | /** @addtogroup RenderBeast |
| 17 | * @{ |
| 18 | */ |
| 19 | |
| 20 | BS_PARAM_BLOCK_BEGIN(DownsampleParamDef) |
| 21 | BS_PARAM_BLOCK_ENTRY_ARRAY(Vector2, gOffsets, 4) |
| 22 | BS_PARAM_BLOCK_END |
| 23 | |
| 24 | extern DownsampleParamDef gDownsampleParamDef; |
| 25 | |
| 26 | /** Shader that downsamples a texture to half its size. */ |
| 27 | class DownsampleMat : public RendererMaterial<DownsampleMat> |
| 28 | { |
| 29 | RMAT_DEF("PPDownsample.bsl" ); |
| 30 | |
| 31 | /** Helper method used for initializing variations of this material. */ |
| 32 | template<UINT32 quality, bool MSAA> |
| 33 | static const ShaderVariation& getVariation() |
| 34 | { |
| 35 | static ShaderVariation variation = ShaderVariation( |
| 36 | { |
| 37 | ShaderVariation::Param("QUALITY" , quality), |
| 38 | ShaderVariation::Param("MSAA" , MSAA) |
| 39 | }); |
| 40 | |
| 41 | return variation; |
| 42 | }; |
| 43 | |
| 44 | public: |
| 45 | DownsampleMat(); |
| 46 | |
| 47 | /** Renders the post-process effect with the provided parameters. */ |
| 48 | void execute(const SPtr<Texture>& input, const SPtr<RenderTarget>& output); |
| 49 | |
| 50 | /** Returns the texture descriptor that can be used for initializing the output render target. */ |
| 51 | static POOLED_RENDER_TEXTURE_DESC getOutputDesc(const SPtr<Texture>& target); |
| 52 | |
| 53 | /** Returns the downsample material variation matching the provided parameters. */ |
| 54 | static DownsampleMat* getVariation(UINT32 quality, bool msaa); |
| 55 | |
| 56 | private: |
| 57 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 58 | GpuParamTexture mInputTexture; |
| 59 | }; |
| 60 | |
| 61 | BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramParamDef) |
| 62 | BS_PARAM_BLOCK_ENTRY(Vector4I, gPixelOffsetAndSize) |
| 63 | BS_PARAM_BLOCK_ENTRY(Vector2, gHistogramParams) |
| 64 | BS_PARAM_BLOCK_ENTRY(Vector2I, gThreadGroupCount) |
| 65 | BS_PARAM_BLOCK_END |
| 66 | |
| 67 | extern EyeAdaptHistogramParamDef gEyeAdaptHistogramParamDef; |
| 68 | |
| 69 | /** Shader that creates a luminance histogram used for eye adaptation. */ |
| 70 | class EyeAdaptHistogramMat : public RendererMaterial<EyeAdaptHistogramMat> |
| 71 | { |
| 72 | RMAT_DEF_CUSTOMIZED("PPEyeAdaptHistogram.bsl" ); |
| 73 | |
| 74 | public: |
| 75 | EyeAdaptHistogramMat(); |
| 76 | |
| 77 | /** Executes the post-process effect with the provided parameters. */ |
| 78 | void execute(const SPtr<Texture>& input, const SPtr<Texture>& output, const AutoExposureSettings& settings); |
| 79 | |
| 80 | /** Returns the texture descriptor that can be used for initializing the output render target. */ |
| 81 | static POOLED_RENDER_TEXTURE_DESC getOutputDesc(const SPtr<Texture>& target); |
| 82 | |
| 83 | /** Calculates the number of thread groups that need to execute to cover the provided texture. */ |
| 84 | static Vector2I getThreadGroupCount(const SPtr<Texture>& target); |
| 85 | |
| 86 | /** |
| 87 | * Returns a vector containing scale and offset (in that order) that will be applied to luminance values |
| 88 | * to determine their position in the histogram. |
| 89 | */ |
| 90 | static Vector2 getHistogramScaleOffset(const AutoExposureSettings& settings); |
| 91 | |
| 92 | static const UINT32 THREAD_GROUP_SIZE_X = 8; |
| 93 | static const UINT32 THREAD_GROUP_SIZE_Y = 8; |
| 94 | |
| 95 | static const UINT32 HISTOGRAM_NUM_TEXELS = (THREAD_GROUP_SIZE_X * THREAD_GROUP_SIZE_Y) / 4; |
| 96 | private: |
| 97 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 98 | GpuParamTexture mSceneColor; |
| 99 | GpuParamLoadStoreTexture mOutputTex; |
| 100 | |
| 101 | static const UINT32 LOOP_COUNT_X = 8; |
| 102 | static const UINT32 LOOP_COUNT_Y = 8; |
| 103 | }; |
| 104 | |
| 105 | BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramReduceParamDef) |
| 106 | BS_PARAM_BLOCK_ENTRY(int, gThreadGroupCount) |
| 107 | BS_PARAM_BLOCK_END |
| 108 | |
| 109 | extern EyeAdaptHistogramReduceParamDef gEyeAdaptHistogramReduceParamDef; |
| 110 | |
| 111 | /** Shader that reduces the luminance histograms created by EyeAdaptHistogramMat into a single histogram. */ |
| 112 | class EyeAdaptHistogramReduceMat : public RendererMaterial<EyeAdaptHistogramReduceMat> |
| 113 | { |
| 114 | RMAT_DEF("PPEyeAdaptHistogramReduce.bsl" ); |
| 115 | |
| 116 | public: |
| 117 | EyeAdaptHistogramReduceMat(); |
| 118 | |
| 119 | /** Executes the post-process effect with the provided parameters. */ |
| 120 | void execute(const SPtr<Texture>& sceneColor, const SPtr<Texture>& histogram, const SPtr<Texture>& prevFrame, |
| 121 | const SPtr<RenderTarget>& output); |
| 122 | |
| 123 | /** Returns the texture descriptor that can be used for initializing the output render target. */ |
| 124 | static POOLED_RENDER_TEXTURE_DESC getOutputDesc(); |
| 125 | private: |
| 126 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 127 | |
| 128 | GpuParamTexture mHistogramTex; |
| 129 | GpuParamTexture mEyeAdaptationTex; |
| 130 | }; |
| 131 | |
| 132 | BS_PARAM_BLOCK_BEGIN(EyeAdaptationParamDef) |
| 133 | BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gEyeAdaptationParams, 3) |
| 134 | BS_PARAM_BLOCK_END |
| 135 | |
| 136 | extern EyeAdaptationParamDef gEyeAdaptationParamDef; |
| 137 | |
| 138 | /** Shader that computes the eye adaptation value based on scene luminance. */ |
| 139 | class EyeAdaptationMat : public RendererMaterial<EyeAdaptationMat> |
| 140 | { |
| 141 | RMAT_DEF_CUSTOMIZED("PPEyeAdaptation.bsl" ); |
| 142 | |
| 143 | public: |
| 144 | EyeAdaptationMat(); |
| 145 | |
| 146 | /** Executes the post-process effect with the provided parameters. */ |
| 147 | void execute(const SPtr<Texture>& reducedHistogram, const SPtr<RenderTarget>& output, float frameDelta, |
| 148 | const AutoExposureSettings& settings, float exposureScale); |
| 149 | |
| 150 | /** Returns the texture descriptor that can be used for initializing the output render target. */ |
| 151 | static POOLED_RENDER_TEXTURE_DESC getOutputDesc(); |
| 152 | |
| 153 | /** |
| 154 | * Populates the provided paramater buffer with eye adaptation parameters. The parameter buffer is expected to be |
| 155 | * created with EyeAdaptationParamDef block definition. |
| 156 | */ |
| 157 | static void populateParams(const SPtr<GpuParamBlockBuffer>& paramBuffer, float frameDelta, |
| 158 | const AutoExposureSettings& settings, float exposureScale); |
| 159 | private: |
| 160 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 161 | GpuParamTexture mReducedHistogramTex; |
| 162 | }; |
| 163 | |
| 164 | /** |
| 165 | * Shader that computes luminance of all the pixels in the provided texture, and stores them in log2 format, scaled |
| 166 | * to [0, 1] range (according to eye adapatation parameters) and stores those values in the alpha channel of the |
| 167 | * output texture. Color channel is just a copy of the input texture. Resulting texture is intended to be provided |
| 168 | * to the downsampling shader in order to calculate the average luminance, used for non-histogram eye adaptation |
| 169 | * calculation (when compute shader is not available). |
| 170 | */ |
| 171 | class EyeAdaptationBasicSetupMat : public RendererMaterial<EyeAdaptationBasicSetupMat> |
| 172 | { |
| 173 | RMAT_DEF("PPEyeAdaptationBasicSetup.bsl" ); |
| 174 | |
| 175 | public: |
| 176 | EyeAdaptationBasicSetupMat(); |
| 177 | |
| 178 | /** Executes the post-process effect with the provided parameters. */ |
| 179 | void execute(const SPtr<Texture>& input, const SPtr<RenderTarget>& output, float frameDelta, |
| 180 | const AutoExposureSettings& settings, float exposureScale); |
| 181 | |
| 182 | /** Returns the texture descriptor that can be used for initializing the output render target. */ |
| 183 | static POOLED_RENDER_TEXTURE_DESC getOutputDesc(const SPtr<Texture>& input); |
| 184 | private: |
| 185 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 186 | GpuParamTexture mInputTex; |
| 187 | }; |
| 188 | |
| 189 | BS_PARAM_BLOCK_BEGIN(EyeAdaptationBasicParamsMatDef) |
| 190 | BS_PARAM_BLOCK_ENTRY(Vector2I, gInputTexSize) |
| 191 | BS_PARAM_BLOCK_END |
| 192 | |
| 193 | extern EyeAdaptationBasicParamsMatDef gEyeAdaptationBasicParamsMatDef; |
| 194 | |
| 195 | /** |
| 196 | * Shader that computes eye adapatation value from a texture that has luminance encoded in its alpha channel (as done |
| 197 | * by EyeAdaptationBasicSetupMat). The result is a 1x1 texture containing the eye adaptation value. |
| 198 | */ |
| 199 | class EyeAdaptationBasicMat : public RendererMaterial<EyeAdaptationBasicMat> |
| 200 | { |
| 201 | RMAT_DEF("PPEyeAdaptationBasic.bsl" ); |
| 202 | |
| 203 | public: |
| 204 | EyeAdaptationBasicMat(); |
| 205 | |
| 206 | /** Executes the post-process effect with the provided parameters. */ |
| 207 | void execute(const SPtr<Texture>& curFrame, const SPtr<Texture>& prevFrame, const SPtr<RenderTarget>& output, |
| 208 | float frameDelta, const AutoExposureSettings& settings, float exposureScale); |
| 209 | |
| 210 | /** Returns the texture descriptor that can be used for initializing the output render target. */ |
| 211 | static POOLED_RENDER_TEXTURE_DESC getOutputDesc(); |
| 212 | private: |
| 213 | SPtr<GpuParamBlockBuffer> mEyeAdaptationParamsBuffer; |
| 214 | SPtr<GpuParamBlockBuffer> mParamsBuffer; |
| 215 | GpuParamTexture mCurFrameTexParam; |
| 216 | GpuParamTexture mPrevFrameTexParam; |
| 217 | }; |
| 218 | |
| 219 | BS_PARAM_BLOCK_BEGIN(CreateTonemapLUTParamDef) |
| 220 | BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gTonemapParams, 2) |
| 221 | BS_PARAM_BLOCK_ENTRY(float, gGammaAdjustment) |
| 222 | BS_PARAM_BLOCK_ENTRY(int, gGammaCorrectionType) |
| 223 | BS_PARAM_BLOCK_ENTRY(Vector3, gSaturation) |
| 224 | BS_PARAM_BLOCK_ENTRY(Vector3, gContrast) |
| 225 | BS_PARAM_BLOCK_ENTRY(Vector3, gGain) |
| 226 | BS_PARAM_BLOCK_ENTRY(Vector3, gOffset) |
| 227 | BS_PARAM_BLOCK_END |
| 228 | |
| 229 | extern CreateTonemapLUTParamDef gCreateTonemapLUTParamDef; |
| 230 | |
| 231 | BS_PARAM_BLOCK_BEGIN(WhiteBalanceParamDef) |
| 232 | BS_PARAM_BLOCK_ENTRY(float, gWhiteTemp) |
| 233 | BS_PARAM_BLOCK_ENTRY(float, gWhiteOffset) |
| 234 | BS_PARAM_BLOCK_END |
| 235 | |
| 236 | extern WhiteBalanceParamDef gWhiteBalanceParamDef; |
| 237 | |
| 238 | /** |
| 239 | * Shader that creates a 3D lookup texture that is used to apply tonemapping, color grading, white balancing and gamma |
| 240 | * correction. |
| 241 | */ |
| 242 | class CreateTonemapLUTMat : public RendererMaterial<CreateTonemapLUTMat> |
| 243 | { |
| 244 | RMAT_DEF_CUSTOMIZED("PPCreateTonemapLUT.bsl" ); |
| 245 | |
| 246 | /** Helper method used for initializing variations of this material. */ |
| 247 | template<bool is3D> |
| 248 | static const ShaderVariation& getVariation() |
| 249 | { |
| 250 | static ShaderVariation variation = ShaderVariation( |
| 251 | { |
| 252 | ShaderVariation::Param("VOLUME_LUT" , is3D), |
| 253 | }); |
| 254 | |
| 255 | return variation; |
| 256 | }; |
| 257 | |
| 258 | public: |
| 259 | CreateTonemapLUTMat(); |
| 260 | |
| 261 | /** |
| 262 | * Executes the post-process effect with the provided parameters, generating a 3D LUT using a compute shader. |
| 263 | * Should only be called on the appropriate variation (3D one). |
| 264 | */ |
| 265 | void execute3D(const SPtr<Texture>& output, const RenderSettings& settings); |
| 266 | |
| 267 | /** |
| 268 | * Executes the post-process effect with the provided parameters, generating an unwrapped 2D LUT without the use |
| 269 | * of a compute shader. Should only be called on the appropriate variation (non-3D one). |
| 270 | */ |
| 271 | void execute2D(const SPtr<RenderTexture>& output, const RenderSettings& settings); |
| 272 | |
| 273 | /** Returns the texture descriptor that can be used for initializing the output render target. */ |
| 274 | POOLED_RENDER_TEXTURE_DESC getOutputDesc() const; |
| 275 | |
| 276 | /** |
| 277 | * Returns the material variation matching the provided parameters. |
| 278 | * |
| 279 | * @param[in] is3D If true the material will generate a 3D LUT using a compute shader. Otherwise it will |
| 280 | * generate an unwrapped 2D LUT withou the use of a compute shader. Depending on this parameter |
| 281 | * you should call either execute3D() or execute2D() methods to render the material. |
| 282 | */ |
| 283 | static CreateTonemapLUTMat* getVariation(bool is3D); |
| 284 | |
| 285 | /** Size of the 3D color lookup table. */ |
| 286 | static const UINT32 LUT_SIZE = 32; |
| 287 | private: |
| 288 | /** Populates the parameter block buffers using the provided settings. */ |
| 289 | void populateParamBuffers(const RenderSettings& settings); |
| 290 | |
| 291 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 292 | SPtr<GpuParamBlockBuffer> mWhiteBalanceParamBuffer; |
| 293 | |
| 294 | GpuParamLoadStoreTexture mOutputTex; |
| 295 | bool mIs3D; |
| 296 | }; |
| 297 | |
| 298 | BS_PARAM_BLOCK_BEGIN(TonemappingParamDef) |
| 299 | BS_PARAM_BLOCK_ENTRY(float, gRawGamma) |
| 300 | BS_PARAM_BLOCK_ENTRY(float, gManualExposureScale) |
| 301 | BS_PARAM_BLOCK_ENTRY(Vector2, gTexSize) |
| 302 | BS_PARAM_BLOCK_ENTRY(Color, gBloomTint) |
| 303 | BS_PARAM_BLOCK_ENTRY(int, gNumSamples) |
| 304 | BS_PARAM_BLOCK_END |
| 305 | |
| 306 | extern TonemappingParamDef gTonemappingParamDef; |
| 307 | |
| 308 | /** Shader that applies tonemapping and converts a HDR image into a LDR image. */ |
| 309 | class TonemappingMat : public RendererMaterial<TonemappingMat> |
| 310 | { |
| 311 | RMAT_DEF_CUSTOMIZED("PPTonemapping.bsl" ); |
| 312 | |
| 313 | /** Helper method used for initializing variations of this material. */ |
| 314 | template<bool volumeLUT, bool gammaOnly, bool autoExposure, bool MSAA> |
| 315 | static const ShaderVariation& getVariation() |
| 316 | { |
| 317 | static ShaderVariation variation = ShaderVariation( |
| 318 | { |
| 319 | ShaderVariation::Param("VOLUME_LUT" , volumeLUT), |
| 320 | ShaderVariation::Param("GAMMA_ONLY" , gammaOnly), |
| 321 | ShaderVariation::Param("AUTO_EXPOSURE" , autoExposure), |
| 322 | ShaderVariation::Param("MSAA" , MSAA), |
| 323 | }); |
| 324 | |
| 325 | return variation; |
| 326 | } |
| 327 | public: |
| 328 | TonemappingMat(); |
| 329 | |
| 330 | /** Executes the post-process effect with the provided parameters. */ |
| 331 | void execute(const SPtr<Texture>& sceneColor, const SPtr<Texture>& eyeAdaptation, const SPtr<Texture>& bloom, |
| 332 | const SPtr<Texture>& colorLUT, const SPtr<RenderTarget>& output, const RenderSettings& settings); |
| 333 | |
| 334 | /** Returns the material variation matching the provided parameters. */ |
| 335 | static TonemappingMat* getVariation(bool volumeLUT, bool gammaOnly, bool autoExposure, bool MSAA); |
| 336 | |
| 337 | private: |
| 338 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 339 | |
| 340 | GpuParamTexture mInputTex; |
| 341 | GpuParamTexture mBloomTex; |
| 342 | GpuParamTexture mColorLUT; |
| 343 | GpuParamTexture mEyeAdaptationTex; |
| 344 | }; |
| 345 | |
| 346 | BS_PARAM_BLOCK_BEGIN(BloomClipParamDef) |
| 347 | BS_PARAM_BLOCK_ENTRY(float, gThreshold) |
| 348 | BS_PARAM_BLOCK_ENTRY(float, gManualExposureScale) |
| 349 | BS_PARAM_BLOCK_END |
| 350 | |
| 351 | extern BloomClipParamDef gBloomClipParamDef; |
| 352 | |
| 353 | /** Shader that clips parts of the image that shouldn't be affected by bloom (parts that aren't bright enough). */ |
| 354 | class BloomClipMat : public RendererMaterial<BloomClipMat> |
| 355 | { |
| 356 | RMAT_DEF("PPBloomClip.bsl" ); |
| 357 | |
| 358 | /** Helper method used for initializing variations of this material. */ |
| 359 | template<bool AUTO_EXPOSURE> |
| 360 | static const ShaderVariation& getVariation() |
| 361 | { |
| 362 | static ShaderVariation variation = ShaderVariation( |
| 363 | { |
| 364 | ShaderVariation::Param("AUTO_EXPOSURE" , AUTO_EXPOSURE) |
| 365 | }); |
| 366 | |
| 367 | return variation; |
| 368 | } |
| 369 | public: |
| 370 | BloomClipMat(); |
| 371 | |
| 372 | /** |
| 373 | * Executes the post-process effect with the provided parameters and writes the results to the currently bound |
| 374 | * render target. |
| 375 | * |
| 376 | * @param[in] input Texture to process. |
| 377 | * @param[in] threshold Treshold below which values will be ignored for purposes of bloom. |
| 378 | * @param[in] eyeAdaptation Texture containing eye adaptation exposure value. Only needed if using the |
| 379 | * AUTO_EXPOSURE variation of this material. |
| 380 | * @param[in] settings Render settings for the current view. |
| 381 | * @param[in] output Render target to write the results to. |
| 382 | */ |
| 383 | void execute(const SPtr<Texture>& input, float threshold, const SPtr<Texture>& eyeAdaptation, |
| 384 | const RenderSettings& settings, const SPtr<RenderTarget>& output); |
| 385 | |
| 386 | /** |
| 387 | * Returns the material variation matching the provided parameters. |
| 388 | * |
| 389 | * @param[in] autoExposure If true the exposure value will need to be provided in a texture output from the |
| 390 | * eye adaptation material. Otherwise manual exposure scale from render settings will |
| 391 | * be used. |
| 392 | */ |
| 393 | static BloomClipMat* getVariation(bool autoExposure); |
| 394 | |
| 395 | private: |
| 396 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 397 | |
| 398 | GpuParamTexture mInputTex; |
| 399 | GpuParamTexture mEyeAdaptationTex; |
| 400 | }; |
| 401 | |
| 402 | const int MAX_BLUR_SAMPLES = 128; |
| 403 | |
| 404 | BS_PARAM_BLOCK_BEGIN(GaussianBlurParamDef) |
| 405 | BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gSampleOffsets, (MAX_BLUR_SAMPLES + 1) / 2) |
| 406 | BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gSampleWeights, MAX_BLUR_SAMPLES) |
| 407 | BS_PARAM_BLOCK_ENTRY(int, gNumSamples) |
| 408 | BS_PARAM_BLOCK_END |
| 409 | |
| 410 | extern GaussianBlurParamDef gGaussianBlurParamDef; |
| 411 | |
| 412 | /** Shader that performs Gaussian blur filtering on the provided texture. */ |
| 413 | class GaussianBlurMat : public RendererMaterial<GaussianBlurMat> |
| 414 | { |
| 415 | // Direction of the Gaussian filter pass |
| 416 | enum Direction |
| 417 | { |
| 418 | DirVertical, |
| 419 | DirHorizontal |
| 420 | }; |
| 421 | |
| 422 | RMAT_DEF_CUSTOMIZED("PPGaussianBlur.bsl" ); |
| 423 | |
| 424 | /** Helper method used for initializing variations of this material. */ |
| 425 | template<bool ADDITIVE> |
| 426 | static const ShaderVariation& getVariation() |
| 427 | { |
| 428 | static ShaderVariation variation = ShaderVariation( |
| 429 | { |
| 430 | ShaderVariation::Param("ADDITIVE" , ADDITIVE), |
| 431 | }); |
| 432 | |
| 433 | return variation; |
| 434 | } |
| 435 | public: |
| 436 | GaussianBlurMat(); |
| 437 | |
| 438 | /** |
| 439 | * Renders the post-process effect with the provided parameters. |
| 440 | * |
| 441 | * @param[in] source Input texture to blur. |
| 442 | * @param[in] filterSize Size of the blurring filter, in percent of the source texture. In range [0, 1]. |
| 443 | * @param[in] destination Output texture to which to write the blurred image to. |
| 444 | * @param[in] tint Optional tint to apply all filtered pixels. |
| 445 | * @param[in] additive Optional texture whose values to add to the destination texture (won't be included |
| 446 | * in filtering). Only used if using the variation of this shader that supports additive |
| 447 | * input. |
| 448 | */ |
| 449 | void execute(const SPtr<Texture>& source, float filterSize, const SPtr<RenderTexture>& destination, |
| 450 | const Color& tint = Color::White, const SPtr<Texture>& additive = nullptr); |
| 451 | |
| 452 | /** |
| 453 | * Returns the material variation matching the provided parameters. |
| 454 | * |
| 455 | * @param[in] additive If true the returned variation will support and additional input texture that will be |
| 456 | * added on top of the filtered output. |
| 457 | */ |
| 458 | static GaussianBlurMat* getVariation(bool additive); |
| 459 | |
| 460 | private: |
| 461 | /** Calculates weights and offsets for the standard distribution of the specified filter size. */ |
| 462 | static UINT32 calcStdDistribution(float filterRadius, std::array<float, MAX_BLUR_SAMPLES>& weights, |
| 463 | std::array<float, MAX_BLUR_SAMPLES>& offsets); |
| 464 | |
| 465 | /** Calculates the radius of the blur kernel depending on the source texture size and provided scale. */ |
| 466 | static float calcKernelRadius(const SPtr<Texture>& source, float scale, Direction filterDir); |
| 467 | |
| 468 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 469 | GpuParamTexture mInputTexture; |
| 470 | GpuParamTexture mAdditiveTexture; |
| 471 | bool mIsAdditive = false; |
| 472 | }; |
| 473 | |
| 474 | BS_PARAM_BLOCK_BEGIN(GaussianDOFParamDef) |
| 475 | BS_PARAM_BLOCK_ENTRY(float, gNearBlurPlane) |
| 476 | BS_PARAM_BLOCK_ENTRY(float, gFarBlurPlane) |
| 477 | BS_PARAM_BLOCK_ENTRY(float, gInvNearBlurRange) |
| 478 | BS_PARAM_BLOCK_ENTRY(float, gInvFarBlurRange) |
| 479 | BS_PARAM_BLOCK_ENTRY(Vector2, gHalfPixelOffset) |
| 480 | BS_PARAM_BLOCK_END |
| 481 | |
| 482 | extern GaussianDOFParamDef sGaussianDOFParamDef; |
| 483 | |
| 484 | /** |
| 485 | * Shader that masks pixels from the input color texture into one or two output textures. The masking is done by |
| 486 | * determining if the pixel falls into near or far unfocused plane, as determined by depth-of-field parameters. User |
| 487 | * can pick whether to output pixels just on the near plane, just on the far plane, or both. |
| 488 | * |
| 489 | */ |
| 490 | class GaussianDOFSeparateMat : public RendererMaterial<GaussianDOFSeparateMat> |
| 491 | { |
| 492 | RMAT_DEF("PPGaussianDOFSeparate.bsl" ); |
| 493 | |
| 494 | /** Helper method used for initializing variations of this material. */ |
| 495 | template<bool near, bool far> |
| 496 | static const ShaderVariation& getVariation() |
| 497 | { |
| 498 | static ShaderVariation variation = ShaderVariation( |
| 499 | { |
| 500 | ShaderVariation::Param("NEAR" , near), |
| 501 | ShaderVariation::Param("FAR" , far) |
| 502 | }); |
| 503 | |
| 504 | return variation; |
| 505 | } |
| 506 | public: |
| 507 | GaussianDOFSeparateMat(); |
| 508 | |
| 509 | /** |
| 510 | * Renders the post-process effect with the provided parameters. |
| 511 | * |
| 512 | * @param[in] color Input color texture to process. |
| 513 | * @param[in] depth Input depth buffer texture that will be used for determining pixel depth. |
| 514 | * @param[in] view View through which the depth of field effect is viewed. |
| 515 | * @param[in] settings Settings used to control depth of field rendering. |
| 516 | */ |
| 517 | void execute(const SPtr<Texture>& color, const SPtr<Texture>& depth, const RendererView& view, |
| 518 | const DepthOfFieldSettings& settings); |
| 519 | |
| 520 | /** |
| 521 | * Returns the texture generated after the shader was executed. Only valid to call this in-between calls to |
| 522 | * execute() & release(), with @p idx value 0 or 1. |
| 523 | */ |
| 524 | SPtr<PooledRenderTexture> getOutput(UINT32 idx); |
| 525 | |
| 526 | /** |
| 527 | * Releases the interally allocated output render textures. Must be called after each call to execute(), when the |
| 528 | * caller is done using the textures. |
| 529 | */ |
| 530 | void release(); |
| 531 | |
| 532 | /** |
| 533 | * Returns the material variation matching the provided parameters. |
| 534 | * |
| 535 | * @param near If true, near plane pixels are output to the first render target. |
| 536 | * @param far If true, far plane pixels are output to the first render target. If @p near is also enabled, the |
| 537 | * pixels are output to the second render target instead. |
| 538 | */ |
| 539 | static GaussianDOFSeparateMat* getVariation(bool near, bool far); |
| 540 | |
| 541 | private: |
| 542 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 543 | GpuParamTexture mColorTexture; |
| 544 | GpuParamTexture mDepthTexture; |
| 545 | |
| 546 | SPtr<PooledRenderTexture> mOutput0; |
| 547 | SPtr<PooledRenderTexture> mOutput1; |
| 548 | }; |
| 549 | |
| 550 | /** |
| 551 | * Shader that combines pixels for near unfocused, focused and far unfocused planes, as calculated by |
| 552 | * GaussianDOFSeparateMat. Outputs final depth-of-field filtered image. |
| 553 | */ |
| 554 | class GaussianDOFCombineMat : public RendererMaterial<GaussianDOFCombineMat> |
| 555 | { |
| 556 | RMAT_DEF("PPGaussianDOFCombine.bsl" ); |
| 557 | |
| 558 | /** Helper method used for initializing variations of this material. */ |
| 559 | template<bool near, bool far> |
| 560 | static const ShaderVariation& getVariation() |
| 561 | { |
| 562 | static ShaderVariation variation = ShaderVariation( |
| 563 | { |
| 564 | ShaderVariation::Param("NEAR" , near), |
| 565 | ShaderVariation::Param("FAR" , far), |
| 566 | }); |
| 567 | |
| 568 | return variation; |
| 569 | } |
| 570 | public: |
| 571 | GaussianDOFCombineMat(); |
| 572 | |
| 573 | /** |
| 574 | * Renders the post-process effect with the provided parameters. |
| 575 | * |
| 576 | * @param[in] focused Input texture containing focused (default) scene color. |
| 577 | * @param[in] near Input texture containing filtered (blurred) values for the unfocused foreground area. |
| 578 | * Can be null if no near plane needs to be blended. |
| 579 | * @param[in] far Input texture containing filtered (blurred) values for the unfocused background area. |
| 580 | * Can be null if no far plane needs to be blended. |
| 581 | * @param[in] depth Input depth buffer texture that will be used for determining pixel depth. |
| 582 | * @param[in] output Texture to output the results to. |
| 583 | * @param[in] view View through which the depth of field effect is viewed. |
| 584 | * @param[in] settings Settings used to control depth of field rendering. |
| 585 | */ |
| 586 | void execute(const SPtr<Texture>& focused, const SPtr<Texture>& near, const SPtr<Texture>& far, |
| 587 | const SPtr<Texture>& depth, const SPtr<RenderTarget>& output, const RendererView& view, |
| 588 | const DepthOfFieldSettings& settings); |
| 589 | |
| 590 | /** |
| 591 | * Returns the material variation matching the provided parameters. |
| 592 | * |
| 593 | * @param near If true, near plane pixels are read from the near plane texture, otherwise near plane is assumed |
| 594 | * not to exist. |
| 595 | * @param far If true, far plane pixels are read from the far plane texture, otherwise far plane is assumed not |
| 596 | * to exist. |
| 597 | */ |
| 598 | static GaussianDOFCombineMat* getVariation(bool near, bool far); |
| 599 | |
| 600 | private: |
| 601 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 602 | GpuParamTexture mFocusedTexture; |
| 603 | GpuParamTexture mNearTexture; |
| 604 | GpuParamTexture mFarTexture; |
| 605 | GpuParamTexture mDepthTexture; |
| 606 | }; |
| 607 | |
| 608 | BS_PARAM_BLOCK_BEGIN(BuildHiZFParamDef) |
| 609 | BS_PARAM_BLOCK_ENTRY(Vector2, gHalfPixelOffset) |
| 610 | BS_PARAM_BLOCK_ENTRY(int, gMipLevel) |
| 611 | BS_PARAM_BLOCK_END |
| 612 | |
| 613 | extern BuildHiZFParamDef sBuildHiZFParamDef; |
| 614 | |
| 615 | /** Shader that calculates a single level of the hierarchical Z mipmap chain. */ |
| 616 | class BuildHiZMat : public RendererMaterial<BuildHiZMat> |
| 617 | { |
| 618 | RMAT_DEF("PPBuildHiZ.bsl" ); |
| 619 | |
| 620 | /** Helper method used for initializing variations of this material. */ |
| 621 | template<bool noTextureViews> |
| 622 | static const ShaderVariation& getVariation() |
| 623 | { |
| 624 | static ShaderVariation variation = ShaderVariation( |
| 625 | { |
| 626 | ShaderVariation::Param("NO_TEXTURE_VIEWS" , noTextureViews), |
| 627 | }); |
| 628 | |
| 629 | return variation; |
| 630 | } |
| 631 | public: |
| 632 | BuildHiZMat(); |
| 633 | |
| 634 | /** |
| 635 | * Renders the post-process effect with the provided parameters. |
| 636 | * |
| 637 | * @param[in] source Input depth texture to use as the source. |
| 638 | * @param[in] srcMip Mip level to read from the @p source texture. |
| 639 | * @param[in] srcRect Rectangle in normalized coordinates, describing from which portion of the source |
| 640 | * texture to read the input. |
| 641 | * @param[in] dstRect Destination rectangle to limit the writes to. |
| 642 | * @param[in] output Output target to which to write to results. |
| 643 | */ |
| 644 | void execute(const SPtr<Texture>& source, UINT32 srcMip, const Rect2& srcRect, const Rect2& dstRect, |
| 645 | const SPtr<RenderTexture>& output); |
| 646 | |
| 647 | /** |
| 648 | * Returns the material variation matching the provided parameters. |
| 649 | * |
| 650 | * @param noTextureViews Specify as true if the current render backend doesn't support texture views, in |
| 651 | * which case the implementation falls back on using a simpler version of the shader. |
| 652 | */ |
| 653 | static BuildHiZMat* getVariation(bool noTextureViews); |
| 654 | private: |
| 655 | GpuParamTexture mInputTexture; |
| 656 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 657 | bool mNoTextureViews = false; |
| 658 | }; |
| 659 | |
| 660 | BS_PARAM_BLOCK_BEGIN(FXAAParamDef) |
| 661 | BS_PARAM_BLOCK_ENTRY(Vector2, gInvTexSize) |
| 662 | BS_PARAM_BLOCK_END |
| 663 | |
| 664 | extern FXAAParamDef gFXAAParamDef; |
| 665 | |
| 666 | /** Shader that performs Fast Approximate anti-aliasing. */ |
| 667 | class FXAAMat : public RendererMaterial<FXAAMat> |
| 668 | { |
| 669 | RMAT_DEF("PPFXAA.bsl" ); |
| 670 | |
| 671 | public: |
| 672 | FXAAMat(); |
| 673 | |
| 674 | /** |
| 675 | * Renders the post-process effect with the provided parameters. |
| 676 | * |
| 677 | * @param[in] source Input texture to apply FXAA to. |
| 678 | * @param[in] destination Output target to which to write the antialiased image to. |
| 679 | */ |
| 680 | void execute(const SPtr<Texture>& source, const SPtr<RenderTarget>& destination); |
| 681 | |
| 682 | private: |
| 683 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 684 | GpuParamTexture mInputTexture; |
| 685 | }; |
| 686 | |
| 687 | BS_PARAM_BLOCK_BEGIN(SSAOParamDef) |
| 688 | BS_PARAM_BLOCK_ENTRY(float, gSampleRadius) |
| 689 | BS_PARAM_BLOCK_ENTRY(float, gWorldSpaceRadiusMask) |
| 690 | BS_PARAM_BLOCK_ENTRY(Vector2, gTanHalfFOV) |
| 691 | BS_PARAM_BLOCK_ENTRY(Vector2, gRandomTileScale) |
| 692 | BS_PARAM_BLOCK_ENTRY(float, gCotHalfFOV) |
| 693 | BS_PARAM_BLOCK_ENTRY(float, gBias) |
| 694 | BS_PARAM_BLOCK_ENTRY(Vector2, gDownsampledPixelSize) |
| 695 | BS_PARAM_BLOCK_ENTRY(Vector2, gFadeMultiplyAdd) |
| 696 | BS_PARAM_BLOCK_ENTRY(float, gPower) |
| 697 | BS_PARAM_BLOCK_ENTRY(float, gIntensity) |
| 698 | BS_PARAM_BLOCK_END |
| 699 | |
| 700 | extern SSAOParamDef gSSAOParamDef; |
| 701 | |
| 702 | /** Textures used as input when calculating SSAO. */ |
| 703 | struct SSAOTextureInputs |
| 704 | { |
| 705 | /** Full resolution scene depth. Only used by final SSAO pass. */ |
| 706 | SPtr<Texture> sceneDepth; |
| 707 | |
| 708 | /** Full resolution buffer containing scene normals. Only used by final SSAO pass. */ |
| 709 | SPtr<Texture> sceneNormals; |
| 710 | |
| 711 | /** Precalculated texture containing downsampled normals/depth, to be used for AO input. */ |
| 712 | SPtr<Texture> aoSetup; |
| 713 | |
| 714 | /** Texture containing AO from the previous pass. Only used if upsampling is enabled. */ |
| 715 | SPtr<Texture> aoDownsampled; |
| 716 | |
| 717 | /** Tileable texture containing random rotations that will be applied to AO samples. */ |
| 718 | SPtr<Texture> randomRotations; |
| 719 | }; |
| 720 | |
| 721 | /** Shader that computes ambient occlusion using screen based methods. */ |
| 722 | class SSAOMat : public RendererMaterial<SSAOMat> |
| 723 | { |
| 724 | RMAT_DEF("PPSSAO.bsl" ); |
| 725 | |
| 726 | /** Helper method used for initializing variations of this material. */ |
| 727 | template<bool upsample, bool finalPass, int quality> |
| 728 | static const ShaderVariation& getVariation() |
| 729 | { |
| 730 | static ShaderVariation variation = ShaderVariation( |
| 731 | { |
| 732 | ShaderVariation::Param("MIX_WITH_UPSAMPLED" , upsample), |
| 733 | ShaderVariation::Param("FINAL_AO" , finalPass), |
| 734 | ShaderVariation::Param("QUALITY" , quality) |
| 735 | }); |
| 736 | |
| 737 | return variation; |
| 738 | } |
| 739 | public: |
| 740 | SSAOMat(); |
| 741 | |
| 742 | /** |
| 743 | * Renders the post-process effect with the provided parameters. |
| 744 | * |
| 745 | * @param[in] view Information about the view we're rendering from. |
| 746 | * @param[in] textures Set of textures to be used as input. Which textures are used depends on the |
| 747 | * template parameters of this class. |
| 748 | * @param[in] destination Output texture to which to write the ambient occlusion data to. |
| 749 | * @param[in] settings Settings used to control the ambient occlusion effect. |
| 750 | */ |
| 751 | void execute(const RendererView& view, const SSAOTextureInputs& textures, const SPtr<RenderTexture>& destination, |
| 752 | const AmbientOcclusionSettings& settings); |
| 753 | |
| 754 | /** |
| 755 | * Returns the material variation matching the provided parameters. |
| 756 | * |
| 757 | * @param upsample If true the shader will blend the calculated AO with AO data from the previous pass. |
| 758 | * @param finalPass If true the shader will use the full screen normal/depth information and perform |
| 759 | * intensity scaling, as well as distance fade. Otherwise the shader will use the |
| 760 | * downsampled AO setup information, with no scaling/fade. |
| 761 | * @param quality Integer in range [0, 4] that controls the quality of SSAO sampling. Higher numbers yield |
| 762 | * better quality at the cost of performance. |
| 763 | */ |
| 764 | static SSAOMat* getVariation(bool upsample, bool finalPass, int quality); |
| 765 | |
| 766 | private: |
| 767 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 768 | GpuParamTexture mDepthTexture; |
| 769 | GpuParamTexture mNormalsTexture; |
| 770 | GpuParamTexture mDownsampledAOTexture; |
| 771 | GpuParamTexture mSetupAOTexture; |
| 772 | GpuParamTexture mRandomTexture; |
| 773 | }; |
| 774 | |
| 775 | BS_PARAM_BLOCK_BEGIN(SSAODownsampleParamDef) |
| 776 | BS_PARAM_BLOCK_ENTRY(Vector2, gPixelSize) |
| 777 | BS_PARAM_BLOCK_ENTRY(float, gInvDepthThreshold) |
| 778 | BS_PARAM_BLOCK_END |
| 779 | |
| 780 | extern SSAODownsampleParamDef gSSAODownsampleParamDef; |
| 781 | |
| 782 | /** |
| 783 | * Shader that downsamples the depth & normal buffer and stores their results in a common texture, to be consumed |
| 784 | * by SSAOMat. |
| 785 | */ |
| 786 | class SSAODownsampleMat : public RendererMaterial<SSAODownsampleMat> |
| 787 | { |
| 788 | RMAT_DEF("PPSSAODownsample.bsl" ); |
| 789 | |
| 790 | public: |
| 791 | SSAODownsampleMat(); |
| 792 | |
| 793 | /** |
| 794 | * Renders the post-process effect with the provided parameters. |
| 795 | * |
| 796 | * @param[in] view Information about the view we're rendering from. |
| 797 | * @param[in] sceneDepth Input texture containing scene depth. |
| 798 | * @param[in] sceneNormals Input texture containing scene world space normals. |
| 799 | * @param[in] destination Output texture to which to write the downsampled data to. |
| 800 | * @param[in] depthRange Valid depth range (in view space) within which nearby samples will be averaged. |
| 801 | */ |
| 802 | void execute(const RendererView& view, const SPtr<Texture>& sceneDepth, const SPtr<Texture>& sceneNormals, |
| 803 | const SPtr<RenderTexture>& destination, float depthRange); |
| 804 | |
| 805 | private: |
| 806 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 807 | GpuParamTexture mDepthTexture; |
| 808 | GpuParamTexture mNormalsTexture; |
| 809 | }; |
| 810 | |
| 811 | BS_PARAM_BLOCK_BEGIN(SSAOBlurParamDef) |
| 812 | BS_PARAM_BLOCK_ENTRY(Vector2, gPixelSize) |
| 813 | BS_PARAM_BLOCK_ENTRY(Vector2, gPixelOffset) |
| 814 | BS_PARAM_BLOCK_ENTRY(float, gInvDepthThreshold) |
| 815 | BS_PARAM_BLOCK_END |
| 816 | |
| 817 | extern SSAOBlurParamDef gSSAOBlurParamDef; |
| 818 | |
| 819 | /** |
| 820 | * Shaders that blurs the ambient occlusion output, in order to hide the noise caused by the randomization texture. |
| 821 | */ |
| 822 | class SSAOBlurMat : public RendererMaterial<SSAOBlurMat> |
| 823 | { |
| 824 | RMAT_DEF("PPSSAOBlur.bsl" ); |
| 825 | |
| 826 | /** Helper method used for initializing variations of this material. */ |
| 827 | template<bool horizontal> |
| 828 | static const ShaderVariation& getVariation() |
| 829 | { |
| 830 | static ShaderVariation variation = ShaderVariation( |
| 831 | { |
| 832 | ShaderVariation::Param("DIR_HORZ" , horizontal) |
| 833 | }); |
| 834 | |
| 835 | return variation; |
| 836 | } |
| 837 | public: |
| 838 | SSAOBlurMat(); |
| 839 | |
| 840 | /** |
| 841 | * Renders the post-process effect with the provided parameters. |
| 842 | * |
| 843 | * @param[in] view Information about the view we're rendering from. |
| 844 | * @param[in] ao Input texture containing ambient occlusion data to be blurred. |
| 845 | * @param[in] sceneDepth Input texture containing scene depth. |
| 846 | * @param[in] destination Output texture to which to write the blurred data to. |
| 847 | * @param[in] depthRange Valid depth range (in view space) within which nearby samples will be averaged. |
| 848 | */ |
| 849 | void execute(const RendererView& view, const SPtr<Texture>& ao, const SPtr<Texture>& sceneDepth, |
| 850 | const SPtr<RenderTexture>& destination, float depthRange); |
| 851 | |
| 852 | /** Returns the material variation matching the provided parameters. */ |
| 853 | static SSAOBlurMat* getVariation(bool horizontal); |
| 854 | |
| 855 | private: |
| 856 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 857 | GpuParamTexture mAOTexture; |
| 858 | GpuParamTexture mDepthTexture; |
| 859 | }; |
| 860 | |
| 861 | BS_PARAM_BLOCK_BEGIN(SSRStencilParamDef) |
| 862 | BS_PARAM_BLOCK_ENTRY(Vector2, gRoughnessScaleBias) |
| 863 | BS_PARAM_BLOCK_END |
| 864 | |
| 865 | extern SSRStencilParamDef gSSRStencilParamDef; |
| 866 | |
| 867 | /** Shader used for marking which parts of the screen require screen space reflections. */ |
| 868 | class SSRStencilMat : public RendererMaterial<SSRStencilMat> |
| 869 | { |
| 870 | RMAT_DEF("PPSSRStencil.bsl" ); |
| 871 | |
| 872 | /** Helper method used for initializing variations of this material. */ |
| 873 | template<bool msaa, bool singleSampleMSAA> |
| 874 | static const ShaderVariation& getVariation() |
| 875 | { |
| 876 | static ShaderVariation variation = ShaderVariation( |
| 877 | { |
| 878 | ShaderVariation::Param("MSAA_COUNT" , msaa ? 2 : 1), |
| 879 | ShaderVariation::Param("MSAA_RESOLVE_0TH" , singleSampleMSAA) |
| 880 | }); |
| 881 | |
| 882 | return variation; |
| 883 | } |
| 884 | public: |
| 885 | SSRStencilMat(); |
| 886 | |
| 887 | /** |
| 888 | * Renders the effect with the provided parameters, using the currently bound render target. |
| 889 | * |
| 890 | * @param[in] view Information about the view we're rendering from. |
| 891 | * @param[in] gbuffer GBuffer textures. |
| 892 | * @param[in] settings Parameters used for controling the SSR effect. |
| 893 | */ |
| 894 | void execute(const RendererView& view, GBufferTextures gbuffer, const ScreenSpaceReflectionsSettings& settings); |
| 895 | |
| 896 | /** |
| 897 | * Returns the material variation matching the provided parameters. |
| 898 | * |
| 899 | * @param[in] msaa True if the shader will operate on a multisampled surface. |
| 900 | * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be |
| 901 | * evaluated. Otherwise all samples will be evaluated. |
| 902 | * @return Requested variation of the material. |
| 903 | */ |
| 904 | static SSRStencilMat* getVariation(bool msaa, bool singleSampleMSAA); |
| 905 | private: |
| 906 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 907 | GBufferParams mGBufferParams; |
| 908 | }; |
| 909 | |
| 910 | BS_PARAM_BLOCK_BEGIN(SSRTraceParamDef) |
| 911 | BS_PARAM_BLOCK_ENTRY(Vector4, gNDCToHiZUV) |
| 912 | BS_PARAM_BLOCK_ENTRY(Vector2, gHiZUVToScreenUV) |
| 913 | BS_PARAM_BLOCK_ENTRY(Vector2I, gHiZSize) |
| 914 | BS_PARAM_BLOCK_ENTRY(int, gHiZNumMips) |
| 915 | BS_PARAM_BLOCK_ENTRY(float, gIntensity) |
| 916 | BS_PARAM_BLOCK_ENTRY(Vector2, gRoughnessScaleBias) |
| 917 | BS_PARAM_BLOCK_ENTRY(int, gTemporalJitter) |
| 918 | BS_PARAM_BLOCK_END |
| 919 | |
| 920 | extern SSRTraceParamDef gSSRTraceParamDef; |
| 921 | |
| 922 | /** Shader used for tracing rays for screen space reflections. */ |
| 923 | class SSRTraceMat : public RendererMaterial<SSRTraceMat> |
| 924 | { |
| 925 | RMAT_DEF("PPSSRTrace.bsl" ); |
| 926 | |
| 927 | /** Helper method used for initializing variations of this material. */ |
| 928 | template<UINT32 quality, bool msaa, bool singleSampleMSAA> |
| 929 | static const ShaderVariation& getVariation() |
| 930 | { |
| 931 | static ShaderVariation variation = ShaderVariation( |
| 932 | { |
| 933 | ShaderVariation::Param("MSAA_COUNT" , msaa ? 2 : 1), |
| 934 | ShaderVariation::Param("QUALITY" , quality), |
| 935 | ShaderVariation::Param("MSAA_RESOLVE_0TH" , singleSampleMSAA) |
| 936 | }); |
| 937 | |
| 938 | return variation; |
| 939 | } |
| 940 | public: |
| 941 | SSRTraceMat(); |
| 942 | |
| 943 | /** |
| 944 | * Renders the effect with the provided parameters. |
| 945 | * |
| 946 | * @param[in] view Information about the view we're rendering from. |
| 947 | * @param[in] gbuffer GBuffer textures. |
| 948 | * @param[in] sceneColor Scene color texture. |
| 949 | * @param[in] hiZ Hierarchical Z buffer. |
| 950 | * @param[in] settings Parameters used for controling the SSR effect. |
| 951 | * @param[in] destination Render target to which to write the results to. |
| 952 | */ |
| 953 | void execute(const RendererView& view, GBufferTextures gbuffer, const SPtr<Texture>& sceneColor, |
| 954 | const SPtr<Texture>& hiZ, const ScreenSpaceReflectionsSettings& settings, |
| 955 | const SPtr<RenderTarget>& destination); |
| 956 | |
| 957 | /** |
| 958 | * Calculates a scale & bias that is used for transforming roughness into a fade out value. Anything that is below |
| 959 | * @p maxRoughness will have the fade value of 1. Values above @p maxRoughness is slowly fade out over a range that |
| 960 | * is 1/2 the length of @p maxRoughness. |
| 961 | */ |
| 962 | static Vector2 calcRoughnessFadeScaleBias(float maxRoughness); |
| 963 | |
| 964 | /** |
| 965 | * Returns the material variation matching the provided parameters. |
| 966 | * |
| 967 | * @param[in] quality Determines how many rays to trace. In range [0, 4]. |
| 968 | * @param[in] msaa True if the shader will operate on a multisampled surface. |
| 969 | * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be |
| 970 | * evaluated. Otherwise all samples will be evaluated. |
| 971 | * @return Requested variation of the material. |
| 972 | */ |
| 973 | static SSRTraceMat* getVariation(UINT32 quality, bool msaa, bool singleSampleMSAA = false); |
| 974 | private: |
| 975 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 976 | GBufferParams mGBufferParams; |
| 977 | GpuParamTexture mSceneColorTexture; |
| 978 | GpuParamTexture mHiZTexture; |
| 979 | }; |
| 980 | |
| 981 | BS_PARAM_BLOCK_BEGIN(TemporalResolveParamDef) |
| 982 | BS_PARAM_BLOCK_ENTRY_ARRAY(float, gSampleWeights, 9) |
| 983 | BS_PARAM_BLOCK_ENTRY_ARRAY(float, gSampleWeightsLowpass, 9) |
| 984 | BS_PARAM_BLOCK_END |
| 985 | |
| 986 | extern TemporalResolveParamDef gTemporalResolveParamDef; |
| 987 | |
| 988 | BS_PARAM_BLOCK_BEGIN(SSRResolveParamDef) |
| 989 | BS_PARAM_BLOCK_ENTRY(Vector2, gSceneDepthTexelSize) |
| 990 | BS_PARAM_BLOCK_ENTRY(Vector2, gSceneColorTexelSize) |
| 991 | BS_PARAM_BLOCK_ENTRY(float, gManualExposure) |
| 992 | BS_PARAM_BLOCK_END |
| 993 | |
| 994 | extern SSRResolveParamDef gSSRResolveParamDef; |
| 995 | |
| 996 | /** Shader used for combining SSR information from the previous frame, in order to yield better quality. */ |
| 997 | class SSRResolveMat : public RendererMaterial<SSRResolveMat> |
| 998 | { |
| 999 | RMAT_DEF("PPSSRResolve.bsl" ); |
| 1000 | |
| 1001 | /** Helper method used for initializing variations of this material. */ |
| 1002 | template<bool msaa> |
| 1003 | static const ShaderVariation& getVariation() |
| 1004 | { |
| 1005 | static ShaderVariation variation = ShaderVariation( |
| 1006 | { |
| 1007 | ShaderVariation::Param("MSAA" , msaa) |
| 1008 | }); |
| 1009 | |
| 1010 | return variation; |
| 1011 | } |
| 1012 | public: |
| 1013 | SSRResolveMat(); |
| 1014 | |
| 1015 | /** |
| 1016 | * Renders the effect with the provided parameters. |
| 1017 | * |
| 1018 | * @param[in] view Information about the view we're rendering from. |
| 1019 | * @param[in] prevFrame SSR data calculated previous frame. |
| 1020 | * @param[in] curFrame SSR data calculated this frame. |
| 1021 | * @param[in] sceneDepth Buffer containing scene depth. |
| 1022 | * @param[in] destination Render target to which to write the results to. |
| 1023 | */ |
| 1024 | void execute(const RendererView& view, const SPtr<Texture>& prevFrame, const SPtr<Texture>& curFrame, |
| 1025 | const SPtr<Texture>& sceneDepth, const SPtr<RenderTarget>& destination); |
| 1026 | |
| 1027 | /** |
| 1028 | * Returns the material variation matching the provided parameters. |
| 1029 | * |
| 1030 | * @param[in] msaa True if the shader will operate on a multisampled surface. Note that previous |
| 1031 | * and current frame color textures must be non-MSAA, regardless of this parameter. |
| 1032 | * @return Requested variation of the material. |
| 1033 | */ |
| 1034 | static SSRResolveMat* getVariation(bool msaa); |
| 1035 | |
| 1036 | private: |
| 1037 | SPtr<GpuParamBlockBuffer> mSSRParamBuffer; |
| 1038 | SPtr<GpuParamBlockBuffer> mTemporalParamBuffer; |
| 1039 | |
| 1040 | GpuParamTexture mSceneColorTexture; |
| 1041 | GpuParamTexture mPrevColorTexture; |
| 1042 | GpuParamTexture mSceneDepthTexture; |
| 1043 | GpuParamTexture mEyeAdaptationTexture; |
| 1044 | }; |
| 1045 | |
| 1046 | BS_PARAM_BLOCK_BEGIN(EncodeDepthParamDef) |
| 1047 | BS_PARAM_BLOCK_ENTRY(float, gNear) |
| 1048 | BS_PARAM_BLOCK_ENTRY(float, gFar) |
| 1049 | BS_PARAM_BLOCK_END |
| 1050 | |
| 1051 | extern EncodeDepthParamDef gEncodeDepthParamDef; |
| 1052 | |
| 1053 | /** |
| 1054 | * Shader that encodes depth from a specified range into [0, 1] range, and writes the result in the alpha channel |
| 1055 | * of the output texture. |
| 1056 | */ |
| 1057 | class EncodeDepthMat : public RendererMaterial<EncodeDepthMat> |
| 1058 | { |
| 1059 | RMAT_DEF("PPEncodeDepth.bsl" ); |
| 1060 | |
| 1061 | public: |
| 1062 | EncodeDepthMat(); |
| 1063 | |
| 1064 | /** |
| 1065 | * Renders the post-process effect with the provided parameters. |
| 1066 | * |
| 1067 | * @param[in] depth Resolved (non-MSAA) depth texture to encode. |
| 1068 | * @param[in] near Near range (in view space) to start encoding the depth. Any depth lower than this will |
| 1069 | * be encoded to 1. |
| 1070 | * @param[in] far Far range (in view space) to end encoding the depth. Any depth higher than this will |
| 1071 | * be encoded to 0. |
| 1072 | * @param[in] output Output texture to write the results in. Results will be written in the alpha channel. |
| 1073 | */ |
| 1074 | void execute(const SPtr<Texture>& depth, float near, float far, const SPtr<RenderTarget>& output); |
| 1075 | |
| 1076 | private: |
| 1077 | SPtr<GpuParamBlockBuffer> mParamBuffer; |
| 1078 | GpuParamTexture mInputTexture; |
| 1079 | }; |
| 1080 | |
| 1081 | /** |
| 1082 | * Shader that outputs a texture that determines which pixels require per-sample evaluation. Only relevant when |
| 1083 | * rendering with MSAA enabled. |
| 1084 | */ |
| 1085 | class MSAACoverageMat : public RendererMaterial<MSAACoverageMat> |
| 1086 | { |
| 1087 | RMAT_DEF("MSAACoverage.bsl" ); |
| 1088 | |
| 1089 | /** Helper method used for initializing variations of this material. */ |
| 1090 | template<UINT32 msaa> |
| 1091 | static const ShaderVariation& getVariation() |
| 1092 | { |
| 1093 | static ShaderVariation variation = ShaderVariation( |
| 1094 | { |
| 1095 | ShaderVariation::Param("MSAA_COUNT" , msaa) |
| 1096 | }); |
| 1097 | |
| 1098 | return variation; |
| 1099 | } |
| 1100 | public: |
| 1101 | MSAACoverageMat(); |
| 1102 | |
| 1103 | /** |
| 1104 | * Renders the effect with the provided parameters, using the currently bound render target. |
| 1105 | * |
| 1106 | * @param[in] view Information about the view we're rendering from. |
| 1107 | * @param[in] gbuffer GBuffer textures. |
| 1108 | */ |
| 1109 | void execute(const RendererView& view, GBufferTextures gbuffer); |
| 1110 | |
| 1111 | /** Returns the material variation matching the provided parameters. */ |
| 1112 | static MSAACoverageMat* getVariation(UINT32 msaaCount); |
| 1113 | private: |
| 1114 | GBufferParams mGBufferParams; |
| 1115 | }; |
| 1116 | |
| 1117 | /** |
| 1118 | * Converts the coverage texture output by MSAACoverageMat and writes its information in the highest bit of the |
| 1119 | * currently bound stencil buffer. This allows coverage information to be used by normal (non-compute) rendering |
| 1120 | * shaders. |
| 1121 | */ |
| 1122 | class MSAACoverageStencilMat : public RendererMaterial<MSAACoverageStencilMat> |
| 1123 | { |
| 1124 | RMAT_DEF("MSAACoverageStencil.bsl" ); |
| 1125 | |
| 1126 | public: |
| 1127 | MSAACoverageStencilMat(); |
| 1128 | |
| 1129 | /** |
| 1130 | * Renders the effect with the provided parameters, using the currently bound render target. |
| 1131 | * |
| 1132 | * @param[in] view Information about the view we're rendering from. |
| 1133 | * @param[in] coverage Coverage texture as output by MSAACoverageMat. |
| 1134 | */ |
| 1135 | void execute(const RendererView& view, const SPtr<Texture>& coverage); |
| 1136 | private: |
| 1137 | GpuParamTexture mCoverageTexParam; |
| 1138 | }; |
| 1139 | |
| 1140 | /** @} */ |
| 1141 | }} |
| 1142 | |