BsPostProcessing.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  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 "BsRendererMaterial.h"
  6. #include "BsParamBlocks.h"
  7. #include "BsGpuResourcePool.h"
  8. #include "BsStandardPostProcessSettings.h"
  9. #include "BsLightRendering.h"
  10. namespace bs { namespace ct
  11. {
  12. struct RendererViewTargetData;
  13. /** @addtogroup RenderBeast
  14. * @{
  15. */
  16. /** Contains per-camera data used by post process effects. */
  17. struct PostProcessInfo
  18. {
  19. SPtr<StandardPostProcessSettings> settings;
  20. bool settingDirty = true;
  21. SPtr<PooledRenderTexture> downsampledSceneTex;
  22. SPtr<PooledRenderTexture> histogramTex;
  23. SPtr<PooledRenderTexture> histogramReduceTex;
  24. SPtr<PooledRenderTexture> eyeAdaptationTex[2];
  25. SPtr<PooledRenderTexture> colorLUT;
  26. INT32 lastEyeAdaptationTex = 0;
  27. };
  28. BS_PARAM_BLOCK_BEGIN(DownsampleParamDef)
  29. BS_PARAM_BLOCK_ENTRY_ARRAY(Vector2, gOffsets, 4)
  30. BS_PARAM_BLOCK_END
  31. extern DownsampleParamDef gDownsampleParamDef;
  32. /**
  33. * Shader that downsamples a texture to half its size.
  34. *
  35. * @tparam Quality 0 for a 2x2 filtered sample, 1 or higher for 4x4 filtered sample
  36. * @tparam MSAA True if the input texture is multi-sampled. Only first sample will be used, the rest will be
  37. * discarded.
  38. */
  39. template<int Quality, bool MSAA>
  40. class DownsampleMat : public RendererMaterial<DownsampleMat<Quality, MSAA>>
  41. {
  42. RMAT_DEF("PPDownsample.bsl");
  43. public:
  44. DownsampleMat();
  45. /** Renders the post-process effect with the provided parameters. */
  46. void execute(const SPtr<Texture>& target, PostProcessInfo& ppInfo);
  47. /** Releases the output render target. */
  48. void release(PostProcessInfo& ppInfo);
  49. /** Returns the render texture where the output will be written. */
  50. SPtr<RenderTexture> getOutput() const { return mOutput; }
  51. private:
  52. SPtr<GpuParamBlockBuffer> mParamBuffer;
  53. GpuParamTexture mInputTexture;
  54. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  55. SPtr<RenderTexture> mOutput;
  56. };
  57. /** Contains all variations of the DownsampleMat material. */
  58. class DownsampleMaterials
  59. {
  60. public:
  61. /**
  62. * Executes the appropriate downsampling material.
  63. *
  64. * @param[in] quality Determines quality of the downsampling filer. Specify 0 to use a 2x2 filter block, and
  65. * 1 or higher for a 4x4 filter block.
  66. * @param[in] msaa If true the input texture is assumed to have multiple samples. The downsampling shader
  67. * will discard all samples except the first one.
  68. * @param[in] target Texture to downsample.
  69. * @param[in] ppInfo Information about the current post processing pass.
  70. */
  71. void execute(UINT32 quality, bool msaa, const SPtr<Texture>& target, PostProcessInfo& ppInfo);
  72. /**
  73. * Releases any resources allocated by execute(). Must be called using the same @p quality and @p msaa parameters as
  74. * the corresponding execute() call. @see execute().
  75. */
  76. void release(UINT32 quality, bool msaa, PostProcessInfo& ppInfo);
  77. private:
  78. DownsampleMat<0, false> m0_NoMSAA;
  79. DownsampleMat<0, true> m0_MSAA;
  80. DownsampleMat<1, false> m1_NoMSAA;
  81. DownsampleMat<1, true> m1_MSAA;
  82. };
  83. BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramParamDef)
  84. BS_PARAM_BLOCK_ENTRY(Vector4I, gPixelOffsetAndSize)
  85. BS_PARAM_BLOCK_ENTRY(Vector2, gHistogramParams)
  86. BS_PARAM_BLOCK_ENTRY(Vector2I, gThreadGroupCount)
  87. BS_PARAM_BLOCK_END
  88. extern EyeAdaptHistogramParamDef gEyeAdaptHistogramParamDef;
  89. /** Shader that creates a luminance histogram used for eye adaptation. */
  90. class EyeAdaptHistogramMat : public RendererMaterial<EyeAdaptHistogramMat>
  91. {
  92. RMAT_DEF("PPEyeAdaptHistogram.bsl");
  93. public:
  94. EyeAdaptHistogramMat();
  95. /** Executes the post-process effect with the provided parameters. */
  96. void execute(PostProcessInfo& ppInfo);
  97. /** Releases the output render target. */
  98. void release(PostProcessInfo& ppInfo);
  99. /** Returns the render texture where the output was written. */
  100. SPtr<RenderTexture> getOutput() const { return mOutput; }
  101. /** Calculates the number of thread groups that need to execute to cover the provided render target. */
  102. static Vector2I getThreadGroupCount(const SPtr<RenderTexture>& target);
  103. /**
  104. * Returns a vector containing scale and offset (in that order) that will be applied to luminance values
  105. * to determine their position in the histogram.
  106. */
  107. static Vector2 getHistogramScaleOffset(const PostProcessInfo& ppInfo);
  108. static const UINT32 THREAD_GROUP_SIZE_X = 8;
  109. static const UINT32 THREAD_GROUP_SIZE_Y = 8;
  110. static const UINT32 HISTOGRAM_NUM_TEXELS = (THREAD_GROUP_SIZE_X * THREAD_GROUP_SIZE_Y) / 4;
  111. private:
  112. SPtr<GpuParamBlockBuffer> mParamBuffer;
  113. GpuParamTexture mSceneColor;
  114. GpuParamLoadStoreTexture mOutputTex;
  115. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  116. SPtr<RenderTexture> mOutput;
  117. static const UINT32 LOOP_COUNT_X = 8;
  118. static const UINT32 LOOP_COUNT_Y = 8;
  119. };
  120. BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramReduceParamDef)
  121. BS_PARAM_BLOCK_ENTRY(int, gThreadGroupCount)
  122. BS_PARAM_BLOCK_END
  123. extern EyeAdaptHistogramReduceParamDef gEyeAdaptHistogramReduceParamDef;
  124. /** Shader that reduces the luminance histograms created by EyeAdaptHistogramMat into a single histogram. */
  125. class EyeAdaptHistogramReduceMat : public RendererMaterial<EyeAdaptHistogramReduceMat>
  126. {
  127. RMAT_DEF("PPEyeAdaptHistogramReduce.bsl");
  128. public:
  129. EyeAdaptHistogramReduceMat();
  130. /** Executes the post-process effect with the provided parameters. */
  131. void execute(PostProcessInfo& ppInfo);
  132. /** Releases the output render target. */
  133. void release(PostProcessInfo& ppInfo);
  134. /** Returns the render texture where the output was written. */
  135. SPtr<RenderTexture> getOutput() const { return mOutput; }
  136. private:
  137. SPtr<GpuParamBlockBuffer> mParamBuffer;
  138. GpuParamTexture mHistogramTex;
  139. GpuParamTexture mEyeAdaptationTex;
  140. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  141. SPtr<RenderTexture> mOutput;
  142. };
  143. BS_PARAM_BLOCK_BEGIN(EyeAdaptationParamDef)
  144. BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gEyeAdaptationParams, 3)
  145. BS_PARAM_BLOCK_END
  146. extern EyeAdaptationParamDef gEyeAdaptationParamDef;
  147. /** Shader that computes the eye adaptation value based on scene luminance. */
  148. class EyeAdaptationMat : public RendererMaterial<EyeAdaptationMat>
  149. {
  150. RMAT_DEF("PPEyeAdaptation.bsl");
  151. public:
  152. EyeAdaptationMat();
  153. /** Executes the post-process effect with the provided parameters. */
  154. void execute(PostProcessInfo& ppInfo, float frameDelta);
  155. private:
  156. SPtr<GpuParamBlockBuffer> mParamBuffer;
  157. GpuParamTexture mReducedHistogramTex;
  158. };
  159. BS_PARAM_BLOCK_BEGIN(CreateTonemapLUTParamDef)
  160. BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gTonemapParams, 2)
  161. BS_PARAM_BLOCK_ENTRY(float, gGammaAdjustment)
  162. BS_PARAM_BLOCK_ENTRY(int, gGammaCorrectionType)
  163. BS_PARAM_BLOCK_ENTRY(Vector3, gSaturation)
  164. BS_PARAM_BLOCK_ENTRY(Vector3, gContrast)
  165. BS_PARAM_BLOCK_ENTRY(Vector3, gGain)
  166. BS_PARAM_BLOCK_ENTRY(Vector3, gOffset)
  167. BS_PARAM_BLOCK_END
  168. extern CreateTonemapLUTParamDef gCreateTonemapLUTParamDef;
  169. BS_PARAM_BLOCK_BEGIN(WhiteBalanceParamDef)
  170. BS_PARAM_BLOCK_ENTRY(float, gWhiteTemp)
  171. BS_PARAM_BLOCK_ENTRY(float, gWhiteOffset)
  172. BS_PARAM_BLOCK_END
  173. extern WhiteBalanceParamDef gWhiteBalanceParamDef;
  174. /**
  175. * Shader that creates a 3D lookup texture that is used to apply tonemapping, color grading, white balancing and gamma
  176. * correction.
  177. */
  178. class CreateTonemapLUTMat : public RendererMaterial<CreateTonemapLUTMat>
  179. {
  180. RMAT_DEF("PPCreateTonemapLUT.bsl");
  181. public:
  182. CreateTonemapLUTMat();
  183. /** Executes the post-process effect with the provided parameters. */
  184. void execute(PostProcessInfo& ppInfo);
  185. /** Releases the output render target. */
  186. void release(PostProcessInfo& ppInfo);
  187. /** Size of the 3D color lookup table. */
  188. static const UINT32 LUT_SIZE = 32;
  189. private:
  190. SPtr<GpuParamBlockBuffer> mParamBuffer;
  191. SPtr<GpuParamBlockBuffer> mWhiteBalanceParamBuffer;
  192. GpuParamLoadStoreTexture mOutputTex;
  193. };
  194. BS_PARAM_BLOCK_BEGIN(TonemappingParamDef)
  195. BS_PARAM_BLOCK_ENTRY(float, gRawGamma)
  196. BS_PARAM_BLOCK_ENTRY(float, gManualExposureScale)
  197. BS_PARAM_BLOCK_ENTRY(int, gNumSamples)
  198. BS_PARAM_BLOCK_END
  199. extern TonemappingParamDef gTonemappingParamDef;
  200. /** Shader that applies tonemapping and converts a HDR image into a LDR image. */
  201. template<bool GammaOnly, bool AutoExposure, bool MSAA>
  202. class TonemappingMat : public RendererMaterial<TonemappingMat<GammaOnly, AutoExposure, MSAA>>
  203. {
  204. RMAT_DEF("PPTonemapping.bsl");
  205. public:
  206. TonemappingMat();
  207. /** Executes the post-process effect with the provided parameters. */
  208. void execute(const SPtr<Texture>& sceneColor, const SPtr<RenderTarget>& outputRT, const Rect2& outputRect,
  209. PostProcessInfo& ppInfo);
  210. private:
  211. SPtr<GpuParamBlockBuffer> mParamBuffer;
  212. GpuParamTexture mInputTex;
  213. GpuParamTexture mColorLUT;
  214. GpuParamTexture mEyeAdaptationTex;
  215. };
  216. /** Container for all variations of the TonemappingMat material. */
  217. class TonemappingMaterials
  218. {
  219. public:
  220. /**
  221. * Finds a valid tonemapping material according to the requested parameters and executes it.
  222. *
  223. * @param[in] gammaOnly If true no color correction, white balancing or curve tonemapping will take place.
  224. * Instead the image will only be scaled by the exposure value and gamma corrected.
  225. * @param[in] autoExposure If true, the automatically calculated eye-adapatation exposure value will be used
  226. * as the exposure scale. If false, the user provided value will be used instead.
  227. * @param[in] MSAA True if the input texture has multiple samples. This will ensure that the samples
  228. * are resolved properly into a non-MSAA output texture.
  229. * @param[in] sceneColor Texture to apply tonemapping to.
  230. * @param[in] outputRT Render target to write the results to.
  231. * @param[in] outputRect Normalized rectangle determining to which part of the output texture to write to.
  232. * @param[in] ppInfo Information about the current post processing pass.
  233. */
  234. void execute(bool gammaOnly, bool autoExposure, bool MSAA, const SPtr<Texture>& sceneColor,
  235. const SPtr<RenderTarget>& outputRT, const Rect2& outputRect, PostProcessInfo& ppInfo);
  236. private:
  237. TonemappingMat<false, false, false> mFFF;
  238. TonemappingMat<false, false, true> mFFT;
  239. TonemappingMat<false, true, false> mFTF;
  240. TonemappingMat<false, true, true> mFTT;
  241. TonemappingMat<true, false, false> mTFF;
  242. TonemappingMat<true, false, true> mTFT;
  243. TonemappingMat<true, true, false> mTTF;
  244. TonemappingMat<true, true, true> mTTT;
  245. };
  246. const int MAX_BLUR_SAMPLES = 128;
  247. BS_PARAM_BLOCK_BEGIN(GaussianBlurParamDef)
  248. BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gSampleOffsets, (MAX_BLUR_SAMPLES + 1) / 2)
  249. BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gSampleWeights, (MAX_BLUR_SAMPLES + 3) / 4)
  250. BS_PARAM_BLOCK_ENTRY(int, gNumSamples)
  251. BS_PARAM_BLOCK_END
  252. extern GaussianBlurParamDef gGaussianBlurParamDef;
  253. /** Shader that performs Gaussian blur filtering on the provided texture. */
  254. class GaussianBlurMat : public RendererMaterial<GaussianBlurMat>
  255. {
  256. // Direction of the Gaussian filter pass
  257. enum Direction
  258. {
  259. DirVertical,
  260. DirHorizontal
  261. };
  262. RMAT_DEF("PPGaussianBlur.bsl");
  263. public:
  264. GaussianBlurMat();
  265. /**
  266. * Renders the post-process effect with the provided parameters.
  267. *
  268. * @param[in] source Input texture to blur.
  269. * @param[in] filterSize Size of the blurring filter, in percent of the source texture. In range [0, 1].
  270. * @param[in] destination Output texture to which to write the blurred image to.
  271. */
  272. void execute(const SPtr<Texture>& source, float filterSize, const SPtr<RenderTexture>& destination);
  273. private:
  274. /** Calculates weights and offsets for the standard distribution of the specified filter size. */
  275. static UINT32 calcStdDistribution(float filterRadius, std::array<float, MAX_BLUR_SAMPLES>& weights,
  276. std::array<float, MAX_BLUR_SAMPLES>& offsets);
  277. /** Calculates the radius of the blur kernel depending on the source texture size and provided scale. */
  278. static float calcKernelRadius(const SPtr<Texture>& source, float scale, Direction filterDir);
  279. SPtr<GpuParamBlockBuffer> mParamBuffer;
  280. GpuParamTexture mInputTexture;
  281. };
  282. BS_PARAM_BLOCK_BEGIN(GaussianDOFParamDef)
  283. BS_PARAM_BLOCK_ENTRY(float, gNearBlurPlane)
  284. BS_PARAM_BLOCK_ENTRY(float, gFarBlurPlane)
  285. BS_PARAM_BLOCK_ENTRY(float, gInvNearBlurRange)
  286. BS_PARAM_BLOCK_ENTRY(float, gInvFarBlurRange)
  287. BS_PARAM_BLOCK_ENTRY(Vector2, gHalfPixelOffset)
  288. BS_PARAM_BLOCK_END
  289. extern GaussianDOFParamDef sGaussianDOFParamDef;
  290. /** Common interface for all variations of GaussianDOFSeparateMat. */
  291. class IGaussianDOFSeparateMat
  292. {
  293. public:
  294. virtual ~IGaussianDOFSeparateMat() { }
  295. /**
  296. * Renders the post-process effect with the provided parameters.
  297. *
  298. * @param[in] color Input color texture to process.
  299. * @param[in] depth Input depth buffer texture that will be used for determining pixel depth.
  300. * @param[in] view View through which the depth of field effect is viewed.
  301. * @param[in] settings Settings used to control depth of field rendering.
  302. */
  303. virtual void execute(const SPtr<Texture>& color, const SPtr<Texture>& depth, const RendererView& view,
  304. const DepthOfFieldSettings& settings) = 0;
  305. /**
  306. * Returns the texture generated after the shader was executed. Only valid to call this in-between calls to
  307. * execute() & release(), with @p idx value 0 or 1.
  308. */
  309. virtual SPtr<PooledRenderTexture> getOutput(UINT32 idx) = 0;
  310. /**
  311. * Releases the interally allocated output render textures. Must be called after each call to execute(), when the
  312. * caller is done using the textures.
  313. */
  314. virtual void release() = 0;
  315. };
  316. /**
  317. * Shader that masks pixels from the input color texture into one or two output textures. The masking is done by
  318. * determining if the pixel falls into near or far unfocused plane, as determined by depth-of-field parameters. User
  319. * can pick whether to output pixels just on the near plane, just on the far plane, or both.
  320. *
  321. * @tparam Near If true, near plane pixels are output to the first render target.
  322. * @tparam Far If true, far plane pixels are output to the first render target. If @p Near is also enabled, the
  323. * pixels are output to the second render target instead.
  324. */
  325. template<bool Near, bool Far>
  326. class GaussianDOFSeparateMat : public IGaussianDOFSeparateMat, public RendererMaterial<GaussianDOFSeparateMat<Near, Far>>
  327. {
  328. RMAT_DEF("PPGaussianDOFSeparate.bsl");
  329. public:
  330. GaussianDOFSeparateMat();
  331. /** @copydoc IGaussianDOFSeparateMat::execute() */
  332. void execute(const SPtr<Texture>& color, const SPtr<Texture>& depth, const RendererView& view,
  333. const DepthOfFieldSettings& settings) override;
  334. /** @copydoc IGaussianDOFSeparateMat::getOutput() */
  335. SPtr<PooledRenderTexture> getOutput(UINT32 idx) override;
  336. /** @copydoc IGaussianDOFSeparateMat::release() */
  337. void release() override;
  338. private:
  339. SPtr<GpuParamBlockBuffer> mParamBuffer;
  340. GpuParamTexture mColorTexture;
  341. GpuParamTexture mDepthTexture;
  342. SPtr<PooledRenderTexture> mOutput0;
  343. SPtr<PooledRenderTexture> mOutput1;
  344. };
  345. /** Common interface for all variations of GaussianDOFCombineMat. */
  346. class IGaussianDOFCombineMat
  347. {
  348. public:
  349. virtual ~IGaussianDOFCombineMat() { }
  350. /**
  351. * Renders the post-process effect with the provided parameters.
  352. *
  353. * @param[in] focused Input texture containing focused (default) scene color.
  354. * @param[in] near Input texture containing filtered (blurred) values for the unfocused foreground area.
  355. * Can be null if no near plane needs to be blended.
  356. * @param[in] far Input texture containing filtered (blurred) values for the unfocused background area.
  357. * Can be null if no far plane needs to be blended.
  358. * @param[in] depth Input depth buffer texture that will be used for determining pixel depth.
  359. * @param[in] output Texture to output the results to.
  360. * @param[in] view View through which the depth of field effect is viewed.
  361. * @param[in] settings Settings used to control depth of field rendering.
  362. */
  363. virtual void execute(const SPtr<Texture>& focused, const SPtr<Texture>& near, const SPtr<Texture>& far,
  364. const SPtr<Texture>& depth, const SPtr<RenderTarget>& output, const RendererView& view,
  365. const DepthOfFieldSettings& settings) = 0;
  366. };
  367. /**
  368. * Shader that combines pixels for near unfocused, focused and far unfocused planes, as calculated by
  369. * GaussianDOFSeparateMat. Outputs final depth-of-field filtered image.
  370. *
  371. * @tparam Near If true, near plane pixels are read from the near plane texture, otherwise near plane is assumed
  372. * not to exist.
  373. * @tparam Far If true, far plane pixels are read from the far plane texture, otherwise far plane is assumed not
  374. * to exist.
  375. */
  376. template<bool Near, bool Far>
  377. class GaussianDOFCombineMat : public IGaussianDOFCombineMat, public RendererMaterial<GaussianDOFCombineMat<Near, Far>>
  378. {
  379. RMAT_DEF("PPGaussianDOFCombine.bsl");
  380. public:
  381. GaussianDOFCombineMat();
  382. void execute(const SPtr<Texture>& focused, const SPtr<Texture>& near, const SPtr<Texture>& far,
  383. const SPtr<Texture>& depth, const SPtr<RenderTarget>& output, const RendererView& view,
  384. const DepthOfFieldSettings& settings) override;
  385. private:
  386. SPtr<GpuParamBlockBuffer> mParamBuffer;
  387. GpuParamTexture mFocusedTexture;
  388. GpuParamTexture mNearTexture;
  389. GpuParamTexture mFarTexture;
  390. GpuParamTexture mDepthTexture;
  391. };
  392. /** Performs Gaussian depth of field effect with the help of various related shaders. */
  393. class GaussianDOF
  394. {
  395. public:
  396. /**
  397. * Executes the depth of field effect on the provided scene color texture.
  398. *
  399. * @param[in] sceneColor Input texture containing scene color.
  400. * @param[in] sceneDepth Input depth buffer texture that will be used for determining pixel depth.
  401. * @param[in] output Texture to output the results to.
  402. * @param[in] view View through which the depth of field effect is viewed.
  403. * @param[in] settings Settings used to control depth of field rendering.
  404. */
  405. void execute(const SPtr<Texture>& sceneColor, const SPtr<Texture>& sceneDepth, const SPtr<RenderTarget>& output,
  406. const RendererView& view, const DepthOfFieldSettings& settings);
  407. /** Checks does the depth of field effect need to execute. */
  408. static bool requiresDOF(const DepthOfFieldSettings& settings);
  409. private:
  410. GaussianDOFSeparateMat<true, true> mSeparateNF;
  411. GaussianDOFSeparateMat<false, true> mSeparateF;
  412. GaussianDOFSeparateMat<true, false> mSeparateN;
  413. GaussianDOFCombineMat<true, true> mCombineNF;
  414. GaussianDOFCombineMat<false, true> mCombineF;
  415. GaussianDOFCombineMat<true, false> mCombineN;
  416. GaussianBlurMat mBlur;
  417. };
  418. /** Shader that calculates a single level of the hierarchical Z mipmap chain. */
  419. class BuildHiZMat : public RendererMaterial<BuildHiZMat>
  420. {
  421. RMAT_DEF("PPBuildHiZ.bsl");
  422. public:
  423. BuildHiZMat();
  424. /**
  425. * Renders the post-process effect with the provided parameters.
  426. *
  427. * @param[in] source Input depth texture to use as the source.
  428. * @param[in] srcMip Mip level to read from the @p source texture.
  429. * @param[in] srcRect Rectangle in normalized coordinates, describing from which portion of the source
  430. * texture to read the input.
  431. * @param[in] dstRect Destination rectangle to limit the writes to.
  432. * @param[in] output Output target to which to write to results.
  433. */
  434. void execute(const SPtr<Texture>& source, UINT32 srcMip, const Rect2& srcRect, const Rect2& dstRect,
  435. const SPtr<RenderTexture>& output);
  436. private:
  437. GpuParamTexture mInputTexture;
  438. };
  439. /** Builds a hierarchical Z mipmap chain from the source depth texture. */
  440. class BuildHiZ
  441. {
  442. public:
  443. /**
  444. * Renders the post-process effect with the provided parameters.
  445. *
  446. * @param[in] viewInfo Information about the view we're rendering from.
  447. * @param[in] source Input depth texture to use as the source.
  448. * @param[in] output Output target to which to write to results. This texture should be created using the
  449. * descriptor returned by getHiZTextureDesc().
  450. */
  451. void execute(const RendererViewTargetData& viewInfo, const SPtr<Texture>& source, const SPtr<Texture>& output);
  452. /** Generates a descriptor that can be used for creating a texture to contain the HiZ mipmap chain. */
  453. static POOLED_RENDER_TEXTURE_DESC getHiZTextureDesc(UINT32 viewWidth, UINT32 viewHeight);
  454. private:
  455. BuildHiZMat mHiZMat;
  456. };
  457. BS_PARAM_BLOCK_BEGIN(FXAAParamDef)
  458. BS_PARAM_BLOCK_ENTRY(Vector2, gInvTexSize)
  459. BS_PARAM_BLOCK_END
  460. extern FXAAParamDef gFXAAParamDef;
  461. /** Shader that performs Fast Approximate anti-aliasing. */
  462. class FXAAMat : public RendererMaterial<FXAAMat>
  463. {
  464. RMAT_DEF("PPFXAA.bsl");
  465. public:
  466. FXAAMat();
  467. /**
  468. * Renders the post-process effect with the provided parameters.
  469. *
  470. * @param[in] source Input texture to apply FXAA to.
  471. * @param[in] destination Output target to which to write the antialiased image to.
  472. */
  473. void execute(const SPtr<Texture>& source, const SPtr<RenderTarget>& destination);
  474. private:
  475. SPtr<GpuParamBlockBuffer> mParamBuffer;
  476. GpuParamTexture mInputTexture;
  477. };
  478. BS_PARAM_BLOCK_BEGIN(SSAOParamDef)
  479. BS_PARAM_BLOCK_ENTRY(float, gSampleRadius)
  480. BS_PARAM_BLOCK_ENTRY(float, gWorldSpaceRadiusMask)
  481. BS_PARAM_BLOCK_ENTRY(Vector2, gTanHalfFOV)
  482. BS_PARAM_BLOCK_ENTRY(Vector2, gRandomTileScale)
  483. BS_PARAM_BLOCK_ENTRY(float, gCotHalfFOV)
  484. BS_PARAM_BLOCK_ENTRY(float, gBias)
  485. BS_PARAM_BLOCK_ENTRY(Vector2, gDownsampledPixelSize)
  486. BS_PARAM_BLOCK_ENTRY(Vector2, gFadeMultiplyAdd)
  487. BS_PARAM_BLOCK_ENTRY(float, gPower)
  488. BS_PARAM_BLOCK_ENTRY(float, gIntensity)
  489. BS_PARAM_BLOCK_END
  490. extern SSAOParamDef gSSAOParamDef;
  491. /** Textures used as input when calculating SSAO. */
  492. struct SSAOTextureInputs
  493. {
  494. /** Full resolution scene depth. Only used by final SSAO pass. */
  495. SPtr<Texture> sceneDepth;
  496. /** Full resolution buffer containing scene normals. Only used by final SSAO pass. */
  497. SPtr<Texture> sceneNormals;
  498. /** Precalculated texture containing downsampled normals/depth, to be used for AO input. */
  499. SPtr<Texture> aoSetup;
  500. /** Texture containing AO from the previous pass. Only used if upsampling is enabled. */
  501. SPtr<Texture> aoDownsampled;
  502. /** Tileable texture containing random rotations that will be applied to AO samples. */
  503. SPtr<Texture> randomRotations;
  504. };
  505. /**
  506. * Shader that computes ambient occlusion using screen based methods.
  507. *
  508. * @tparam UPSAMPLE If true the shader will blend the calculated AO with AO data from the previous pass.
  509. * @tparam FINAL_PASS If true the shader will use the full screen normal/depth information and perform
  510. * intensity scaling, as well as distance fade. Otherwise the shader will use the
  511. * downsampled AO setup information, with no scaling/fade.
  512. * @tparam QUALITY Integer in range [0, 4] that controls the quality of SSAO sampling. Higher numbers yield
  513. * better quality at the cost of performance.
  514. */
  515. template<bool UPSAMPLE, bool FINAL_PASS, int QUALITY>
  516. class SSAOMat : public RendererMaterial<SSAOMat<UPSAMPLE, FINAL_PASS, QUALITY>>
  517. {
  518. RMAT_DEF("PPSSAO.bsl");
  519. public:
  520. SSAOMat();
  521. /**
  522. * Renders the post-process effect with the provided parameters.
  523. *
  524. * @param[in] view Information about the view we're rendering from.
  525. * @param[in] textures Set of textures to be used as input. Which textures are used depends on the
  526. * template parameters of this class.
  527. * @param[in] destination Output texture to which to write the ambient occlusion data to.
  528. * @param[in] settings Settings used to control the ambient occlusion effect.
  529. */
  530. void execute(const RendererView& view, const SSAOTextureInputs& textures, const SPtr<RenderTexture>& destination,
  531. const AmbientOcclusionSettings& settings);
  532. private:
  533. SPtr<GpuParamBlockBuffer> mParamBuffer;
  534. GpuParamTexture mDepthTexture;
  535. GpuParamTexture mNormalsTexture;
  536. GpuParamTexture mDownsampledAOTexture;
  537. GpuParamTexture mSetupAOTexture;
  538. GpuParamTexture mRandomTexture;
  539. };
  540. BS_PARAM_BLOCK_BEGIN(SSAODownsampleParamDef)
  541. BS_PARAM_BLOCK_ENTRY(Vector2, gPixelSize)
  542. BS_PARAM_BLOCK_ENTRY(float, gInvDepthThreshold)
  543. BS_PARAM_BLOCK_END
  544. extern SSAODownsampleParamDef gSSAODownsampleParamDef;
  545. /**
  546. * Shader that downsamples the depth & normal buffer and stores their results in a common texture, to be consumed
  547. * by SSAOMat.
  548. */
  549. class SSAODownsampleMat : public RendererMaterial<SSAODownsampleMat>
  550. {
  551. RMAT_DEF("PPSSAODownsample.bsl");
  552. public:
  553. SSAODownsampleMat();
  554. /**
  555. * Renders the post-process effect with the provided parameters.
  556. *
  557. * @param[in] view Information about the view we're rendering from.
  558. * @param[in] sceneDepth Input texture containing scene depth.
  559. * @param[in] sceneNormals Input texture containing scene world space normals.
  560. * @param[in] destination Output texture to which to write the downsampled data to.
  561. * @param[in] depthRange Valid depth range (in view space) within which nearby samples will be averaged.
  562. */
  563. void execute(const RendererView& view, const SPtr<Texture>& sceneDepth, const SPtr<Texture>& sceneNormals,
  564. const SPtr<RenderTexture>& destination, float depthRange);
  565. private:
  566. SPtr<GpuParamBlockBuffer> mParamBuffer;
  567. GpuParamTexture mDepthTexture;
  568. GpuParamTexture mNormalsTexture;
  569. };
  570. BS_PARAM_BLOCK_BEGIN(SSAOBlurParamDef)
  571. BS_PARAM_BLOCK_ENTRY(Vector2, gPixelSize)
  572. BS_PARAM_BLOCK_ENTRY(Vector2, gPixelOffset)
  573. BS_PARAM_BLOCK_ENTRY(float, gInvDepthThreshold)
  574. BS_PARAM_BLOCK_END
  575. extern SSAOBlurParamDef gSSAOBlurParamDef;
  576. /**
  577. * Shaders that blurs the ambient occlusion output, in order to hide the noise caused by the randomization texture.
  578. */
  579. template<bool HORIZONTAL>
  580. class SSAOBlurMat : public RendererMaterial<SSAOBlurMat<HORIZONTAL>>
  581. {
  582. RMAT_DEF("PPSSAOBlur.bsl");
  583. public:
  584. SSAOBlurMat();
  585. /**
  586. * Renders the post-process effect with the provided parameters.
  587. *
  588. * @param[in] view Information about the view we're rendering from.
  589. * @param[in] ao Input texture containing ambient occlusion data to be blurred.
  590. * @param[in] sceneDepth Input texture containing scene depth.
  591. * @param[in] destination Output texture to which to write the blurred data to.
  592. * @param[in] depthRange Valid depth range (in view space) within which nearby samples will be averaged.
  593. */
  594. void execute(const RendererView& view, const SPtr<Texture>& ao, const SPtr<Texture>& sceneDepth,
  595. const SPtr<RenderTexture>& destination, float depthRange);
  596. private:
  597. SPtr<GpuParamBlockBuffer> mParamBuffer;
  598. GpuParamTexture mAOTexture;
  599. GpuParamTexture mDepthTexture;
  600. };
  601. /** Helper class that is used for calculating the SSAO information. */
  602. class SSAO
  603. {
  604. public:
  605. SSAO();
  606. /**
  607. * Calculates SSAO for the specified view.
  608. *
  609. * @param[in] view Information about the view we're rendering from.
  610. * @param[in] destination Output texture to which to write the SSAO data to.
  611. * @param[in] settings Settings that control how is SSAO calculated.
  612. */
  613. void execute(const RendererView& view, const SPtr<RenderTexture>& destination,
  614. const AmbientOcclusionSettings& settings);
  615. /**
  616. * Generates a texture that is used for randomizing sample locations during SSAO calculation. The texture contains
  617. * 16 different rotations in a 4x4 tile.
  618. */
  619. SPtr<Texture> generate4x4RandomizationTexture() const;
  620. private:
  621. /** @copydoc SSAOMat::execute() */
  622. void executeSSAOMat(bool upsample, bool final, int quality, const RendererView& view,
  623. const SSAOTextureInputs& textures, const SPtr<RenderTexture>& destination,
  624. const AmbientOcclusionSettings& settings);
  625. SSAODownsampleMat mDownsample;
  626. SSAOBlurMat<true> mBlurHorz;
  627. SSAOBlurMat<false> mBlurVert;
  628. SPtr<Texture> mSSAORandomizationTex;
  629. #define DEFINE_MATERIAL(QUALITY) \
  630. SSAOMat<false, false, QUALITY> mSSAO_FF_##QUALITY; \
  631. SSAOMat<true, false, QUALITY> mSSAO_TF_##QUALITY; \
  632. SSAOMat<false, true, QUALITY> mSSAO_FT_##QUALITY; \
  633. SSAOMat<true, true, QUALITY> mSSAO_TT_##QUALITY; \
  634. DEFINE_MATERIAL(0)
  635. DEFINE_MATERIAL(1)
  636. DEFINE_MATERIAL(2)
  637. DEFINE_MATERIAL(3)
  638. DEFINE_MATERIAL(4)
  639. #undef DEFINE_MATERIAL
  640. };
  641. BS_PARAM_BLOCK_BEGIN(SSRStencilParamDef)
  642. BS_PARAM_BLOCK_ENTRY(Vector2, gRoughnessScaleBias)
  643. BS_PARAM_BLOCK_END
  644. extern SSRStencilParamDef gSSRStencilParamDef;
  645. /** Shader used for marking which parts of the screen require screen space reflections. */
  646. class SSRStencilMat : public RendererMaterial<SSRStencilMat>
  647. {
  648. RMAT_DEF("PPSSRStencil.bsl");
  649. public:
  650. SSRStencilMat();
  651. /**
  652. * Renders the effect with the provided parameters, using the currently bound render target.
  653. *
  654. * @param[in] view Information about the view we're rendering from.
  655. * @param[in] settings Parameters used for controling the SSR effect.
  656. */
  657. void execute(const RendererView& view, const ScreenSpaceReflectionsSettings& settings);
  658. private:
  659. SPtr<GpuParamBlockBuffer> mParamBuffer;
  660. GBufferParams mGBufferParams;
  661. };
  662. BS_PARAM_BLOCK_BEGIN(SSRTraceParamDef)
  663. BS_PARAM_BLOCK_ENTRY(Vector4, gNDCToHiZUV)
  664. BS_PARAM_BLOCK_ENTRY(Vector2, gHiZUVToScreenUV)
  665. BS_PARAM_BLOCK_ENTRY(Vector2I, gHiZSize)
  666. BS_PARAM_BLOCK_ENTRY(int, gHiZNumMips)
  667. BS_PARAM_BLOCK_ENTRY(float, gIntensity)
  668. BS_PARAM_BLOCK_ENTRY(Vector2, gRoughnessScaleBias)
  669. BS_PARAM_BLOCK_END
  670. extern SSRTraceParamDef gSSRTraceParamDef;
  671. /** Shader used for tracing rays for screen space reflections. */
  672. class SSRTraceMat : public RendererMaterial<SSRTraceMat>
  673. {
  674. RMAT_DEF("PPSSRTrace.bsl");
  675. public:
  676. SSRTraceMat();
  677. /**
  678. * Renders the effect with the provided parameters.
  679. *
  680. * @param[in] view Information about the view we're rendering from.
  681. * @param[in] settings Parameters used for controling the SSR effect.
  682. * @param[in] destination Render target to which to write the results to.
  683. */
  684. void execute(const RendererView& view, const ScreenSpaceReflectionsSettings& settings,
  685. const SPtr<RenderTarget>& destination);
  686. /**
  687. * Calculates a scale & bias that is used for transforming roughness into a fade out value. Anything that is below
  688. * @p maxRoughness will have the fade value of 1. Values above @p maxRoughness is slowly fade out over a range that
  689. * is 1/2 the length of @p maxRoughness.
  690. */
  691. static Vector2 calcRoughnessFadeScaleBias(float maxRoughness);
  692. private:
  693. SPtr<GpuParamBlockBuffer> mParamBuffer;
  694. GBufferParams mGBufferParams;
  695. GpuParamTexture mSceneColorTexture;
  696. GpuParamTexture mHiZTexture;
  697. };
  698. BS_PARAM_BLOCK_BEGIN(TemporalResolveParamDef)
  699. BS_PARAM_BLOCK_ENTRY_ARRAY(float, gSampleWeights, 9)
  700. BS_PARAM_BLOCK_ENTRY_ARRAY(float, gSampleWeightsLowpass, 9)
  701. BS_PARAM_BLOCK_END
  702. extern TemporalResolveParamDef gTemporalResolveParamDef;
  703. BS_PARAM_BLOCK_BEGIN(SSRResolveParamDef)
  704. BS_PARAM_BLOCK_ENTRY(Vector2, gSceneDepthTexelSize)
  705. BS_PARAM_BLOCK_ENTRY(Vector2, gSceneColorTexelSize)
  706. BS_PARAM_BLOCK_ENTRY(float, gManualExposure)
  707. BS_PARAM_BLOCK_END
  708. extern SSRResolveParamDef gSSRResolveParamDef;
  709. /**
  710. * Shader used for combining SSR information from the previous frame, in order to yield better quality.
  711. *
  712. * @tparam EyeAdaptation When true the shader will expect a texture containing an exposure value calculated by
  713. * the eye adaptation shader. Otherwise the manually provided exposure value is used instead.
  714. */
  715. template<bool EyeAdaptation>
  716. class SSRResolveMat : public RendererMaterial<SSRResolveMat<EyeAdaptation>>
  717. {
  718. RMAT_DEF("PPSSRResolve.bsl");
  719. public:
  720. SSRResolveMat();
  721. /**
  722. * Renders the effect with the provided parameters.
  723. *
  724. * @param[in] view Information about the view we're rendering from.
  725. * @param[in] prevFrame SSR data calculated previous frame.
  726. * @param[in] curFrame SSR data calculated this frame.
  727. * @param[in] sceneDepth Buffer containing scene depth.
  728. * @param[in] destination Render target to which to write the results to.
  729. */
  730. void execute(const RendererView& view, const SPtr<Texture>& prevFrame, const SPtr<Texture>& curFrame,
  731. const SPtr<Texture>& sceneDepth, const SPtr<RenderTarget>& destination);
  732. private:
  733. SPtr<GpuParamBlockBuffer> mSSRParamBuffer;
  734. SPtr<GpuParamBlockBuffer> mTemporalParamBuffer;
  735. GpuParamTexture mSceneColorTexture;
  736. GpuParamTexture mPrevColorTexture;
  737. GpuParamTexture mSceneDepthTexture;
  738. GpuParamTexture mEyeAdaptationTexture;
  739. };
  740. /**
  741. * Renders post-processing effects for the provided render target.
  742. *
  743. * @note Core thread only.
  744. */
  745. class PostProcessing : public Module<PostProcessing>
  746. {
  747. public:
  748. /**
  749. * Renders post-processing effects for the provided render target. Resolves provided scene color texture into the
  750. * view's final output render target. Once the method exits, final render target is guaranteed to be currently
  751. * bound for rendering.
  752. */
  753. void postProcess(RendererView* viewInfo, const SPtr<RenderTargets>& renderTargets, float frameDelta);
  754. /**
  755. * Populates the ambient occlusion texture of the specified view with screen-space ambient occlusion information.
  756. * Ambient occlusion texture must be allocated on the view's render targets before calling this method.
  757. */
  758. void buildSSAO(const RendererView& view);
  759. private:
  760. DownsampleMaterials mDownsample;
  761. EyeAdaptHistogramMat mEyeAdaptHistogram;
  762. EyeAdaptHistogramReduceMat mEyeAdaptHistogramReduce;
  763. EyeAdaptationMat mEyeAdaptation;
  764. CreateTonemapLUTMat mCreateLUT;
  765. TonemappingMaterials mTonemapping;
  766. GaussianDOF mGaussianDOF;
  767. FXAAMat mFXAA;
  768. SSAO mSSAO;
  769. };
  770. /** @} */
  771. }}