This is the documentation for Enlighten.
Custom direct lights
Enlighten includes the following standard light types:
Type | Description |
---|---|
Directional | An infinitely distant light source with no falloff. |
Spotlight | A point source with spherical falloff which emits light in a circular cone shape. |
Point | A point source with spherical falloff which emits light in all directions. |
Rectangle | A rectangular area light. |
Box Spotlight | A point source with spherical falloff which emits light in a square cone shape. |
Frustum | A point source with parallel falloff which emits light in a frustum shape. |
If your engine uses a non-physical falloff model, use these light types with a custom light falloff table.
If your light sources have a very different light beam shape, implement a custom light type.
Custom light falloff
Enlighten uses a physically realistic algorithm for bouncing indirect light around a scene (subject to the tweakable albedo and bounce scale values), but makes no particular assumptions about the direct lighting model. In practice, it is often more convenient to use a non-physical fall-off model for spot and point lights. They can be simpler to work with, reduce artefacts, and given the limitations of output displays it is often the only way to produce the desired effect. Because of this, Enlighten allows you to specify a custom distance fall-off for point and spot light using the Enlighten::InputLightFalloffTable
.
It is not necessary for there to be an exact correspondence between the model used for direct, on-screen lighting and the model used for producing input lighting for Enlighten. The closer the two models correspond, the more self-consistent the lighting model as a whole. On the other hand, if the Enlighten input lighting uses a completely non-physical model, it can produce counter-intuitive effects. For example, the amount of light in a scene could vary greatly as a light source of constant intensity is moved closer to or further away from geometry; as soon as the model is non-physical, energy is not necessarily conserved.
Enlighten provides two API functions for generating suitable fall-off tables: Enlighten::GenerateUnrealCompatibleLightFalloffTable
and Enlighten::GenerateInverseSquaredLightFalloffTable
. See also the Enlighten::InputLight
class.
Custom light types
To add a custom light type, first modify the eLightType
enumeration in EnlightenLights.h.
Insert the enumeration for your custom light type between //Begin Customer Light types
and //End Customer Light types
.
The example below shows a modification to add LIGHT_TYPE_CUSTOM_LIGHT_TYPE
.
//-------------------------------------------------------------------------------------------------- /// Different types of Enlighten input lights enum eLightType { LIGHT_TYPE_INVALID = -1, ///< Invalid light type LIGHT_TYPE_SPOT_LIGHT = 0, ///< Spot light LIGHT_TYPE_POINT_LIGHT = 1, ///< Point light LIGHT_TYPE_DIRECTIONAL_LIGHT = 2, ///< Directional light LIGHT_TYPE_RECTANGLE_LIGHT = 3, ///< Rectangular area light (only available on PC) LIGHT_TYPE_FRUSTUM_LIGHT = 4, ///< Frustum light LIGHT_TYPE_BOXSPOT_LIGHT = 5, ///< BoxSpot light #if defined(GEO_FEATURE_EXTENDED_INPUT_LIGHTING) // Begin Customer Light types LIGHT_TYPE_CUSTOM_LIGHT_TYPE, // End Customer Light types LIGHT_TYPE_NUM_TYPES //This must be the last entry in the enum #endif //defined(GEO_FEATURE_EXTENDED_INPUT_LIGHTING) };
Next, create a light class that derives from InputLightBase. The example below shows the required members.
class CustomLightType : public Enlighten::InputLightBase { public: CustomLightType() : InputLightBase(LIGHT_TYPE_CUSTOM_LIGHT_TYPE) { }; //Add destructor ~CustomLightType() {} //..add light member data here //..add a class called CachedData here. This is the main object which does all the work. // The input lighting framework will automatically generate this CachedData object from the light // pointers passed into the DoDirectInputLighting() function parameter. struct CachedData : public Enlighten::InputLightBase { //Add a constructor which takes the main light type as its only parameter CachedData(CustomLightType& srcLight, void* visibilityPointer) : InputLightBase(LIGHT_TYPE_CUSTOM_LIGHT_TYPE) { // cache any required data for the shade functions } //add members here which contain optimised data for best performance. //=================================================== // Add member functions with the following signatures //=================================================== //Function to shade four point which share a normal. The quad idx and cluster idx can be used for looking up visibility in the visibility buffer. GEO_FORCE_INLINE Geo::v128 ShadeQuad(const Geo::v128& positionsX, const Geo::v128& positionY, const Geo::v128& positionZ, const Geo::v128& normal, Geo::u32 clusterIdx, Geo::u32 quadIdx) const { } //Test if the light intersects the systems bounding box GEO_FORCE_INLINE bool IsIntersectingSystem(const Geo::v128& bbMin, const Geo::v128& bbMax) const { return true; } //Test if the lights intersects a group of clusters bounding box. Additional normal vectors enable culling against direction. GEO_FORCE_INLINE bool IsIntersectingClusterGroup(const Geo::v128& bbMin, const Geo::v128& bbMax, const Geo::v128& minNormalFlipped, const Geo::v128& maxNormalFlipped) const { return true; } //Test if the lights intersects a single cluster. Additional normal vectors enable culling against direction. GEO_FORCE_INLINE bool IsIntersectingCluster(const Geo::v128& bbMin, const Geo::v128& bbMax, const Geo::v128& minNormalFlipped, const Geo::v128& maxNormalFlipped) const { return true; } //hash the light data void Hash(Helpers::Hasher &hash, Geo::u32 clusterVisSize, Geo::u32 quadVisSize) { } }; };
For more examples see PointLight.h, Spotlight.h and DirectionalLight.h.
To allow Enlighten to use the new light type, immediately after the declaration of CustomLightType
, add a mapping from LIGHT_TYPE_CUSTOM_LIGHT_TYPE
to the CustomLightType
class.
template<> struct TypeIdToType<LIGHT_TYPE_CUSTOM_LIGHT_TYPE> { typedef CustomLightType Type; };