2
0

BsPostProcessing.h 37 KB

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