BsPostProcessing.h 37 KB

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