BsLightProbes.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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 "Utility/BsTriangulation.h"
  6. #include "Math/BsMatrix4.h"
  7. #include "Math/BsMatrixNxM.h"
  8. #include "Renderer/BsRendererMaterial.h"
  9. #include "BsGpuResourcePool.h"
  10. #include "Renderer/BsParamBlocks.h"
  11. #include "BsLightRendering.h"
  12. namespace bs { namespace ct
  13. {
  14. struct LightProbesInfo;
  15. struct GBufferTextures;
  16. struct FrameInfo;
  17. class LightProbeVolume;
  18. /** @addtogroup RenderBeast
  19. * @{
  20. */
  21. BS_PARAM_BLOCK_BEGIN(TetrahedraRenderParamDef)
  22. BS_PARAM_BLOCK_ENTRY(Vector2I, gDepthTexSize)
  23. BS_PARAM_BLOCK_END
  24. extern TetrahedraRenderParamDef gTetrahedraRenderParamDef;
  25. /**
  26. * Shader that renders the tetrahedra used for light probe evaluation. Tetrahedra depth is compare with current scene
  27. * depth, and for each scene pixel the matching tetrahedron index is written to the output target.
  28. */
  29. class TetrahedraRenderMat : public RendererMaterial<TetrahedraRenderMat>
  30. {
  31. RMAT_DEF("TetrahedraRender.bsl");
  32. public:
  33. TetrahedraRenderMat();
  34. /**
  35. * Executes the material using the provided parameters.
  36. *
  37. * @param[in] view View that is currently being rendered.
  38. * @param[in] sceneDepth Depth of scene objects that should be lit.
  39. * @param[in] mesh Mesh to render.
  40. * @param[in] output Output texture created using the descriptor returned by getOutputDesc().
  41. */
  42. void execute(const RendererView& view, const SPtr<Texture>& sceneDepth, const SPtr<Mesh>& mesh,
  43. const SPtr<RenderTexture>& output);
  44. /**
  45. * Returns the descriptors that can be used for creating the output render texture for this material. The render
  46. * texture is expected to have a single color attachment, and a depth attachment.
  47. */
  48. static void getOutputDesc(const RendererView& view, POOLED_RENDER_TEXTURE_DESC& colorDesc,
  49. POOLED_RENDER_TEXTURE_DESC& depthDesc);
  50. /**
  51. * Returns the material variation matching the provided parameters.
  52. *
  53. * @param[in] msaa True if the shader will operate on a multisampled surface.
  54. * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be
  55. * evaluated. Otherwise all samples will be evaluated.
  56. * @return Requested variation of the material.
  57. */
  58. static TetrahedraRenderMat* getVariation(bool msaa, bool singleSampleMSAA);
  59. private:
  60. SPtr<GpuParamBlockBuffer> mParamBuffer;
  61. GpuParamTexture mDepthBufferTex;
  62. static ShaderVariation VAR_FullMSAA;
  63. static ShaderVariation VAR_SingleMSAA;
  64. static ShaderVariation VAR_NoMSAA;
  65. };
  66. BS_PARAM_BLOCK_BEGIN(IrradianceEvaluateParamDef)
  67. BS_PARAM_BLOCK_ENTRY(float, gSkyBrightness)
  68. BS_PARAM_BLOCK_ENTRY(INT32, gNumTetrahedra)
  69. BS_PARAM_BLOCK_END
  70. extern IrradianceEvaluateParamDef gIrradianceEvaluateParamDef;
  71. /** Evaluates radiance from the light probe volume, or the sky if light probes are not available. */
  72. class IrradianceEvaluateMat : public RendererMaterial<IrradianceEvaluateMat>
  73. {
  74. RMAT_DEF("IrradianceEvaluate.bsl");
  75. public:
  76. IrradianceEvaluateMat();
  77. /**
  78. * Executes the material using the provided parameters.
  79. *
  80. * @param[in] view View that is currently being rendered.
  81. * @param[in] gbuffer Previously rendered GBuffer textures.
  82. * @param[in] lightProbeIndices Indices calculated by TetrahedraRenderMat.
  83. * @param[in] lightProbesInfo Information about light probes.
  84. * @param[in] skybox Skybox, if available. If sky is not available, but sky rendering is enabled,
  85. * the system will instead use a default irradiance texture.
  86. * @param[in] ambientOcclusion Texture containing per-pixel ambient occlusion.
  87. * @param[in] output Output texture to write the radiance to. The evaluated value will be added to
  88. * existing radiance in the texture, using blending.
  89. */
  90. void execute(const RendererView& view, const GBufferTextures& gbuffer, const SPtr<Texture>& lightProbeIndices,
  91. const LightProbesInfo& lightProbesInfo, const Skybox* skybox, const SPtr<Texture>& ambientOcclusion,
  92. const SPtr<RenderTexture>& output);
  93. /**
  94. * Returns the material variation matching the provided parameters.
  95. *
  96. * @param[in] msaa True if the shader will operate on a multisampled surface.
  97. * @param[in] singleSampleMSAA Only relevant of @p msaa is true. When enabled only the first sample will be
  98. * evaluated. Otherwise all samples will be evaluated.
  99. * @param[in] skyOnly When true, only the sky irradiance will be evaluated. Otherwise light probe
  100. * irradiance will be evaluated.
  101. * @return Requested variation of the material.
  102. */
  103. static IrradianceEvaluateMat* getVariation(bool msaa, bool singleSampleMSAA, bool skyOnly);
  104. private:
  105. GBufferParams mGBufferParams;
  106. SPtr<GpuParamBlockBuffer> mParamBuffer;
  107. GpuParamTexture mParamInputTex;
  108. GpuParamTexture mParamSkyIrradianceTex;
  109. GpuParamTexture mParamAmbientOcclusionTex;
  110. GpuParamBuffer mParamSHCoeffsBuffer;
  111. GpuParamBuffer mParamTetrahedraBuffer;
  112. GpuParamBuffer mParamTetFacesBuffer;
  113. bool mSkyOnly;
  114. static ShaderVariation VAR_FullMSAA_Probes;
  115. static ShaderVariation VAR_SingleMSAA_Probes;
  116. static ShaderVariation VAR_NoMSAA_Probes;
  117. static ShaderVariation VAR_FullMSAA_Sky;
  118. static ShaderVariation VAR_SingleMSAA_Sky;
  119. static ShaderVariation VAR_NoMSAA_Sky;
  120. };
  121. /** Contains information required by light probe shaders. Output by LightProbes. */
  122. struct LightProbesInfo
  123. {
  124. /** Contains a set of spherical harmonic coefficients for every light probe. */
  125. SPtr<GpuBuffer> shCoefficients;
  126. /**
  127. * Contains information about tetrahedra formed by light probes. First half of the buffer is populated by actual
  128. * tetrahedrons, while the second half is populated by information about outer faces (triangles). @p numTetrahedra
  129. * marks the spot where split happens.
  130. */
  131. SPtr<GpuBuffer> tetrahedra;
  132. /** Contains additional information about outer tetrahedron faces, required for extrapolating tetrahedron data. */
  133. SPtr<GpuBuffer> faces;
  134. /**
  135. * Mesh representing the entire light probe volume. Each vertex has an associated tetrahedron (or face) index which
  136. * can be used to map into the tetrahedra array to retrieve probe information.
  137. */
  138. SPtr<Mesh> tetrahedraVolume;
  139. /** Total number of valid tetrahedra in the @p tetrahedra buffer. */
  140. UINT32 numTetrahedra;
  141. };
  142. /** Handles any pre-processing for light (irradiance) probe lighting. */
  143. class LightProbes
  144. {
  145. /** Internal information about a single light probe volume. */
  146. struct VolumeInfo
  147. {
  148. /** Volume containing the information about the probes. */
  149. LightProbeVolume* volume;
  150. /** Remains true as long as there are dirty probes in the volume. */
  151. bool isDirty;
  152. };
  153. /**
  154. * Information about a single tetrahedron, including neighbor information. Neighbor 4th index will be set to -1
  155. * if the tetrahedron represents an outer face (which is not actually a tetrahedron, but a triangle, but is stored
  156. * in the same array for convenience).
  157. */
  158. struct TetrahedronData
  159. {
  160. Tetrahedron volume;
  161. Matrix4 transform;
  162. };
  163. /**
  164. * Information about a single tetrahedron face, with information about extrusion and how to project a point in
  165. * the extrusion volume, on to the face.
  166. */
  167. struct TetrahedronFaceData
  168. {
  169. UINT32 innerVertices[3];
  170. UINT32 outerVertices[3];
  171. Vector3 normals[3];
  172. Matrix4 transform;
  173. UINT32 tetrahedron;
  174. bool quadratic;
  175. };
  176. public:
  177. LightProbes();
  178. /** Notifies sthe manager that the provided light probe volume has been added. */
  179. void notifyAdded(LightProbeVolume* volume);
  180. /** Notifies the manager that the provided light probe volume has some dirty light probes. */
  181. void notifyDirty(LightProbeVolume* volume);
  182. /** Notifies the manager that all the probes in the provided volume have been removed. */
  183. void notifyRemoved(LightProbeVolume* volume);
  184. /** Updates light probe tetrahedron data after probes changed (added/removed/moved). */
  185. void updateProbes();
  186. /** Returns true if there are any registered light probes. */
  187. bool hasAnyProbes() const;
  188. /**
  189. * Returns a set of buffers that can be used for rendering the light probes. updateProbes() must be called
  190. * at least once before the buffer is populated. If the probes changed since the last call, call updateProbes()
  191. * to refresh the buffer.
  192. */
  193. LightProbesInfo getInfo() const;
  194. private:
  195. /**
  196. * Perform tetrahedrization of the provided point list, and outputs a list of tetrahedrons and outer faces of the
  197. * volume. Each entry contains connections to nearby tetrahedrons/faces, as well as a matrix that can be used for
  198. * calculating barycentric coordinates within the tetrahedron (or projected triangle barycentric coordinates for
  199. * faces).
  200. *
  201. * @param[in,out] positions A set of positions to generate the tetrahedra from. If
  202. * @p generateExtrapolationVolume is enabled then this array will be
  203. * appended with new vertices forming that volume.
  204. * @param[out] tetrahedra A list of generated tetrahedra and relevant data.
  205. * @param[out] faces A list of faces representing the surface of the tetrahedra volume.
  206. * @param[in] generateExtrapolationVolume If true, the tetrahedron volume will be surrounded with points
  207. * at "infinity" (technically just far away).
  208. */
  209. void generateTetrahedronData(Vector<Vector3>& positions, Vector<TetrahedronData>& tetrahedra,
  210. Vector<TetrahedronFaceData>& faces, bool generateExtrapolationVolume = false);
  211. /** Resizes the GPU buffer used for holding tetrahedron data, to the specified size (in number of tetraheda). */
  212. void resizeTetrahedronBuffer(UINT32 count);
  213. /** Resizes the GPU buffer used for holding tetrahedron face data, to the specified size (in number of faces). */
  214. void resizeTetrahedronFaceBuffer(UINT32 count);
  215. /**
  216. * Resized the GPU buffer that stores light probe SH coefficients, to the specified size (in the number of probes).
  217. */
  218. void resizeCoefficientBuffer(UINT32 count);
  219. Vector<VolumeInfo> mVolumes;
  220. bool mTetrahedronVolumeDirty;
  221. UINT32 mMaxCoefficients;
  222. UINT32 mMaxTetrahedra;
  223. UINT32 mMaxFaces;
  224. Vector<TetrahedronData> mTetrahedronInfos;
  225. SPtr<GpuBuffer> mProbeCoefficientsGPU;
  226. SPtr<GpuBuffer> mTetrahedronInfosGPU;
  227. SPtr<GpuBuffer> mTetrahedronFaceInfosGPU;
  228. SPtr<Mesh> mVolumeMesh;
  229. UINT32 mNumValidTetrahedra;
  230. // Temporary buffers
  231. Vector<Vector3> mTempTetrahedronPositions;
  232. Vector<UINT32> mTempTetrahedronBufferIndices;
  233. };
  234. /** @} */
  235. }}