Physical Light Exploited

I know many people are using the physical_light. Usually they use it with the intention, well, to obtain physical correct renderings. I'm sure most of them don't know that sometimes they put the fox in charge of the hen house this way. Why this?

First, physical_light does cause problems when used together with Maya standard shaders, like Maya blinn for example. Here's a rendering with raytracing set to on, the material is the default Maya lambert, the light is a physical_light with intensity 200000 attached to a Maya pointlight:

Looks good so far, but what happens when raytracing is turned off? Here's an example:

What's that illuminated rim around the lower right of our sphere? Looks like physical_light shades both sides of our object, regardless where the normal is pointing at. Hm, let's see if the problem persists if we use MentalRay shaders instead of the Maya lambert:

Apparently it renders correct. So, if you plan to use native Maya shaders instead of custom MentalRay shaders, physical_light might cause problems. What I came across for example, is that extremely bright final gathering blotches (blotches that are "not" caused by insufficient rays) were caused by this fact.

Second, physical_light lacks of almost every neat feature the Maya lights have: raytrace shadow attributes like light radius, amount of shadow rays, shadow ray depth limit, shadow color, light fog, light glow, intensity curve, barn doors (if you ever use it..), decay regions, and last but [i]not[/i] least the capability to emit diffuse or specular only. With this in mind, I went out to find a 'substitute' for the physical_light. To anticipate but hopefully not to lower the suspense (heh..) I can say that this has been successfully accomplished by exactly 75%.

Foremost we need to know what the key-features of physical_light are: It is a) the decay, following physical light's inverse-square falloff law. And more important b) it works perfectly together with the light's photon emission attributes, creating a physically plausible correlation between direct and indirect illumination.

To maintain this correlation, we need to find an exact conversion factor for the light's intensity. Well, if you ever tried to approximate a Maya light's intensity to a physical_light's, you probably came up with the factor 12.5, +-0.1 maybe. Hmm, why this? The physical_light's source code gives the answer: at line 109 it states

[code] switch(areatype) {
case miLIGHT_NONE: /* point, spot or directional*/
/*
* distance attenuation: 4 Pi r^2 is the area of a
* sphere around the point. Same normalization as for
* spherical light
*/
f = type==miLIGHT_DIRECTION ? 1 : 1 / (4 * M_PI * r2);
break;[/code]



..which means, the formula for distance attenuation (for point, spot and directional lights) is 1 divided by 4*pi, multiplied by the radius^2, or 1/(4*3.14159*radius^2). Now, if we use a Maya light, the radius^2 thingy is handled by simply switching the decay rate attribute to quadratic. The 4*pi needs to be handled manually though. So, if our physical light had an intensity of 200000.000, we needed to switch our Maya pendant to a quadratic decay rate, and we needed to divide the intensity by 4*pi - let's have a look. Continuing with the above example, I switched to regular Maya light and set it's intensity to 15915.494:

Ugh! Exact same result!

This also clarifies why most people tend to set their photon intensity to 10 times their direct light intensity when using Maya lights with quadratic decay. Well, now they know that they actually should either divide the direct light intensity by 4*pi (=~12.566), or multiply the photon intensity by 4*pi. This way, physical_light can safely be 'emulated' in case of point, spot or directional lights.

Conclusion

Maya light intensity = physical_light intensity / 4*pi (=~12.566)

But what about (flat) area lights? Well, here's a simple point light, with physical_light attached (intensity 10000.000) and MentalRay area light set to true, type rectangle - it's sampling is set to 1/1 and the number of anti-aliasing samples is min/max 1/1 to avoid irregular noise for our test:

Let's try to apply what we learned above. Physical_light detached, intensity divided by 4*pi, decay rate quadratic:

Hmm, that didn't work out. Let's have a look at the physical_light's source code again:

[code] case miLIGHT_RECTANGLE: /* rectangular area light */
mi_query(miQ_LIGHT_AREA_R_EDGE_U, state, light, &u;);
mi_query(miQ_LIGHT_AREA_R_EDGE_V, state, light, &v;);
mi_vector_prod(&normal;, &u;, &v;);
mi_vector_normalize(&normal;);
mi_vector_to_light(state, &dir;, &state-;>dir);
mi_vector_normalize(&dir;);
/*
* Compute area-to-point form factor (except cos at
* the receiver). is cos at sender. Returning
* 2 means "no color and stop sampling".
*/
cosine = mi_vector_dot(&normal;, &dir;);
if (cosine <= 0)
return((miBoolean)2);
if (paras->cos_exp != 0 && paras->cos_exp != 1)
cosine = pow(cosine, paras->cos_exp);
/*
* cos term and distance attenuation. No area term
* since "color" of the light is energy, not radiance.
*/
f = cosine / (M_PI * r2);
break;[/code]

As you can see, in the line next to the last, pi only is used. So let's try that - intensity divided by pi only (10000/pi = 3183.099):

Better, but there's still a big difference for some reason..? Well, it has to do with the cosine_exponent attribute of the physical_light. The cosine_exponent is narrowing the light's default cosine distribution by taking cosine to cos_exp's power - so if we use a physical_light again and set cosine_exponent to 0 it should be equal to what we just rendered with the Maya light

Same result! Sweet! But didn't we want to emulate a physical_light with Maya lights, not vice versa? So how can we simulate this cosine_exponent? I had to experiment, and found out that a Maya spot light's dropoff attribute has the very same effect - only drawback is that you need to max the spot light's cone angle (~179.994°) - this can get a bit annoying, because the displayed cone get's incredibly huge (tip: to overcome this scale annoyance we can trim down the Locator Scale attribute under Object Display of our lightShape node to something like 0.001 or lower). So I switched my maya light to type spot light with cone angle 179.994, penumbra 0 and dropoff 1 - intensity again is physical_light's intensity/1pi (and don't forget to switch decay rate to quadratic again, as it gets switched to 'No Decay' when switching light types):

Snap! It's the exact same result as with physical_light.

Conclusion

For rectangle and disc ('flat') area lights:
Maya light intensity = physical_light intensity / 1pi (=~3.142)
Maya spot light's dropoff (with cone angle maxed) = physical_light's cosine_exponent
For sphere, cylindrical and geometric area lights:
Maya light intensity = physical_light intensity / 4*pi (=~12.566)

note: cosine_exponent does apply to flat area lights only

Well, this perfectly emulates physical_light's intensity and cosine_exponent. But what about it's cone attribute? The cone attribute simply represents (out of the manual) 'the cosine of the opening angle of the inner solid cone'. With Maya lights this can easily be imitated by using a negative penumbra angle (a positive penumbra would make the cone angle actually wider).

So what's left is the threshold attribute of the physical_light. That's why my success goes as far as exactly 75% (4 attributes to be 'emulated', 1 failed, makes a loss of success of 25%, heh). The threshold attribute sometimes helps to effectively reduce the amount of shadow rays when using finalgathering. It's kinda useless though when used solely with direct lighting. However, this internal optimization cannot be achieved by a standard Maya light - maybe in future?

With the above correlations in mind, you hopefully better understand the interplay of direct and indirect (photon) intensity and you can get physically plausible solutions without abandoning Maya's native lights and material shaders.

I hope you enjoyed another experiment that maybe will let you get a bit more out of MentalRay than usual.

Contact me via mymail@floze.de, or visit my website at

http://individual.floze.de/

Enter content...

Fetching comments...

Post a comment