# Energy Conservation in Lighting Equation

I am currently making a Ray-tracer as a personal project. My lighting equation looks like this

Pixel_color[i] = 255 * (Ma*Ig*Ca + Md*I*Cd * diffuse  + Ms*I*Cs * glossy)
// M = material color (ambient, diffuse and specular)
// I = intensity of light (Ig is the global ambient intensity)
// C = color of the light (ambient , diffuse and specular)


Here diffuse and glossy contains all the necessary dot products and the normalization factors ( PI for diffuse and n+8/8*PI for Blinn Phong). Also everything is in range 0-1. I've read from some books and it says to make sure that "Ks + Kd" <= 1 And now I am confused.

1) What exactly is Ks and Kd? Is it just my surface diffuse color and specular color divided by 255 to make it in the range 0-1? Or is it the reflectance ratio that I have to multiply with my color? If it's something else then what should I set them to? For example if I have a color rgb(66, 170, 244) which is somewhat light blue. What should the Ks and Kd be for the above color?

2) These books don't include the ambient component when talking about this conservation so should it be Ka+Kd+Ks <= 1? Again if that's the case what will Ka be?

3) If I consider Ks = Ms and Kd = Md. It doesn't fit out. for example if I want a surface with the above color rgb(66, 170, 244) to be shiny and the specular highlight should be white. Then my Ms would be (255-66, 255-170, 255-244) which won't be white. Another way I could do is subtract the maximum from every component Ms(255-244, 255-244, 255-244). But this means the specular color would be very low. What if I wanted a very shiny surface?

UPDATE:-

So according to the book Computer Graphics Principles and Practice, Chapter 6 "Fixed Function and Hierarchial Modeling in WPF"

Cd Innate color of “diffuse layer” (Cd,R,Cd,G,Cd,B)
Cs Innate color of “specular layer” (Cs,R,Cs,G,Cs,B)
ka Efficiency of diffuse layer at reflecting ambient light (ka,R, ka,G, ka,B)
kd Efficiency of diffuse layer at reflecting light (kd,R, kd,G, kd,B)
ks Efficiency of specular layer at reflecting light (ks,R, ks,G, ks,B)


After that it writes,

Note that for solid-color materials, the distinction between the two terms Cd and kd is unnecessary, as far as the math is concerned; you can think of them as a single term. That is, you can fix kd,R at 1. 0 and use Cd,R to achieve any effect, and conversely you could fix Cd,R and specify only kd,R. However, the distinction between the two terms is meaningful when the innate color Cd is being provided via texture mapping; in that case, there is a need for a kd,R factor affecting the reflection of the varying color Cd specified by the texture.

After that in Chapter 14.9 it removes Kd/Ks and Cd/Cs and replaces both with K_L and K_G

These k parameters are no longer potentially ambiguous RGB triples (each 0 . . . 1), but constants representing the net probability over all directions of that term contributing to scattering.

Which led me to think they are just a single constant like "0.5" However in the next example they are telling the same thing to ensure that K_L + K_G <= 1 across all channel which implies that k_L and k_G are infact RGB triples.

• CGPP is dated regarding PBR and statements like Kd+Ks<=1 isn't correct, assuming they stand for diffuse & specular albedo. It's rather that integral of BRDF over hemisphere <= 1 for energy conservation – JarkkoL Feb 12 '17 at 14:18
• @JarkkoL - does that mean when i normalize blinn phong, there is no need for Kd+Ks <= 1? – gallickgunner Feb 12 '17 at 15:18

Comment: if you make references to book, then it would be good if you could provide references.

1. First, it is quite unusual these days to see people representing colors using a computer byte that is integer values within the range [0:255]. Most people these days use floats, and you will understand why in a moment. When you look at a material in general you can see a shiny part and a diffuse part. Shininess and diffuse appearance are computed using two different types of equation. Let's call the functions that compute the diffuse part diffuse() and the function that compute the specular component specular(). So now you can write:

ObjectColor = Ks * specular() + Kd * diffuse();

Ks and Kd control how shiny or/and diffuse your object is.

About conservation of energy. In short an object can not reflect more light that it receives. So that means that technically if the specular() and diffuse() function do the right thing Ks + Kd ought to be 1. If that wasn't true you would violate the principle of conservation of energy. In practice, it is generally good to follow this rule though most of the basic shading models are based on simple diffuse and specular models (for example the Phong model) and are not themselves energy conserving, so trying to be purely energy conserving at this level, is like trying to say you can paint a miniature with a paint roller. Forget about it, just try to be more or less in the right range.

ks and kd generally stand for the specular and diffuse coefficients.

1. if you don't do path tracing (aka don't simulate global illumination) the object won't reflect light from other objects in the scene, just light from direct light sources. So in the old time, in order to compensate for that, they would add an ambient term. In these days in age, this is considered as 'heresy'. Though if you account for the ambient term still then Ka + Kd + Ks should be again equal to 1 (same principle).

2. Not sure to understand what you say here but all these components are additive. You compute the diffuse multiplied by Kd and then you multiply the specular multiplied by Ks and then you add the two resulting numbers together. And that's your object color at the intersection point.

For an introduction to these topics I recommend you read:

Introduction Ray-Tracing