Setup a physical light

Generic physical lights

There are three different physical lights in REDsdk: the sky, the sun and the generic one. We'll focus here on the third types. For the two others, please refer to the related pages.

You need to start with the creation of a light instance using the generic REDsdk shape creation mechanism (Creating and destroying shapes).

Then you have to retrieve the interface dedicated to physical lights:

// "phy" is a pointer to a REDsdk light instance.
RED::IPhysicalLightShape* iphy = phy->As< RED::IPhysicalLightShape >();

A physical light needs a base mesh to setup correctly. The base mesh is the shape of light emission. It also needs some physical values as the luminous flux or power (in lumens or Watts), the light colour and the scene units conversion factor (this is because computations are physically correct and need real world units to produce right values):

// "emitter" is a pointer to a valid triangle-based mesh in the scene.
// "scene_units_to_meters" is the conversion factor between scene units and meters.
RC_TEST( iphy->SetEmitter( emitter, scene_units_to_meters, iresmgr->GetState() ) );

For example, if your scene is modelled in feet, the scene units conversion factor should be set to 0.3048 because 1 foot = 0.3048 meter.

Ok, we've just setup the shape of the physical light emission. We now must set the light emission parameters: intensity, colour, distribution... Bulb manufacturers often give detailed information about their products including lumens and color temperature. Those values can be entered straight in REDsdk using the right API calls:

float luminous_flux = 1500.f;
RED::Color color = RED::Color::FromTemperature( 2700.f );
RC_TEST( iphy->SetLuminousFlux( luminous_flux, iresmgr->GetState() ) );
RC_TEST( iphy->SetColor( color, iresmgr->GetState() ) );

In order for the light mesh to render with the right colour and intensity, we can ask the light for a corresponding ready-to-use material and apply it to the geometry.

// Builds the emitter material.
RED::Object* emitter_material = NULL;
RC_TEST( iphy->GetEmitterMaterial( emitter_material, iresmgr->GetState() ) );

// Applies the emitter material to the corresponding emitter mesh.
RC_TEST( emitter->As< RED::IShape >()->SetMaterial( emitter_material, iresmgr->GetState() ) );

The colour of a physical light can also be textured-based. To do that, simply call RED::IPhysicalLightShape::SetTexture instead of SetColor on the light object. This can be useful to simulate back lighting screens for example.

A texture-based physical light.

We now have a fully featured omnidirectional light of 1500 lumens and 1700 Kelvin color temperature. For convenience, REDsdk also provides alternate ways of setting the light intensity using power and efficiency or efficacy (See RED::IPhysicalLightShape for details).

We can go a little further by adding a custom profile of emission to a light using standardized industrial data: IES files. Most of the bulb manufacturers provide measured IES files of their products. REDsdk is compatible with the LM-63-02 IES norm. It's easy to set an IES profile to an existing light:

RED::Vector< RED::String > ies_attributes;
const char* ies_file_path = "./resources/50w_light_bulb.ies";
RC_TEST( iphy->SetIES( ies_attributes, ies_file_path, iresmgr->GetState() ) );

The attributes stored in the IES profile are returned in a readable format in a vector of strings.

Finally, as for any other sampled light in REDsdk, the quality of the light rendering can be tuned by setting the light number of samples:

RC_TEST( iphy->SetSamplesCount( 64, iresmgr->GetState() ) );

Spherical physical lights

RED physical lights provide a special case of lights: spherical physical lights. Spherical lights are useful as they are very often encountered in real-life and are easier and quicker to render than more complex light shapes. To create a spherical physical light, just call:

// "emitter" is a pointer to a valid triangle-based mesh in the scene.
// "light_dir" is the main light direction if the light is a spot (ignored otherwise)
// "light_angle" is the light spot half-angle in radians if the light is a spot (ignored otherwise)
RC_TEST( iphy->SetEmitterSpherical( emitter, scene_units_to_meters, light_dir, light_angle, iresmgr->GetState() ) );

The passed mesh is used to represent the light in the scene but internally, the light shape will be an analytical sphere. The radius of that sphere is determined by computing the radius of the given mesh bounding sphere. As a bonus, a spherical physical light can also be a spot light without having to model the light panes. This is achieved by passing a main direction and half-angle to the method.

Three physical spherical lights; left: omnidirectional, middle: spot, right: with IES profile