Forum: Poser - OFFICIAL


Subject: A Dummies Guide to Indirect Lighting in Poser 8

ziggie opened this issue on Aug 05, 2009 ยท 761 posts


bagginsbill posted Thu, 10 September 2009 at 1:57 PM

Back to basics. This is one of those explanations that involves simple addition and multiplication, but I'm going to lose a lot of people, even though balancing a checkbook is harder than this. So be it. You asked, I will answer.

Color arithmetic is just 3 copies of ordinary arithmetic, done independently for each of the R, G, and B components of a color.

We also need to clarify the numerical value of these components. While it is commonly accepted that each component is an integer from 0 to 255, this is not how the math proceeds inside the render. Instead, these 0 to 255 values are mapped into fractional values from 0 to 1.

So if you specify the luminance of a color component in an RGB value as 200, the fractional or unit-range representation is 200/255 = approximately .7843.

As a final step to produce an image, unit-range color components are converted back to 0 to 255 by multiplying the final pixel values with 255 and then rounding to the nearest integer.

Note also that color components are not limited to the range 0 to 1. Color components can be less than 0 (what I call hypocolors) and greater than 1 (what I call hypercolors, also known as High Dynamic Range, or HDR.)

Then we also have the added complication that most images are encoded as sRGB values, not linear values. This means, for example, that in a JPEG, 200 is not exactly twice as bright as 100. Nor is 100 twice the brightness of 50. Instead, one must convert these to linear unit-range values. This means, for example, that the true luminance of 200 is not 200/255, but 200/255 to the power 2.2, or about .58597.

Having said all that, I'll now just assume we're talking about linear unit-range color components. The arithmetic is straightforward.

I will use capital letters like A or B to represent colors. Each is actually 3 numbers, one for each value of R, G, or B. To refer to the individual red component of A, I'll say A.red. The green is A.green. The blue component of B is B.blue. With me? (Don't run - it's easy.)

I'll also use square brackets to denote a color as an individual tuple or vector. That is to say:

A is the same as [A.red, A.green, A.blue]

Adding two colors A and B to get a new color, C, is simple.

C = A + B

which proceeds like this

[C.red, C.green, C.blue] = [A.red + B.red, A.blue + B.blue, A.green + B.green]

Or, to put it another way:

C.red = A.red + B.red
C.green = A.green + B.green
C.blue = A.blue + B.blue

It should be obvious clear, then that the operator, +, is distributed over the components. Using the same principle, subtracting colors we get:

C = A - B

[C.red, C.green, C.blue] = [A.red - B.red, A.blue - B.blue, A.green - B.green]

or

C.red = A.red - B.red
etc.

Multiplication is the same, just change the operator from + to *.

C = A * B

[C.red, C.green, C.blue] = [A.red * B.red, A.blue * B.blue, A.green * B.green]

Now how do we do arithmetic where we mixing individual numbers with colors? Consider some numerical value, v, which is not a color, but just a single number. The rule is simply this: convert the individual number into an equivalent color by duplicating v for each of R, G, and B.

Consider the color A = [.2, .5, .7]. What happens if we use v = .5, and we multiply A * v?

A * v = [.2, .5, .7] * .5

Promote .5 to the equivalent color, [.5, .5, .5]
A * v = [.2, .5, .7] * [.5, .5, .5]

And now use the color multiply rule.

A * v = [.2 * .5, .5, * .5, .7 * .5] = [.1, .25, .35]

Nothing to it.

Now we can finally consider your question. How does Diffuse_Color and Diffuse_Value and lighting all come together?

Assume the light color is L. For diffuse lighting, the angle between the surface normal and the direction to the source of the light determines a fraction that is used to decrease the light density arriving at any given location. This is a simple consequence of the geometry of light, or a garden hose, for that matter. Spray a hose vertically straight down at the ground, and a lot of water arrives in a small area. Spray horizontally away from you, and the water spray spreads out, which means any given spot is receiving less water than when shooting it straight down.

So let's just reduce the angular decreasing effective illumination to a simple number. Let's call it k.

The diffuse lighting equation is simple:

k * L * Diffuse_Color * Diffuse_Value

In this equation we are just multiplying two colors and two numbers. The numbers get promoted to an equivalent RGB color and then the whole thing is a simple 4-term multiplication.

For each component then, independently you can see that the outcome is

k * l * dc * dv

Set any of those to 0, and the whole thing is 0.

Set any of those to 1, and the whole thing is unaffected by that individual value.

The color WHITE is [1, 1, 1], so multiplying with WHITE makes no change.

The color BLACK is [0, 0, 0], so multiplying with BLACK always results in BLACK.

So the effective illumination where the Diffuse_Color is WHITE, and the Diffuse_Value is 1, and the angle of incidence is 90 degrees causes k to also be 1, you get:

k * L * dc * dv = 1 * L * 1 * 1 = L

In other words, if you set things up that way, then all the light from the light source bounces off the surface. That is impossible.

Decreasing any of the components (angle, DC, or DV) will result in some less-than-all fraction bouncing off instead.

Consider dv = .8, but still WHITE and 90 degrees.

k * L * dc * .8 = .8 * L

80% of the light bounces off.

But what if the Diffuse_Color is itself only 60% red, 50% green, and 40% blue?

k * L * [.6, .5, .4] * .8 = k * L * [.48, .40, .32]

So in that case at 90 degrees, 48% of the red reflects, 40% of the green reflects, and 32% of the blue reflects.

Any factor you apply to DC or DV alters the outcome. You can switch the factor between the two and it doesn't change anything. This is because multiplication is associative, i.e. it is always true that

(P * Q) * R = P * (Q * R)

Assume some initial state of the shader. Suppose you perform two test renders. In the first you decrease Diffuse_Color by half. In the second you decrease Diffuse_Value by half. Will they render any differently? The answer is no. What about instead of half, you use 80%? No difference.

As long as each component of DC * DV results in a number near 1, you will have trouble with IDL. If the product is less than .8 in each component, you will have no trouble with IDL.


Renderosity forum reply notifications are wonky. If I read a follow-up in a thread, but I don't myself reply, then notifications no longer happen AT ALL on that thread. So if I seem to be ignoring a question, that's why. (Updated September 23, 2019)