This is the documentation for Enlighten.

Custom direct lights


Enlighten includes the following standard light types:

TypeDescription
DirectionalAn infinitely distant light source with no falloff.
SpotlightA point source with spherical falloff which emits light in a circular cone shape. 
PointA point source with spherical falloff which emits light in all directions.
RectangleA rectangular area light.
Box SpotlightA point source with spherical falloff which emits light in a square cone shape.
FrustumA 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.

Light types enumeration in EnlightenLights.h
//--------------------------------------------------------------------------------------------------
/// 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.

Custom light class template
	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.

Make custom light type usable by Enlighten
template<>
struct TypeIdToType<LIGHT_TYPE_CUSTOM_LIGHT_TYPE>
{
	typedef CustomLightType Type;
};