BsPostProcessing.h 30 KB

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