Using Vuforia Fusion Illumination

This article provides an overview of the Vuforia Fusion illumination and color correction features. The Vuforia::Illumination class contains information about the illumination in a camera frame. Objects of this class can obtain a scene’s illumination values and use the returned values to render augmentation consistent with the real-world scene. An Illumination object can be returned from the State. This allows illumination values to be provided at any time.

Illumination Values

ARKit and ARCore produce different values. These values adjust for the current lighting in the application’s environment.

ARKit generates two physical measurements: (1) a color temperature measured in Kelvin and (2) an intensity measured in Lumens. In applications such as Unity and SceneKit, these values are easily applied to light used in the rendering.  

ARCore supplies values that can be applied directly to a shader’s RGB values, as well as an intensity value. 

For each platform, the values are returned in the following elements of the Illumination class:

Platform Elements
iOS ARKit ambientColorTemperature and ambientIntensity
Android ARCore intensityCorrection and colorCorrection

If the device does not support ARKit, then ambientIntensity returns AMBIENT_INTENSITY_UNAVAILABLE and ambientColorTemperature returns AMBIENT_ COLOR_TEMPERATURE_UNAVAILABLE

The intensityCorrection and colorCorrection elements always return valid values that can be applied to a shader. If ARCore is not used, however, the returned values default to 1 and the shader values remain unchanged.

For more information on obtaining these values, refer to the Illumination API reference pages.

Working with the Illumination API

The example code below explains how to retrieve, convert, and load the rendered illumination values into the light shader.

Example: iOS ARKit

  1. Retrieve the illumination values from the state and convert them to renderable values:
auto illumination = state.getIllumination();
if (illumination != nullptr)
{
    float ambientIntensity = illumination->getAmbientIntensity();
    if (ambientIntensity != Vuforia::Illumination::AMBIENT_INTENSITY_UNAVAILABLE)
    {
    // We set the model lighting considering the min and max lumens values in the sample to 200 - 1500
    // In our sample 200 lumens is considered low brightness, 200 lumens in real life is similar to a dimmed light bulb;
    // 1500 lumens is considered bright, in real life as bright as a standard light bulb.
    // These values are used specifically for the samples but higher values could be obtained from brighter sources
    mLightIntensity = fmin(1.5f, .4f + (ambientIntensity - 200.0f) / 1300.0f);
    }
}
  1. Load the rendered values into the light shader:
float lightColor[] = {mLightIntensity, mLightIntensity, mLightIntensity, 1.0f};
glUniform4f(self.objMtlLightColorHandle, self.lightColor[0], self.lightColor[1], self.lightColor[2], self.lightColor[3]);
  1. Set up the shader to use the light value.
    Note: Refer to the Ground Plane and Model Target shader contained in the Core Features sample.

Example: Android ARCore

  1. Retrieve the illumination values from the state and convert them to renderable values:
// Use color correction if illumination information is available
  Illumination illumination = state.getIllumination();
  if (illumination != null)
  {
     // Assumes we are rendering in gamma space, as per Google ARCore documentation
     // https://developers.google.com/ar/reference/c/group/light#group__light_1ga70e0426f83e94a3f8f4c103a060b3414
     // These correction values are being used in the shaders used for augmentations rendering: LightingShaders and DiffuseLightMaterials
     mIntensityCorrection = illumination.getIntensityCorrection() / 0.466f;
     mColorCorrection = illumination.getColorCorrection();
 }
  1. Load the rendered values into the light shader:
GLES20.glUniform4f(colorCorrectionHandle,
       mColorCorrection.getData()[0],
       mColorCorrection.getData()[1],
       mColorCorrection.getData()[2],
       mColorCorrection.getData()[3]);
GLES20.glUniform1f(intensityCorrectionHandle, mIntensityCorrection);
  1. Set up the shader to use the light value.
    Note: Refer to the Ground Plane and Model Target shader contained in the Core Features sample.