BsPostProcessing.h 35 KB

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