BakeLight.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. // Copyright (c) 2014-2017, THUNDERBEAST GAMES LLC All rights reserved
  2. // Portions Copyright (c) 2015 Dmitry Sovetov
  3. // Portions Copyright 2009-2017 Intel Corporation
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #pragma once
  24. #include <Atomic/Core/Mutex.h>
  25. #include <Atomic/Math/Plane.h>
  26. #include "BakeNode.h"
  27. namespace Atomic
  28. {
  29. class Light;
  30. class Zone;
  31. }
  32. using namespace Atomic;
  33. namespace AtomicGlow
  34. {
  35. class LightRay;
  36. class BakeMesh;
  37. class BakeLight;
  38. class LightVertexGenerator;
  39. /// Light cuttoff is used for configuring the light source influence direction (omni, directional, spotlight).
  40. /// LightCutoff class is a base for all cutoff models and represents an omni-directional light.
  41. class LightCutoff : public RefCounted
  42. {
  43. ATOMIC_REFCOUNTED(LightCutoff)
  44. public:
  45. /// Constructs a LightCutoff instance.
  46. LightCutoff( const BakeLight* light );
  47. virtual ~LightCutoff( void ) {}
  48. /// Calculates a light influence to a given point.
  49. virtual float Calculate( const Vector3& point ) const;
  50. /// Calculates a light cutoff for direction.
  51. virtual float GetCutoffForDirection( const Vector3& direction ) const;
  52. protected:
  53. /// Parent light instance.
  54. const BakeLight* light_;
  55. };
  56. /// LightSpotCutoff is used for spot lights.
  57. class LightSpotCutoff : public LightCutoff
  58. {
  59. ATOMIC_REFCOUNTED(LightSpotCutoff)
  60. public:
  61. // Constructs a LightSpotCutoff instance
  62. // param light Parent light source.
  63. // param direction Spot light direction.
  64. // param cutoff The cutoff value represents the maximum angle between the light direction and the light to pixel vector.
  65. // param exponent The cutoff exponent.
  66. LightSpotCutoff( const BakeLight* light, const Vector3& direction, float cutoff, float exponent );
  67. virtual ~LightSpotCutoff( void ) {}
  68. /// Calculates a light influence for a spot light.
  69. virtual float Calculate( const Vector3& point ) const;
  70. /// Calculates a light cutoff for direction.
  71. virtual float GetCutoffForDirection( const Vector3& direction ) const;
  72. private:
  73. /// Light direction.
  74. Vector3 direction_;
  75. /// Light cutoff.
  76. float cutoff_;
  77. /// Light spot exponent.
  78. float exponent_;
  79. };
  80. /// Light distance attenuation model.
  81. class LightAttenuation : public RefCounted
  82. {
  83. ATOMIC_REFCOUNTED(LightAttenuation)
  84. public:
  85. /// Constructs a LightAttenuation instance.
  86. LightAttenuation( const BakeLight* light );
  87. virtual ~LightAttenuation( void ) {}
  88. /// Calculates light attenuation by distance.
  89. /// An attenuation factor is a value in range [0;1], where 0 means
  90. /// that light is attenuated to zero, and 1 means no attenuation at all.
  91. virtual float Calculate( float distance ) const { return 0.0f; }
  92. protected:
  93. /// Parent light source.
  94. const BakeLight* light_;
  95. };
  96. /// Linear light attenuation model.
  97. class LinearLightAttenuation : public LightAttenuation
  98. {
  99. ATOMIC_REFCOUNTED(LinearLightAttenuation)
  100. public:
  101. /// Constructs a LinearLightAttenuation instance.
  102. LinearLightAttenuation( const BakeLight* light, float radius, float constant = 0.0f, float linear = 0.0f, float quadratic = 25.0f );
  103. virtual float Calculate( float distance ) const;
  104. private:
  105. // Light influence radius.
  106. float radius_;
  107. // Constant light attenuation factor.
  108. float constant_;
  109. // Linear light attenuation factor.
  110. float linear_;
  111. // Quadratic light attenuation factor.
  112. float quadratic_;
  113. };
  114. /// Light to point influence model.
  115. class LightInfluence : public RefCounted
  116. {
  117. ATOMIC_REFCOUNTED(LightInfluence)
  118. public:
  119. /// Constructs a LightInfluence instance.
  120. LightInfluence( const BakeLight* light );
  121. virtual ~LightInfluence( void ) {}
  122. /// Calculates omni light influence to a given point.
  123. virtual float Calculate(LightRay* lightRay, const Vector3 &light, float& distance ) const;
  124. /// Calculates a light influence by a Lambert's cosine law.
  125. static float GetLambert( const Vector3& direction, const Vector3& normal );
  126. protected:
  127. /// Parent light instance.
  128. const BakeLight* light_;
  129. };
  130. /// Directional light influence model.
  131. class DirectionalLightInfluence : public LightInfluence
  132. {
  133. ATOMIC_REFCOUNTED(DirectionalLightInfluence)
  134. public:
  135. /// Constructs a DirectionalLightInfluence instance.
  136. DirectionalLightInfluence( const BakeLight* light, const Vector3& direction );
  137. /// Calculates a directional light influence.
  138. virtual float Calculate( LightRay* lightRay, const Vector3& light, float& distance ) const;
  139. private:
  140. /// Light source direction.
  141. Vector3 direction_;
  142. };
  143. /// Ambient occlusion influence model.
  144. class AmbientOcclusionInfluence : public LightInfluence
  145. {
  146. ATOMIC_REFCOUNTED(AmbientOcclusionInfluence)
  147. public:
  148. /// Constructs a AmbientOcclusionInfluence instance.
  149. AmbientOcclusionInfluence( const BakeLight* light);
  150. /// Calculates a ambient occlusion light influence.
  151. virtual float Calculate( LightRay* lightRay, const Vector3& light, float& distance ) const;
  152. private:
  153. };
  154. /// Photon emitter is used to determine an amount of photons to be emitted by a given light.
  155. class PhotonEmitter : public RefCounted
  156. {
  157. ATOMIC_REFCOUNTED(PhotonEmitter)
  158. public:
  159. // Constructs a new PhotonEmitter instance.
  160. PhotonEmitter( const BakeLight* light );
  161. virtual ~PhotonEmitter( void ) {}
  162. // Calculates an amount of photons to be emitted.
  163. virtual int GetPhotonCount( void ) const;
  164. // Emits a new photon.
  165. virtual void Emit( SceneBaker* scene, Vector3& position, Vector3& direction ) const;
  166. protected:
  167. // Parent light source.
  168. const BakeLight* light_;
  169. };
  170. /// Directional photon emitter emits photons with a given direction.
  171. class DirectionalPhotonEmitter : public PhotonEmitter
  172. {
  173. ATOMIC_REFCOUNTED(DirectionalPhotonEmitter)
  174. public:
  175. // Constructs a new DirectionalPhotonEmitter instance.
  176. // param light Parent light source.
  177. // param direction Emission direction.
  178. DirectionalPhotonEmitter( const BakeLight* light, const Vector3& direction );
  179. /// Emits a new photon.
  180. virtual void Emit( SceneBaker* scene, Vector3& position, Vector3& direction ) const;
  181. private:
  182. /// Emission direction.
  183. Vector3 direction_;
  184. /// Emission plane.
  185. Plane plane_;
  186. };
  187. class BakeLight : public BakeNode
  188. {
  189. ATOMIC_OBJECT(BakeLight, BakeNode)
  190. public:
  191. BakeLight(Context* context, SceneBaker *sceneBaker);
  192. virtual ~BakeLight();
  193. /*
  194. virtual void SetLight(Atomic::Light* light) = 0;
  195. virtual void Light(LightRay* ray) = 0;
  196. */
  197. // Returns an light influence model.
  198. LightInfluence* GetInfluenceModel( void ) const;
  199. // Sets an light influence model.
  200. void SetInfluenceModel( LightInfluence* value );
  201. // Returns an attenuation model.
  202. LightAttenuation* GetAttenuationModel( void ) const;
  203. // Sets an attenuation model.
  204. void SetAttenuationModel( LightAttenuation* value );
  205. // Returns a light vertex generator.
  206. LightVertexGenerator* GetVertexGenerator( void ) const;
  207. // Sets an light vertex generator.
  208. void SetVertexGenerator( LightVertexGenerator* value );
  209. // Returns an cutoff model.
  210. LightCutoff* GetCutoffModel( void ) const;
  211. // Sets an cutoff model.
  212. void SetCutoffModel( LightCutoff* value );
  213. // Returns a photon emitter.
  214. PhotonEmitter* GetPhotonEmitter( void ) const;
  215. // Sets a photon emitter.
  216. // By default each light has a photon emitter, light sources with no photon emitter
  217. // set won't make any influence to a global illumination.
  218. void SetPhotonEmitter( PhotonEmitter* value );
  219. // Returns a light position.
  220. const Vector3& GetPosition( void ) const;
  221. // Sets a light position.
  222. void SetPosition( const Vector3& value );
  223. // Returns a light color.
  224. const Color& GetColor( void ) const;
  225. // Sets a light color.
  226. void SetColor( const Color& value );
  227. // Returns a light intensity.
  228. float GetIntensity( void ) const;
  229. // Sets a light intensity.
  230. void SetIntensity( float value );
  231. // Returns true if this light casts shadow otherwise false.
  232. bool GetCastsShadow( void ) const;
  233. // Sets a castShadow flag.
  234. void SetCastsShadow( bool value );
  235. // Direct Lighting
  236. void DirectLight(LightRay* lightRay);
  237. // Creates a Zone light instance.
  238. static BakeLight* CreateZoneLight( SceneBaker* baker, const Color& color = Color::WHITE );
  239. // Creates a point light instance.
  240. static BakeLight* CreatePointLight( SceneBaker* baker, const Vector3& position, float radius, const Color& color = Color::WHITE, float intensity = 1.0f, bool castsShadow = true );
  241. // Creates a spot light instance.
  242. static BakeLight* CreateSpotLight( SceneBaker* baker, const Vector3& position, const Vector3& direction, float cutoff, float radius, const Color& color = Color::WHITE, float intensity = 1.0f, bool castsShadow = true );
  243. // Creates a directional light instance.
  244. static BakeLight* CreateDirectionalLight( SceneBaker* baker, const Vector3& direction, const Color& color = Color::WHITE, float intensity = 1.0f, bool castsShadow = true );
  245. // Creates an area light instance.
  246. static BakeLight* CreateAreaLight( SceneBaker* baker, BakeMesh* mesh, const Vector3& position, const Color& color = Color::WHITE, float intensity = 1.0f, bool castsShadow = true );
  247. private:
  248. // Light position.
  249. Vector3 position_;
  250. // Light color.
  251. Color color_;
  252. // Light intensity.
  253. float intensity_;
  254. // Casts shadow flag.
  255. bool castsShadow_;
  256. // Light cutoff model.
  257. SharedPtr<LightCutoff> cutoffModel_;
  258. // Light attenuation model.
  259. SharedPtr<LightAttenuation> attenuationModel_;
  260. // Light influence model.
  261. SharedPtr<LightInfluence> influenceModel_;
  262. // Light source photon emitter.
  263. SharedPtr<PhotonEmitter> photonEmitter_;
  264. // Light vertex sampler.
  265. SharedPtr<LightVertexGenerator> vertexGenerator_;
  266. };
  267. // A light vertex is a single light point used with mesh light sources.
  268. struct LightVertex
  269. {
  270. // Point position.
  271. Vector3 position_;
  272. // Point normal.
  273. Vector3 normal_;
  274. static LightVertex Interpolate( const LightVertex& a, const LightVertex& b, float scalar )
  275. {
  276. LightVertex result;
  277. result.position_ = a.position_ * scalar + b.position_ * (1.0f - scalar);
  278. result.normal_ = a.normal_ * scalar + b.normal_ * (1.0f - scalar);
  279. result.normal_.Normalize();
  280. return result;
  281. }
  282. };
  283. // A helper class to tesselate faces.
  284. class LightTriangle
  285. {
  286. public:
  287. /// Constructs a Triangle instance
  288. LightTriangle( void ) {}
  289. /// Constructs a Triangle instance from three vertices.
  290. LightTriangle( const LightVertex& a, const LightVertex& b, const LightVertex& c );
  291. /// Returns a triangle centroid.
  292. const LightVertex& GetCentroid( void ) const;
  293. /// Tesselates a triangle. Splits this triangle into 4 smaller ones.
  294. /// param center Output center triangle.
  295. /// param triangles Three triangles on corners.
  296. void Tesselate( LightTriangle& center, LightTriangle triangles[3] ) const;
  297. private:
  298. // Triangle vertices
  299. LightVertex a_, b_, c_;
  300. // Triangle centroid.
  301. LightVertex centroid_;
  302. };
  303. typedef PODVector<LightVertex> LightVertexVector;
  304. /// A LightVertexGenerator used to generate a set of light points for mesh light sources.
  305. class LightVertexGenerator : public RefCounted
  306. {
  307. ATOMIC_REFCOUNTED(LightVertexGenerator)
  308. public:
  309. /// Constructs a LightVertexGenerator instance.
  310. LightVertexGenerator( BakeMesh* bakeMesh );
  311. virtual ~LightVertexGenerator( void ) {}
  312. /// Returns vector of light vertices.
  313. const LightVertexVector& GetVertices( void ) const;
  314. /// Generates a set of light vertices based on mesh vertices.
  315. virtual void Generate( void );
  316. /// Clears a previously generated data.
  317. void Clear( void );
  318. /// Returns a total number of light vertices.
  319. unsigned GetVertexCount( void ) const;
  320. protected:
  321. /// Adds a new light vertex.
  322. void Push( const LightVertex& vertex );
  323. protected:
  324. // Source mesh.
  325. WeakPtr<BakeMesh> mesh_;
  326. // Set of generated light vertices.
  327. LightVertexVector vertices_;
  328. };
  329. /// A FaceLightVertexGenerator generates a set of vertices based on mesh vertices & face centroids.
  330. /// Face based generator can also perform a mesh tesselation.
  331. class FaceLightVertexGenerator : public LightVertexGenerator
  332. {
  333. ATOMIC_REFCOUNTED(FaceLightVertexGenerator)
  334. public:
  335. /// Constructs a FaceLightVertexGenerator instance.
  336. /// param mesh Source light mesh.
  337. /// param excludeVertices The flag indicating that we should skip mesh vertices.
  338. /// param maxSubdivisions Maximum subdivision steps per mesh face (0 means no tesselation).
  339. FaceLightVertexGenerator( BakeMesh* bakeMesh, bool excludeVertices = true, int maxSubdivisions = 0 );
  340. /// Generates a set of light vertices.
  341. virtual void Generate( void );
  342. private:
  343. /// Generates a set of light vertices from triangle.
  344. virtual void GenerateFromTriangle( const LightTriangle& triangle, int subdivision );
  345. private:
  346. /// The flag indicating that we should skip mesh vertices.
  347. bool excludeVertices_;
  348. /// Max subdivision depth.
  349. int maxSubdivisions_;
  350. };
  351. }