BsLightProbes.h 9.4 KB

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