This is the documentation for Enlighten.

Debugging with ILightTransportOutput

The ILightTransportOutput object contains the following:

  • One pixel object per pixel in the radiosity texture, storing:
    • The X,Y location of this pixel in the texture
    • A collection of valid ray origins
    • A collection of invalid ray origins
    • A collection of rays that hit backfaces

Loading the data

Usually at runtime you simply create a new ILightTransportOutput object, and serialise the data into it.

ILightTransportOutput* ltOutput = LoadInterface<ILightTransportOutput>("<myfilename>");

If you are not using the LoadInterface helper functions, call Create and then Load yourself.

Valid/invalid origins

These per-pixel arrays store the locations from which rays were dispatched. Usually you are only interested in pixels with no valid origins, as these will not have correct lighting. Usually the reason for no valid origins is either a poor initial projection, or the GetRejectRayOriginIfAnyBackFaces build parameter is enabled. Another possible reason for invalid ray origins is that Enlighten will try to ensure that a radiosity pixel only contains the largest set of ray origins which can see each other as its valid set of ray origins, meaning that there is a clear visible line of sight between the ray origins. Ray origins that are not part of this set will be marked as invalid as well.

Backface line segments

These per-pixel arrays store the endpoints of a ray that started at a ray origin and hit a backface. If you are seeing light leaking, it may be that there is an open path to back faces. This should show up such authoring errors.

Sample code

The following code fills a copy of the radiosity texture with debugging data that shows the validity of each output pixel. Usually, you would also want to be able to draw any backface rays for a selected output pixel.

s32 outputWidth = radCore->m_MetaData.m_OutputWidth;
s32 outputHeight = radCore->m_MetaData.m_OutputHeight;

// create a texture
Texture* tex = TextureManager::Get()->CreateTexture(outputWidth, outputHeight);

// (optionally) fill texure with some noise, so it is not all black
srand(23562123);
for ( s32 i=0; i<outputWidth * outputHeight; i++ )
{
	float r=.15f*Min(1.0f,Max(0.0f,((float)rand()/RAND_MAX)));
	float g=.15f*Min(1.0f,Max(0.0f,((float)rand()/RAND_MAX)));
	float b=.15f*Min(1.0f,Max(0.0f,((float)rand()/RAND_MAX)));

	tex->PixelColour(i, VConstruct(r,g,b,0.f));
}

for ( s32 i=0; i<ltOutput->GetNumPixels(); i++ )
{
	const Enlighten::LightTransportPixel* pix = ltOutput->GetLightTransportPixel(i);

	if (!pix->m_ValidRayOrigins.GetSize())
	{
		tex->SetPixelColour(i, VConstruct(1.f, 0.f, 0.f, 0.f));		// make pixel red
	}
}

// render the scene with the new texture, using the radiosity UVs. Invalid pixels will show up in red.