Materials and light transport

61 replies to this topic

#41Alienizer

Member

• Members
• 440 posts

Posted 10 April 2012 - 02:30 PM

"the same umber of" is the answer to your hidden part I undestand all that, it's all about proportion.

I understand about shooting photons proportinal to light power. But the color is what I'm not sure about.

Say, Light1 color(1,1,1) power 100, and Light2 color(1,1,1) power 50.

Light1 shoot 100 photons of color(1,1,1)
Light2 shoot 50 photons of color(1,1,1)
is that correct so far?

Now at trace time, when a ray hit the light, it's not correct to return color(1.1,1) for both lights since one is 50% dimmer then the other.

So do I have to scale the color of Light2 to (0.5,0.5,0.5) and shoot the same amout of photons as Light1, and at trace time, return color(0.5,0.5,0.5) for Light2 and color(1,1,1) for Light1?

#42}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 10 April 2012 - 09:27 PM

Lights cannot have color and power. It must be either color and area or power (3 components) and area:

power = color * area * pi

Light shoot photons proportional to power and return color equals to their color.

Light1 color(1,1,1) power 100 must have double of surface area than Light2 color(1,1,1) power 50. It is right to return color(1,1,1) for both lights and since the second light is smaller it'll look dimmer than first.
Sorry my broken english!

#43Alienizer

Member

• Members
• 440 posts

Posted 10 April 2012 - 10:32 PM

}:+()___ (Smile), on 10 April 2012 - 09:27 PM, said:

Lights cannot have color and power. It must be either color and area or power (3 components) and area

oh! I didn't know that!! Now that makes a big difference.

}:+()___ (Smile), on 10 April 2012 - 09:27 PM, said:

It is right to return color(1,1,1) for both lights and since the second light is smaller it'll look dimmer than first.

How can this be? if we raytrace back and hit a light, (1,1,1) is returned, so both lights will be as bright exept one is smaller then the other which makes no difference on brightness as far as pixels goes ???

#44geon

Senior Member

• Members
• 939 posts

Posted 11 April 2012 - 09:18 PM

Alienizer, on 10 April 2012 - 10:32 PM, said:

How can this be? if we raytrace back and hit a light, (1,1,1) is returned, so both lights will be as bright exept one is smaller then the other which makes no difference on brightness as far as pixels goes ???

This is correct. You are confusing the brightness of the lamp surface with how much power they light up the room with. A large window will light a room more than a tiny one, even though the brightness outside is the same. How much the room is lit is depending both on the brightness of the lightsource and its area. Multiply them and you get the power.

#45Alienizer

Member

• Members
• 440 posts

Posted 11 April 2012 - 10:12 PM

ok you pined it, this is where I think I'm getting confused. brightness and power. So if I have a light of power 100w and an area of 2, then the brightness is 50, and I shoot 100 photons for that light. So where do I use brightness at? At trace time? return brightness * lightColor if ray hit the light?

#46Alienizer

Member

• Members
• 440 posts

Posted 11 April 2012 - 10:45 PM

Here's what I do and it seems to look ok...

I have 3 lights set to color(1,1,1) , power 100w, 66w and 33w.

for each light...
shoot power photons (shoot 100 photons for first light, 66 for second and 33 for third light)

at trace time...
if ray hit light return color * power / lightArea

Is that the right way to do it?

#47geon

Senior Member

• Members
• 939 posts

Posted 12 April 2012 - 11:27 AM

Alienizer, on 11 April 2012 - 10:12 PM, said:

ok you pined it, this is where I think I'm getting confused. brightness and power. So if I have a light of power 100w and an area of 2, then the brightness is 50, and I shoot 100 photons for that light. So where do I use brightness at? At trace time? return brightness * lightColor if ray hit the light?

It really doesn't make sense to have lamp "color". What would a grey light mean? A tiny LED looks white in a dark room, but so does she sun, even though it is orders of magnitudes brighter.

No. Don't do it. It might seem intuitive to you, but it messes up your thinking. You simply should not think in therms of white = (1,1,1) until you are actually showing the image on screen. That is also AFTER you run it through an exposure function and gamma correction. Before that, all light is simply a value between zero and infinity.

Instead, store EITHER power OR brightness. Either way, you need to store them in RGB. If you count the power in Watts, you would ger (33, 33, 33) for a completely white 100 W lamp. You can calculate the other from either value if you know the area. (Point lights would need to store the power, since they have no area. But point lights are a hack anyway.)

#48Alienizer

Member

• Members
• 440 posts

Posted 13 April 2012 - 04:20 AM

ok I get it now, works perfect

Sorry guys for being so hard headed at understanding, but I'm not a genius like you all are, and I like to learn. You've been all a great help and I really, really appreciate the efforts you all put into making me understand.

#49Alienizer

Member

• Members
• 440 posts

Posted 19 April 2012 - 01:44 AM

ok, me again, hard headed at understanding how it works for raytracing this time, not photons.

Say I have a light of color/power vec3(60,60,50) over a 2x4 rectangle (area=8). Here is what I do...

for each screen pixel (set all balck first)...

if hit something other than the light{
dist = get distance to light
if not in shadow then...
return vec3(60,60,50) / (dist*dist);
} else {
return vec3(60,60,50) / lightArea(8)
}

doesn't look right. What am I missing?

#50geon

Senior Member

• Members
• 939 posts

Posted 19 April 2012 - 10:21 AM

Alienizer, on 19 April 2012 - 01:44 AM, said:

