LightsprintSDK 2021.08.08
Detect material properties

Global illumination is based on physically correct calculation of light transport. For such calculation it's necessary to know physical properties of surfaces. See RRMaterial for list of supported material properties of a surface.

Fortunately you don't have to study advanced laws of physics for good results, you don't even need any additional information provided by artists who create materials or compose shaders. Everything can be detected automatically.

In very simple cases, materials contain only diffuse texture without specular and transparency, so whole detection is reduced to calculating average color of diffuse texture and storing it into RRMaterial::diffuseReflectance.

In more general cases where renderer uses fixed set of shaders, you can extend this approach and get all values by analyzing textures and other inputs used by shaders. This can take you a few hours. Viability of this approach highly depends on your shaders and can't be decided here. If you are not sure, describe us your shaders and we will help you.

In fully general case, you don't need any information about shaders. It works even if you let modders create new shaders, their properties will be autodetected. Everything you need is ability to render simple scene into small texture (16x16 pixels is typically enough) and calculate average color of rendered image. Follow these steps for each material

  1. Create an empty scene and place 1x1m rectangle covered by material in front of orthogonal camera in 1m distance, so that rectangle covers whole viewport, but nothing more. If material needs uv coordinates for textures, use whole texture space from 0,0 to 1,1 in rectangle.
  2. Clear to black and render rectangle. Store acquired average color as RRMaterial::diffuseEmittance.
  3. Clear to white and render rectangle. Store acquired average color minus emittance as RRMaterial::specularTransmittance.
  4. Add white point light without distance attenuation to the same position as camera. Clear to black and render rectangle. Store (acquired average color minus emittance)*1.0805 as RRMaterial::diffuseReflectance.
  5. If your engine's lights have separated diffuse and specular color, repeat previous step for RRMaterial::specularReflectance. Use white diffuse and black specular light in previous step, black diffuse and white specular light in this step.
  • If you use materials with faked reflection maps (planar or cubic), make sure that reflection intensity drops to 0 in dark scene, or manually disable it before detection. If you apply faked reflection even in completely dark unlit scene, detection described above must think it's emissive material. Alternatively, if you don't have any emissive materials, you can simply set emissivity to 0.

This automatic approach can be further extended to differentiate between diffuse and specular reflectance or even to detect complete BRDF.

Of course you are allowed to use any other approach, e.g. let graphics artists enter all values by hand.