BsPostProcessing.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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. };
  45. /** Contains per-camera data used by post process effects. */
  46. struct PostProcessInfo
  47. {
  48. PostProcessSettings settings;
  49. SPtr<PooledRenderTexture> downsampledSceneTex;
  50. SPtr<PooledRenderTexture> histogramTex;
  51. SPtr<PooledRenderTexture> histogramReduceTex;
  52. SPtr<PooledRenderTexture> eyeAdaptationTex[2];
  53. INT32 lastEyeAdaptationTex = 0;
  54. };
  55. BS_PARAM_BLOCK_BEGIN(DownsampleParams)
  56. BS_PARAM_BLOCK_ENTRY(Vector2, gInvTexSize)
  57. BS_PARAM_BLOCK_END
  58. /** Shader that downsamples a texture to half its size. */
  59. class DownsampleMat : public RendererMaterial<DownsampleMat>
  60. {
  61. RMAT_DEF("PPDownsample.bsl");
  62. public:
  63. DownsampleMat();
  64. /** Renders the post-process effect with the provided parameters. */
  65. void execute(const SPtr<RenderTextureCore>& target, PostProcessInfo& ppInfo);
  66. /** Releases the output render target. */
  67. void release(PostProcessInfo& ppInfo);
  68. /** Returns the render texture where the output will be written. */
  69. SPtr<RenderTextureCore> getOutput() const { return mOutput; }
  70. private:
  71. DownsampleParams mParams;
  72. MaterialParamVec2Core mInvTexSize;
  73. MaterialParamTextureCore mInputTexture;
  74. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  75. SPtr<RenderTextureCore> mOutput;
  76. };
  77. BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramParams)
  78. BS_PARAM_BLOCK_ENTRY(Vector4I, gPixelOffsetAndSize)
  79. BS_PARAM_BLOCK_ENTRY(Vector2, gHistogramParams)
  80. BS_PARAM_BLOCK_ENTRY(Vector2I, gThreadGroupCount)
  81. BS_PARAM_BLOCK_END
  82. /** Shader that creates a luminance histogram used for eye adaptation. */
  83. class EyeAdaptHistogramMat : public RendererMaterial<EyeAdaptHistogramMat>
  84. {
  85. RMAT_DEF("PPEyeAdaptHistogram.bsl");
  86. public:
  87. EyeAdaptHistogramMat();
  88. /** Executes the post-process effect with the provided parameters. */
  89. void execute(PostProcessInfo& ppInfo);
  90. /** Releases the output render target. */
  91. void release(PostProcessInfo& ppInfo);
  92. /** Returns the render texture where the output was written. */
  93. SPtr<RenderTextureCore> getOutput() const { return mOutput; }
  94. /** Calculates the number of thread groups that need to execute to cover the provided render target. */
  95. static Vector2I getThreadGroupCount(const SPtr<RenderTextureCore>& target);
  96. /**
  97. * Returns a vector containing scale and offset (in that order) that will be applied to luminance values
  98. * to determine their position in the histogram.
  99. */
  100. static Vector2 getHistogramScaleOffset(const PostProcessInfo& ppInfo);
  101. static const UINT32 THREAD_GROUP_SIZE_X = 8;
  102. static const UINT32 THREAD_GROUP_SIZE_Y = 8;
  103. static const UINT32 HISTOGRAM_NUM_TEXELS = (THREAD_GROUP_SIZE_X * THREAD_GROUP_SIZE_Y) / 4;
  104. private:
  105. EyeAdaptHistogramParams mParams;
  106. MaterialParamTextureCore mSceneColor;
  107. MaterialParamLoadStoreTextureCore mOutputTex;
  108. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  109. SPtr<RenderTextureCore> mOutput;
  110. static const UINT32 LOOP_COUNT_X = 8;
  111. static const UINT32 LOOP_COUNT_Y = 8;
  112. };
  113. BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramReduceParams)
  114. BS_PARAM_BLOCK_ENTRY(int, gThreadGroupCount)
  115. BS_PARAM_BLOCK_END
  116. /** Shader that reduces the luminance histograms created by EyeAdaptHistogramMat into a single histogram. */
  117. class EyeAdaptHistogramReduceMat : public RendererMaterial<EyeAdaptHistogramReduceMat>
  118. {
  119. RMAT_DEF("PPEyeAdaptHistogramReduce.bsl");
  120. public:
  121. EyeAdaptHistogramReduceMat();
  122. /** Executes the post-process effect with the provided parameters. */
  123. void execute(PostProcessInfo& ppInfo);
  124. /** Releases the output render target. */
  125. void release(PostProcessInfo& ppInfo);
  126. /** Returns the render texture where the output was written. */
  127. SPtr<RenderTextureCore> getOutput() const { return mOutput; }
  128. private:
  129. EyeAdaptHistogramReduceParams mParams;
  130. MaterialParamTextureCore mHistogramTex;
  131. MaterialParamTextureCore mEyeAdaptationTex;
  132. POOLED_RENDER_TEXTURE_DESC mOutputDesc;
  133. SPtr<RenderTextureCore> mOutput;
  134. };
  135. BS_PARAM_BLOCK_BEGIN(EyeAdaptationParams)
  136. BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gEyeAdaptationParams, 3)
  137. BS_PARAM_BLOCK_END
  138. /** Shader that computes the eye adaptation value based on scene luminance. */
  139. class EyeAdaptationMat : public RendererMaterial<EyeAdaptationMat>
  140. {
  141. RMAT_DEF("PPEyeAdaptation.bsl");
  142. public:
  143. EyeAdaptationMat();
  144. /** Executes the post-process effect with the provided parameters. */
  145. void execute(PostProcessInfo& ppInfo, float frameDelta);
  146. private:
  147. EyeAdaptationParams mParams;
  148. MaterialParamTextureCore mReducedHistogramTex;
  149. };
  150. /** Shader that applies tonemapping and converts a HDR image into a LDR image. */
  151. class TonemappingMat : public RendererMaterial<TonemappingMat>
  152. {
  153. RMAT_DEF("PPTonemapping.bsl");
  154. public:
  155. TonemappingMat();
  156. /** Executes the post-process effect with the provided parameters. */
  157. void execute(const SPtr<RenderTextureCore>& sceneColor, const SPtr<ViewportCore>& outputViewport,
  158. PostProcessInfo& ppInfo);
  159. private:
  160. MaterialParamTextureCore mInputTex;
  161. MaterialParamTextureCore mEyeAdaptationTex;
  162. };
  163. /**
  164. * Renders post-processing effects for the provided render target.
  165. *
  166. * @note Core thread only.
  167. */
  168. class BS_BSRND_EXPORT PostProcessing : public Module<PostProcessing>
  169. {
  170. public:
  171. /** Renders post-processing effects for the provided render target. */
  172. void postProcess(const SPtr<RenderTextureCore>& sceneColor, const SPtr<ViewportCore>& outputViewport,
  173. PostProcessInfo& ppInfo, float frameDelta);
  174. private:
  175. DownsampleMat mDownsample;
  176. EyeAdaptHistogramMat mEyeAdaptHistogram;
  177. EyeAdaptHistogramReduceMat mEyeAdaptHistogramReduce;
  178. EyeAdaptationMat mEyeAdaptation;
  179. TonemappingMat mTonemapping;
  180. };
  181. /** @} */
  182. }