ok, me again, hard headed at understanding how it works for raytracing this time, not photons.

No problem! It's not easy to get it right.

Alienizer, on 19 April 2012 - 01:44 AM, said:

dist = get distance to light

(...)

return vec3(60,60,50) / (dist*dist);

Nope! Since you have an area light you should not care about the distace. Each ray (photon) has still the same brightness, no matter how far they travel. The distance squared is just a hack to make pointlights dimmer by distance. With han area light, you will automatically get the right brightness depending on the distance, since the light source will appear smaller at a larget distance, and thus get hit by fewer (global illumination) rays.

You could emulate a true area light by splitting it into a grid of pointlights. Then your distance formula is correct, but it isn't clear from your code sample how you have implemented it.

Alienizer, on 19 April 2012 - 01:44 AM, said:

if not in shadow then...

Hmm. This sounds like you work with a point light. All area lights have a penumbra, so you can't just check if it's in the shadow or not. Again, you could sample a number of pointlights spread over the surface of the area light, but you'd have to average a number of samples.

You need to decide if you are going to work with the area light as an actual area, or emulate it with a number of point lights.

#51Alienizer

Member

• Members
• 440 posts

Posted 19 April 2012 - 12:13 PM

Thanks Geon.

I'm using area lights by sampling it randomly, not with a grid. This gives me nice shadows when running it for a long time.

I thought that direct illumination must use 1/(dist^2) because if it doesn't, everything looks the same intensity!

#52}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 19 April 2012 - 10:44 PM

For naive backward ray tracing you don't need to know light integral power at all, only color is that matter. When your ray hit light directly return light surface color. If you ray hit something another than light then spawn hundreds of secondary rays according to surface BRDF. If secondary ray hit light than return light surface color multiplied by correct coefficient (normalized surface reflection color).

Something like light power can arise then you try to optimize secondary light shooting: shoot rays not randomly in the whole hemisphere but aim to lights. Usually aiming done not to light itself but to enclosing sphere, and it's where 1/dist^2 coefficient arise: you replace the whole hemisphere with small circle with area approximately proportional to 1/dist^2.
Sorry my broken english!

#53Alienizer

Member

• Members
• 440 posts

Posted 20 April 2012 - 12:42 AM

ok, I'm just trying a simple ray tracer to get the area lights to look correct. I want it to work with lights of different intensity and size, and the code below is the basic (very basic) loop I use, and what I'm not sure about is #1 and #2


for each screen pixel {
find hit
if hit = light {
return light color #1
} else {
color = black
for each light {
find hitLight
if hitLight {
color += light color #2
}
}
return color
}
}


#54}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 20 April 2012 - 08:28 AM

"For each light" part isn't for basic ray tracer (it's only simple with point lights). Try something like

for each screen pixel {
find hit
if hit = light {
return light color #1
} else {
color = black
for 1..LargeNumber {
(hit2, color2) = spawn secondary ray
if hit2 = light {
color += color2 * light color #2
} else {
spawn ternary ray, etc...
}
return color / LargeNumber
}
}


Sorry my broken english!

#55Alienizer

Member

• Members
• 440 posts

Posted 20 April 2012 - 12:57 PM

oh I see, but isn't that a path tracer?

#56}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 20 April 2012 - 02:52 PM

Yes, it is path tracer if you don't stop after second hit. But it's important to know that light sampling is optimization over simple path tracing and it's challenging to do it right (probability theory calculations). Main problem is that light sampling works well only with point lights (possibly anisotropic). One of solutions is first randomly choose points on light surfaces then sample that points in raytracer. For good image without banding you must choose different points for different screen pixels.

for each screen pixel {
find hit
if hit = light {
return light color #1
} else {
color = black
for 1..LargeNumber {
(point, power, normal) = generate random point on light surface
if point visible from hit {
color += BRDF * max(0, normal * dir) * power / dist^2
}
return color / LargeNumber
}
}


Sorry my broken english!

#57Alienizer

Member

• Members
• 440 posts

Posted 20 April 2012 - 03:46 PM

I see what you mean, that works better now, thanks! But, when the eye ray hits the light, it always return the same color/power for the light hit, which is ok, but in the loop 1..LargeNumber, the color returned is very very dark, I have to mult it by 10000 so I can see it. Is it because of dist^2 that attenuate the light so rapidly? Or maybe I do this wrong? When the eye ray hit the light, I return color/power vec3(60,60,60) as oppose the just color vec3(1,1,1) is that correct?

#58}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 20 April 2012 - 05:21 PM

This is the most tricky part to get coefficients right.

For each light you have color and area.
Also you have RGB -> grayscale conversion function norm().
Calculate total normalized power: total = sumi{ area[i] * norm(color[i]) }.
Then choose light with probability area[i] * norm(color[i]) / total.
And then use in formula power = total * color[i] / norm(color[i]).

Somewhere may be skipped pi or small integer coefficient, but it's hard for me to guess without calculating integrals. Also create basic path tracer first for reference images before moving to more complicated algorithms.
Sorry my broken english!

#59Alienizer

Member

• Members
• 440 posts

Posted 20 April 2012 - 11:13 PM

That's a perfect explanation THANK YOU. Now I understand it. My head got it this time, and it works

Thanks again for the details, I realy appreciate it.

#60Alienizer

Member

• Members
• 440 posts

Posted 21 April 2012 - 12:07 AM

One more thing, can I substitute norm() for Luminance() or does it have to be grayscale?

1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users