BsRenderBeastIBLUtility.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsPrerequisites.h"
  5. #include "Renderer/BsIBLUtility.h"
  6. #include "Renderer/BsRendererMaterial.h"
  7. #include "Renderer/BsParamBlocks.h"
  8. #include "BsGpuResourcePool.h"
  9. namespace bs { namespace ct
  10. {
  11. /** @addtogroup RenderBeast
  12. * @{
  13. */
  14. BS_PARAM_BLOCK_BEGIN(ReflectionCubeDownsampleParamDef)
  15. BS_PARAM_BLOCK_ENTRY(int, gCubeFace)
  16. BS_PARAM_BLOCK_ENTRY(int, gMipLevel)
  17. BS_PARAM_BLOCK_END
  18. extern ReflectionCubeDownsampleParamDef gReflectionCubeDownsampleParamDef;
  19. /** Performs filtering on cubemap faces in order to prepare them for importance sampling. */
  20. class ReflectionCubeDownsampleMat : public RendererMaterial<ReflectionCubeDownsampleMat>
  21. {
  22. RMAT_DEF("ReflectionCubeDownsample.bsl")
  23. public:
  24. ReflectionCubeDownsampleMat();
  25. /** Downsamples the provided texture face and outputs it to the provided target. */
  26. void execute(const SPtr<Texture>& source, UINT32 face, UINT32 mip, const SPtr<RenderTarget>& target);
  27. private:
  28. SPtr<GpuParamBlockBuffer> mParamBuffer;
  29. GpuParamTexture mInputTexture;
  30. };
  31. BS_PARAM_BLOCK_BEGIN(ReflectionCubeImportanceSampleParamDef)
  32. BS_PARAM_BLOCK_ENTRY(int, gCubeFace)
  33. BS_PARAM_BLOCK_ENTRY(int, gMipLevel)
  34. BS_PARAM_BLOCK_ENTRY(int, gNumMips)
  35. BS_PARAM_BLOCK_ENTRY(float, gPrecomputedMipFactor)
  36. BS_PARAM_BLOCK_END
  37. extern ReflectionCubeImportanceSampleParamDef gReflectionCubeImportanceSampleParamDef;
  38. /** Performs importance sampling on cubemap faces in order for make them suitable for specular evaluation. */
  39. class ReflectionCubeImportanceSampleMat : public RendererMaterial<ReflectionCubeImportanceSampleMat>
  40. {
  41. RMAT_DEF("ReflectionCubeImportanceSample.bsl")
  42. public:
  43. ReflectionCubeImportanceSampleMat();
  44. /** Importance samples the provided texture face and outputs it to the provided target. */
  45. void execute(const SPtr<Texture>& source, UINT32 face, UINT32 mip, const SPtr<RenderTarget>& target);
  46. private:
  47. static const UINT32 NUM_SAMPLES;
  48. SPtr<GpuParamBlockBuffer> mParamBuffer;
  49. GpuParamTexture mInputTexture;
  50. };
  51. /** Vector representing spherical harmonic coefficients for 5 bands. */
  52. struct SHVector5
  53. {
  54. SHVector5()
  55. :coeffs()
  56. { }
  57. float coeffs[25];
  58. };
  59. /** Vector representing spherical coefficients for 5 bands, separate for red, green and blue components. */
  60. struct SHVector5RGB
  61. {
  62. SHVector5 R, G, B;
  63. };
  64. /** Vector representing spherical harmonic coefficients for 3 bands. */
  65. struct SHVector3
  66. {
  67. float coeffs[9];
  68. };
  69. /** Vector representing spherical coefficients for 3 bands, separate for red, green and blue components. */
  70. struct SHVector3RGB
  71. {
  72. SHVector3 R, G, B;
  73. };
  74. /** Intermediate structure used for spherical coefficient calculation. Contains RGB coefficients and weight. */
  75. struct SHCoeffsAndWeight5
  76. {
  77. SHVector5RGB coeffs;
  78. float weight;
  79. };
  80. /** Intermediate structure used for spherical coefficient calculation. Contains RGB coefficients and weight. */
  81. struct SHCoeffsAndWeight3
  82. {
  83. SHVector3RGB coeffs;
  84. float weight;
  85. };
  86. BS_PARAM_BLOCK_BEGIN(IrradianceComputeSHParamDef)
  87. BS_PARAM_BLOCK_ENTRY(int, gCubeFace)
  88. BS_PARAM_BLOCK_ENTRY(int, gFaceSize)
  89. BS_PARAM_BLOCK_ENTRY(Vector2I, gDispatchSize)
  90. BS_PARAM_BLOCK_END
  91. extern IrradianceComputeSHParamDef gIrradianceComputeSHParamDef;
  92. /** Computes spherical harmonic coefficients from a radiance cubemap. */
  93. class IrradianceComputeSHMat : public RendererMaterial<IrradianceComputeSHMat>
  94. {
  95. RMAT_DEF("IrradianceComputeSH.bsl")
  96. public:
  97. IrradianceComputeSHMat();
  98. /**
  99. * Computes spherical harmonic coefficients from a radiance texture and outputs a buffer containing a list of
  100. * coefficient sets (one set of coefficients for each thread group). Coefficients must be reduced and normalized
  101. * by IrradianceReduceSHMat before use. Output buffer should be created by calling createOutputBuffer().
  102. */
  103. void execute(const SPtr<Texture>& source, UINT32 face, const SPtr<GpuBuffer>& output);
  104. /** Creates a buffer of adequate size to be used as output for this material. */
  105. SPtr<GpuBuffer> createOutputBuffer(const SPtr<Texture>& source, UINT32& numCoeffSets);
  106. /**
  107. * Returns the material variation matching the provided parameters.
  108. *
  109. * @param order SH order, which defines the number of coefficients and quality. Only values of 3 and 5 are
  110. * supported.
  111. */
  112. static IrradianceComputeSHMat* getVariation(int order = 5);
  113. private:
  114. SPtr<GpuParamBlockBuffer> mParamBuffer;
  115. GpuParamTexture mInputTexture;
  116. GpuParamBuffer mOutputBuffer;
  117. static ShaderVariation VAR_Order3;
  118. static ShaderVariation VAR_Order5;
  119. };
  120. BS_PARAM_BLOCK_BEGIN(IrradianceReduceSHParamDef)
  121. BS_PARAM_BLOCK_ENTRY(Vector2I, gOutputIdx)
  122. BS_PARAM_BLOCK_ENTRY(int, gNumEntries)
  123. BS_PARAM_BLOCK_END
  124. extern IrradianceReduceSHParamDef gIrradianceReduceSHParamDef;
  125. /**
  126. * Sums spherical harmonic coefficients calculated by each thread group of IrradianceComputeSHMat and outputs a single
  127. * set of normalized coefficients.
  128. */
  129. class IrradianceReduceSHMat : public RendererMaterial<IrradianceReduceSHMat>
  130. {
  131. RMAT_DEF("IrradianceReduceSH.bsl")
  132. public:
  133. IrradianceReduceSHMat();
  134. /**
  135. * Sums spherical harmonic coefficients calculated by each thread group of IrradianceComputeSHMat and outputs a
  136. * single set of normalized coefficients. Output texture should be created by calling createOutputTexture(). The
  137. * value will be recorded at the @p outputIdx position in the texture.
  138. */
  139. void execute(const SPtr<GpuBuffer>& source, UINT32 numCoeffSets, const SPtr<Texture>& output, UINT32 outputIdx);
  140. /** Creates a texture of adequate size to be used as output for this material. */
  141. SPtr<Texture> createOutputTexture(UINT32 numCoeffSets);
  142. /**
  143. * Returns the material variation matching the provided parameters.
  144. *
  145. * @param order SH order, which defines the number of coefficients and quality. Only values of 3 and 5 are
  146. * supported.
  147. */
  148. static IrradianceReduceSHMat* getVariation(int order = 5);
  149. private:
  150. SPtr<GpuParamBlockBuffer> mParamBuffer;
  151. GpuParamBuffer mInputBuffer;
  152. GpuParamLoadStoreTexture mOutputTexture;
  153. static ShaderVariation VAR_Order3;
  154. static ShaderVariation VAR_Order5;
  155. };
  156. BS_PARAM_BLOCK_BEGIN(IrradianceComputeSHFragParamDef)
  157. BS_PARAM_BLOCK_ENTRY(int, gCubeFace)
  158. BS_PARAM_BLOCK_ENTRY(int, gFaceSize)
  159. BS_PARAM_BLOCK_ENTRY(int, gCoeffIdx)
  160. BS_PARAM_BLOCK_END
  161. extern IrradianceComputeSHFragParamDef gIrradianceComputeSHFragParamDef;
  162. /**
  163. * Computes spherical harmonic coefficients from a radiance cubemap. This is an alternative to IrradianceComputeSHMat
  164. * that does not require compute shader support.
  165. */
  166. class IrradianceComputeSHFragMat : public RendererMaterial<IrradianceComputeSHFragMat>
  167. {
  168. RMAT_DEF("IrradianceComputeSHFrag.bsl")
  169. public:
  170. IrradianceComputeSHFragMat();
  171. /**
  172. * Computes spherical harmonic coefficients from a face of an input cube radiance texture and outputs them to the
  173. * specified face of the output cube texture. Only a single coefficient is output per execution. The output texture
  174. * will contain the coefficients for red, green and blue channels in the corresponding texture channels, and
  175. * per-texel weight in the alpha channel. Output coefficients must be summed up and normalized before use (using
  176. * IrradianceAccumulateCubeSH).
  177. */
  178. void execute(const SPtr<Texture>& source, UINT32 face, UINT32 coefficientIdx, const SPtr<RenderTarget>& output);
  179. /**
  180. * Returns the texture descriptor that can be used for initializing the output render target. Note that the
  181. * output texture is a cubemap but the execute() method expects a render target that is a single face of a
  182. * cubemap.
  183. */
  184. static POOLED_RENDER_TEXTURE_DESC getOutputDesc(const SPtr<Texture>& source);
  185. private:
  186. SPtr<GpuParamBlockBuffer> mParamBuffer;
  187. GpuParamTexture mInputTexture;
  188. };
  189. BS_PARAM_BLOCK_BEGIN(IrradianceAccumulateSHParamDef)
  190. BS_PARAM_BLOCK_ENTRY(int, gCubeFace)
  191. BS_PARAM_BLOCK_ENTRY(int, gCubeMip)
  192. BS_PARAM_BLOCK_ENTRY(Vector2, gHalfPixel)
  193. BS_PARAM_BLOCK_END
  194. extern IrradianceAccumulateSHParamDef gIrradianceAccumulateSHParamDef;
  195. /**
  196. * Downsamples a cubemap face containing SH coefficient and weight values as output by IrradianceComputeSHFragMat. Each
  197. * downsample sums up 2x2 pixel area coefficients/weights from the previous mip level.
  198. */
  199. class IrradianceAccumulateSHMat : public RendererMaterial<IrradianceAccumulateSHMat>
  200. {
  201. RMAT_DEF("IrradianceAccumulateSH.bsl")
  202. public:
  203. IrradianceAccumulateSHMat();
  204. /**
  205. * Downsamples the provided face and mip level of the source texture and outputs the downsampled (i.e summed up)
  206. * values in the resulting output texture.
  207. */
  208. void execute(const SPtr<Texture>& source, UINT32 face, UINT32 sourceMip, const SPtr<RenderTarget>& output);
  209. /**
  210. * Returns the texture descriptor that can be used for initializing the output render target. Note the output
  211. * is a cubemap.
  212. */
  213. static POOLED_RENDER_TEXTURE_DESC getOutputDesc(const SPtr<Texture>& source);
  214. private:
  215. SPtr<GpuParamBlockBuffer> mParamBuffer;
  216. GpuParamTexture mInputTexture;
  217. };
  218. /**
  219. * Accumulates SH coefficient values from all six faces of a cubemap and normalizes them. The cubemap is expected to be
  220. * 1x1 in size (previously downsampled by IrradianceAccumulateSHMat). After this shader is ran for all SH coefficients
  221. * the output texture will contain final valid set of SH coefficients.
  222. */
  223. class IrradianceAccumulateCubeSHMat : public RendererMaterial<IrradianceAccumulateCubeSHMat>
  224. {
  225. RMAT_DEF("IrradianceAccumulateCubeSH.bsl")
  226. public:
  227. IrradianceAccumulateCubeSHMat();
  228. /**
  229. * Sums up all faces of the input cube texture and writes the value to the corresponding index in the output
  230. * texture. The source mip should point to a mip level with size 1x1.
  231. */
  232. void execute(const SPtr<Texture>& source, UINT32 sourceMip, const Vector2I& outputOffset, UINT32 coefficientIdx,
  233. const SPtr<RenderTarget>& output);
  234. /**
  235. * Returns the texture descriptor that can be used for initializing the output render target. The render target
  236. * will be able to hold all required SH coefficients (even though execute() outputs just one coefficient at a time).
  237. */
  238. static POOLED_RENDER_TEXTURE_DESC getOutputDesc();
  239. private:
  240. SPtr<GpuParamBlockBuffer> mParamBuffer;
  241. GpuParamTexture mInputTexture;
  242. };
  243. BS_PARAM_BLOCK_BEGIN(IrradianceProjectSHParamDef)
  244. BS_PARAM_BLOCK_ENTRY(int, gCubeFace)
  245. BS_PARAM_BLOCK_END
  246. extern IrradianceProjectSHParamDef gIrradianceProjectSHParamDef;
  247. /**
  248. * Projects spherical harmonic coefficients calculated by IrradianceReduceSHMat and projects them onto faces of
  249. * a cubemap.
  250. */
  251. class IrradianceProjectSHMat : public RendererMaterial<IrradianceProjectSHMat>
  252. {
  253. RMAT_DEF("IrradianceProjectSH.bsl")
  254. public:
  255. IrradianceProjectSHMat();
  256. /**
  257. * Projects spherical harmonic coefficients calculated by IrradianceReduceSHMat and projects them onto faces of
  258. * a cubemap.
  259. */
  260. void execute(const SPtr<Texture>& shCoeffs, UINT32 face, const SPtr<RenderTarget>& target);
  261. private:
  262. SPtr<GpuParamBlockBuffer> mParamBuffer;
  263. GpuParamTexture mInputTexture;
  264. };
  265. /** Render beast implementation of IBLUtility. */
  266. class RenderBeastIBLUtility : public IBLUtility
  267. {
  268. public:
  269. /** @copydoc IBLUtility::filterCubemapForSpecular */
  270. void filterCubemapForSpecular(const SPtr<Texture>& cubemap, const SPtr<Texture>& scratch) const override;
  271. /** @copydoc IBLUtility::filterCubemapForIrradiance(const SPtr<Texture>&, const SPtr<Texture>&) */
  272. void filterCubemapForIrradiance(const SPtr<Texture>& cubemap, const SPtr<Texture>& output) const override;
  273. /** @copydoc IBLUtility::filterCubemapForIrradiance(const SPtr<Texture>&, const SPtr<GpuBuffer>&, UINT32) */
  274. void filterCubemapForIrradiance(const SPtr<Texture>& cubemap, const SPtr<Texture>& output,
  275. UINT32 outputIdx) const override;
  276. /** @copydoc IBLUtility::scaleCubemap */
  277. void scaleCubemap(const SPtr<Texture>& src, UINT32 srcMip, const SPtr<Texture>& dst, UINT32 dstMip) const override;
  278. private:
  279. /**
  280. * Downsamples a cubemap using hardware bilinear filtering.
  281. *
  282. * @param[in] src Cubemap to downsample.
  283. * @param[in] srcMip Determines which mip level of the source texture to downsample.
  284. * @param[in] dst Desination texture to output the scaled data to. Must be usable as a render target.
  285. * @param[in] dstMip Determines which mip level of the destination texture to scale.
  286. */
  287. static void downsampleCubemap(const SPtr<Texture>& src, UINT32 srcMip, const SPtr<Texture>& dst, UINT32 dstMip);
  288. /**
  289. * Generates irradiance SH coefficients from the input cubemap and writes them to a 1D texture. Does not make
  290. * use of the compute shader.
  291. */
  292. static void filterCubemapForIrradianceNonCompute(const SPtr<Texture>& cubemap, UINT32 outputIdx,
  293. const SPtr<RenderTexture>& output);
  294. };
  295. /** @} */
  296. }}