BsPostProcessing.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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 "BsRenderTexturePool.h"
  8. namespace BansheeEngine
  9. {
  10. /** @addtogroup RenderBeast
  11. * @{
  12. */
  13. /** Settings that control the post-process operation. */
  14. struct PostProcessSettings
  15. {
  16. PostProcessSettings();
  17. /**
  18. * Determines minimum luminance value in the eye adaptation histogram. In log2 units (-8 = 1/256). In the range
  19. * [-16, 0].
  20. */
  21. float histogramLog2Min;
  22. /**
  23. * Determines maximum luminance value in the eye adaptation histogram. In log2 units (4 = 16). In the range
  24. * [0, 16].
  25. */
  26. float histogramLog2Max;
  27. /** Percentage below which to ignore values in the eye adaptation histogram. In range [0.0f, 1.0f]. */
  28. float histogramPctLow;
  29. /** Percentage above which to ignore values in the eye adaptation histogram. In range [0.0f, 1.0f]. */
  30. float histogramPctHigh;
  31. /** Clamps the minimum eye adaptation scale (pre-exposure scale) to this value. In range [0.0f, 10.0f]. */
  32. float minEyeAdaptation;
  33. /** Clamps the maximum eye adaptation scale (pre-exposure scale) to this value. In range [0.0f, 10.0f]. */
  34. float maxEyeAdaptation;
  35. /**
  36. * Log2 value to scale the eye adaptation by. Smaller values yield darker image, while larger yield brighter image.
  37. * In range [-8, 8].
  38. */
  39. float exposureScale;
  40. /** Determines how quickly does the eye adaptation adjust to larger values. In range [0.01f, 20.0f]. */
  41. float eyeAdaptationSpeedUp;
  42. /** Determines how quickly does the eye adaptation adjust to smaller values. In range [0.01f, 20.0f]. */
  43. float eyeAdaptationSpeedDown;
  44. /** Value that controls the shoulder (upper non-linear) section of the filmic curve. Affects high-range. */
  45. float filmicCurveShoulderStrength;
  46. /** Value that controls the linear (middle) section of the filmic curve. Affects mid-range. */
  47. float filmicCurveLinearStrength;
  48. /** Value that controls the linear (middle) section of the filmic curve. Affects mid-range. */
  49. float filmicCurveLinearAngle;
  50. /** Value that controls the toe (lower non-linear) section of the filmic curve. Affects low-range. */
  51. float filmicCurveToeStrength;
  52. /** Value that controls the toe (lower non-linear) section of the filmic curve. Affects low-range. */
  53. float filmicCurveToeNumerator;
  54. /** Value that controls the toe (lower non-linear) section of the filmic curve. Affects low-range. */
  55. float filmicCurveToeDenominator;
  56. /** Value that controls the white point of the filmic curve. Affects the entire curve. */
  57. float filmicCurveLinearWhitePoint;
  58. /** Determines should the final output be tonemapped. */
  59. bool tonemapping;
  60. /** Determines should automatic exposure be applied to the HDR image. */
  61. bool autoExposure;
  62. /** Gamma value to adjust the image for. Larger values result in a brighter image. */
  63. float gamma;
  64. };
  65. /** Contains per-camera data used by post process effects. */
  66. struct PostProcessInfo
  67. {
  68. PostProcessSettings settings;
  69. SPtr<PooledRenderTexture> downsampledSceneTex;
  70. SPtr<PooledRenderTexture> histogramTex;
  71. SPtr<PooledRenderTexture> histogramReduceTex;
  72. SPtr<PooledRenderTexture> eyeAdaptationTex[2];
  73. SPtr<PooledRenderTexture> colorLUT;
  74. INT32 lastEyeAdaptationTex = 0;
  75. };
  76. BS_PARAM_BLOCK_BEGIN(DownsampleParams)
  77. BS_PARAM_BLOCK_ENTRY(Vector2, gInvTexSize)
  78. BS_PARAM_BLOCK_END
  79. /** Shader that downsamples a texture to half its size. */
  80. class DownsampleMat : public RendererMaterial<DownsampleMat>
  81. {
  82. RMAT_DEF("PPDownsample.bsl");
  83. public:
  84. DownsampleMat();
  85. /** Renders the post-process effect with the provided parameters. */
  86. void execute(const SPtr<RenderTextureCore>& target, PostProcessInfo& ppInfo);
  87. /** Releases the output render target. */
  88. void release(PostProcessInfo& ppInfo);
  89. /** Returns the render texture where the output will be written. */
  90. SPtr<RenderTextureCore> getOutput() const { return mOutput; }
  91. private:
  92. DownsampleParams mParams;
  93. MaterialParamVec2Core mInvTexSize;
  94. MaterialParamTextureCore mInputTexture;
  95. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  96. SPtr<RenderTextureCore> mOutput;
  97. };
  98. BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramParams)
  99. BS_PARAM_BLOCK_ENTRY(Vector4I, gPixelOffsetAndSize)
  100. BS_PARAM_BLOCK_ENTRY(Vector2, gHistogramParams)
  101. BS_PARAM_BLOCK_ENTRY(Vector2I, gThreadGroupCount)
  102. BS_PARAM_BLOCK_END
  103. /** Shader that creates a luminance histogram used for eye adaptation. */
  104. class EyeAdaptHistogramMat : public RendererMaterial<EyeAdaptHistogramMat>
  105. {
  106. RMAT_DEF("PPEyeAdaptHistogram.bsl");
  107. public:
  108. EyeAdaptHistogramMat();
  109. /** Executes the post-process effect with the provided parameters. */
  110. void execute(PostProcessInfo& ppInfo);
  111. /** Releases the output render target. */
  112. void release(PostProcessInfo& ppInfo);
  113. /** Returns the render texture where the output was written. */
  114. SPtr<RenderTextureCore> getOutput() const { return mOutput; }
  115. /** Calculates the number of thread groups that need to execute to cover the provided render target. */
  116. static Vector2I getThreadGroupCount(const SPtr<RenderTextureCore>& target);
  117. /**
  118. * Returns a vector containing scale and offset (in that order) that will be applied to luminance values
  119. * to determine their position in the histogram.
  120. */
  121. static Vector2 getHistogramScaleOffset(const PostProcessInfo& ppInfo);
  122. static const UINT32 THREAD_GROUP_SIZE_X = 8;
  123. static const UINT32 THREAD_GROUP_SIZE_Y = 8;
  124. static const UINT32 HISTOGRAM_NUM_TEXELS = (THREAD_GROUP_SIZE_X * THREAD_GROUP_SIZE_Y) / 4;
  125. private:
  126. EyeAdaptHistogramParams mParams;
  127. MaterialParamTextureCore mSceneColor;
  128. MaterialParamLoadStoreTextureCore mOutputTex;
  129. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  130. SPtr<RenderTextureCore> mOutput;
  131. static const UINT32 LOOP_COUNT_X = 8;
  132. static const UINT32 LOOP_COUNT_Y = 8;
  133. };
  134. BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramReduceParams)
  135. BS_PARAM_BLOCK_ENTRY(int, gThreadGroupCount)
  136. BS_PARAM_BLOCK_END
  137. /** Shader that reduces the luminance histograms created by EyeAdaptHistogramMat into a single histogram. */
  138. class EyeAdaptHistogramReduceMat : public RendererMaterial<EyeAdaptHistogramReduceMat>
  139. {
  140. RMAT_DEF("PPEyeAdaptHistogramReduce.bsl");
  141. public:
  142. EyeAdaptHistogramReduceMat();
  143. /** Executes the post-process effect with the provided parameters. */
  144. void execute(PostProcessInfo& ppInfo);
  145. /** Releases the output render target. */
  146. void release(PostProcessInfo& ppInfo);
  147. /** Returns the render texture where the output was written. */
  148. SPtr<RenderTextureCore> getOutput() const { return mOutput; }
  149. private:
  150. EyeAdaptHistogramReduceParams mParams;
  151. MaterialParamTextureCore mHistogramTex;
  152. MaterialParamTextureCore mEyeAdaptationTex;
  153. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  154. SPtr<RenderTextureCore> mOutput;
  155. };
  156. BS_PARAM_BLOCK_BEGIN(EyeAdaptationParams)
  157. BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gEyeAdaptationParams, 3)
  158. BS_PARAM_BLOCK_END
  159. /** Shader that computes the eye adaptation value based on scene luminance. */
  160. class EyeAdaptationMat : public RendererMaterial<EyeAdaptationMat>
  161. {
  162. RMAT_DEF("PPEyeAdaptation.bsl");
  163. public:
  164. EyeAdaptationMat();
  165. /** Executes the post-process effect with the provided parameters. */
  166. void execute(PostProcessInfo& ppInfo, float frameDelta);
  167. private:
  168. EyeAdaptationParams mParams;
  169. MaterialParamTextureCore mReducedHistogramTex;
  170. };
  171. BS_PARAM_BLOCK_BEGIN(CreateTonemapLUTParams)
  172. BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gTonemapParams, 2)
  173. BS_PARAM_BLOCK_ENTRY(float, gGammaAdjustment)
  174. BS_PARAM_BLOCK_ENTRY(int, gGammaCorrectionType)
  175. BS_PARAM_BLOCK_END
  176. /**
  177. * Shader that creates a 3D lookup texture that is used to apply tonemapping, color grading, white balancing and gamma
  178. * correction.
  179. */
  180. class CreateTonemapLUTMat : public RendererMaterial<CreateTonemapLUTMat>
  181. {
  182. RMAT_DEF("PPCreateTonemapLUT.bsl");
  183. public:
  184. CreateTonemapLUTMat();
  185. /** Executes the post-process effect with the provided parameters. */
  186. void execute(PostProcessInfo& ppInfo);
  187. /** Releases the output render target. */
  188. void release(PostProcessInfo& ppInfo);
  189. /** Size of the 3D color lookup table. */
  190. static const UINT32 LUT_SIZE = 32;
  191. private:
  192. CreateTonemapLUTParams mParams;
  193. };
  194. BS_PARAM_BLOCK_BEGIN(TonemappingParams)
  195. BS_PARAM_BLOCK_ENTRY(float, gRawGamma)
  196. BS_PARAM_BLOCK_ENTRY(float, gManualExposureScale)
  197. BS_PARAM_BLOCK_END
  198. /** Shader that applies tonemapping and converts a HDR image into a LDR image. */
  199. template<bool GammaOnly, bool AutoExposure>
  200. class TonemappingMat : public RendererMaterial<TonemappingMat<GammaOnly, AutoExposure>>
  201. {
  202. RMAT_DEF("PPTonemapping.bsl");
  203. public:
  204. TonemappingMat();
  205. /** Executes the post-process effect with the provided parameters. */
  206. void execute(const SPtr<RenderTextureCore>& sceneColor, const SPtr<ViewportCore>& outputViewport,
  207. PostProcessInfo& ppInfo);
  208. private:
  209. TonemappingParams mParams;
  210. MaterialParamTextureCore mInputTex;
  211. MaterialParamTextureCore mColorLUT;
  212. MaterialParamTextureCore mEyeAdaptationTex;
  213. };
  214. /**
  215. * Renders post-processing effects for the provided render target.
  216. *
  217. * @note Core thread only.
  218. */
  219. class BS_BSRND_EXPORT PostProcessing : public Module<PostProcessing>
  220. {
  221. public:
  222. /** Renders post-processing effects for the provided render target. */
  223. void postProcess(const SPtr<RenderTextureCore>& sceneColor, const SPtr<ViewportCore>& outputViewport,
  224. PostProcessInfo& ppInfo, float frameDelta);
  225. private:
  226. DownsampleMat mDownsample;
  227. EyeAdaptHistogramMat mEyeAdaptHistogram;
  228. EyeAdaptHistogramReduceMat mEyeAdaptHistogramReduce;
  229. EyeAdaptationMat mEyeAdaptation;
  230. CreateTonemapLUTMat mCreateLUT;
  231. TonemappingMat<false, true> mTonemapping_AE;
  232. TonemappingMat<true, true> mTonemapping_AE_GO;
  233. TonemappingMat<false, false> mTonemapping;
  234. TonemappingMat<true, false> mTonemapping_GO;
  235. };
  236. /** @} */
  237. }