Jump to content
• What is your GameDev Story?

• Advertisement

Radiosity in Practice

This topic is 4676 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a few questions about implementing certain parts of radiosity. I hope somebody can give me some insight: 1) All papers around the internet seem to use a single value for the light. How about color lights? How do the formulas change with these? 2) If I do get an imlpementation of light color, how do I make sure my radiosity renderer produces color bleeding? 3) Is there a nice way of calculating the reflectivity of a patch with the color at the point? I would have guessed that a dark point tends to absord more light, thats why it's dark... In that case, the color map should be able to be used as a "reflexivity map"? A reflexivity of [RR, RG, RB] would mean that this surface reflects RR of red component, RG of green and RB of blue. Therefore, the final "color" at this point would be [RR * L_R, RR * L_G, RB * L_B], where [L_R, L_R, L_B] is the total light received at this point. Tell me if this is wrong, thx.

Share this post

Share on other sites
Advertisement
Quote:
 Original post by David Hart1) All papers around the internet seem to use a single value for the light. How about color lights? How do the formulas change with these?

I believe the articles use a single color value to simplify the explanation of the radiosity process. However for color lights you just perform the same steps on each channel (RGB) in parallel.

Quote:
 Original post by David Hart3) Is there a nice way of calculating the reflectivity of a patch with the color at the point? I would have guessed that a dark point tends to absord more light, thats why it's dark... In that case, the color map should be able to be used as a "reflexivity map"? A reflexivity of [RR, RG, RB] would mean that this surface reflects RR of red component, RG of green and RB of blue. Therefore, the final "color" at this point would be [RR * L_R, RR * L_G, RB * L_B], where [L_R, L_R, L_B] is the total light received at this point. Tell me if this is wrong, thx.

As it turns out, the color map (texture) in this context is often refereed to as the Albedo, which is the measure of reflectiveness of a surface. So you are 100% correct.

Quote:
 Original post by David Hart2) If I do get an imlpementation of light color, how do I make sure my radiosity renderer produces color bleeding?

As long as you use the equation you presented in your third question to reflect the light, color bleeding should be a natural result of the process. However this means you'll need to have the textures at the time you perform radiosity.

Share this post

Share on other sites
David: Youre worrying for color bleeding, while it seems you dont have basic simple rooms lighted with radiosity. Dont worry for color bleeding yet, its just a byproduct of whole radiosity implementation. You dont turn it on separately. You just have to distribute most of the energy inside the scene so it is visible to human eye. Theoretically, you could need just few passes, if that colored object had high reflectivity and was very near some other white wall. But generally, you need to distribute most of the energy inside the scene so that it becomes visible (technically, when all patches had shot their energy just once, the color bleeding is there - its just not visible until you set you Exposure value high enough to see the bleeding effect (though, the rest of the scene shall become totally saturated, but its possible) ).

Id like to recommend you few ideas, so that you actually get to finishing the radiosity implementation - many people start it but later they drop it because its just so much work and most of the papers are not a very god read either.

1. Start with boxes - itll make your initial testing and experimenting much easier than some general scenes. Make a box room and place a light in the middle of the box. That way you can manually check the results (calculate the form factor manually) and spot any bugs right away.

2. Do not engage in texturing right away. Theres several issues with filtering and correct calculation of texture coordinates that would make you scratch your head needlessly while youre struggling with basic FF calculation.
Instead, consider dividing your walls (simple quads) into many square patches - like a regular grid. Make those patches polygonal (2 triangles) and assign it a color after you calculate the radiosity. This way youll be able to check your results immediatelly after you go through few passes.
To explain a bit more, if you have a wall of the box that has a real-world size of, say, 10.0f (regular coordinates of your vertices) and you decide that your Patch will have a size of 1.0f (just make sure all patches in your whole scene have a same area), you divide the Wall into 10x10 quads (i.e. patches) and let the program distribute the light. Right after first pass, youll be able to see the results immediatelly.
So, leave the texturing (with all its problems at triangle edges) as a final issue when youll be sure your radiosity processor works correctly.

3. Start with only a one, single pass. You might not see anything meaningfull (i.e. itll be just black). After your calculations you must convert the Received energy values of each patch into RGB values to be displayed on your monitor. Now you could assign your lights a value in range (0-255) so its better debugged when you are just starting, but remember, that the light source can have any range (0-1000000) or energy. In the end, it just has to be remapped to a range (0-255) to be displayed on your monitor. Exposure function is easiest here, since its just 2 lines of code. Youll need to experiment with the exposure parameters a little to get some good results.

4. Progressive Refinement.At the start of each pass, just browse all patches in the scene and choose the one with highest unshot energy (Patch .UnShot.R + Patch .UnShot.G + Patch .UnShot ). Make that one Shooter and shoot his energy to all other patches in the scene. With multiple lights, first few passes will mean, that youll shoot the energy from the lights, and when all lights were shots, Indirect Illumination shall finally take place - the energy shall be shot from the scene patches that already received the energy from lights - thats how you can get that color bleeding (if the objects are near enough).

5. FF Calculation. At the very start, forget the visibility - just let it be 1.0f. Besides, its the visibility that eats the most of the time to compute full radiosity distribution. You wont have shadows at the very start, but hey, its a good start !

6. If you havent yet, read the Radiosity threads by me (VladR) and HellRaiZer at these forums. Everything you might need regarding implementing a full radiosity solution is there. It just awaits for you to be implemented.

7. You can get some pretty "Disney was here" scenes with multiple lights:
Clicky !

Share this post

Share on other sites
Thank you both for your precise and informative answers!

To Zipster:

Quote:
 As it turns out, the color map (texture) in this context is often refereed to as the Albedo, which is the measure of reflectiveness of a surface. So you are 100% correct.

Now that I read my explanation again, I'm not sure if I did get something wrong in the end. Lets imagine I get my reflexivity value from a color map [RR, RG, RB], and that the incoming light is [IR, IG, IB]. Following the standard formulee, the "reflected" light is:

[RR * IR, RG * IG, RB * IB] * FF

And the "absorbed" light is:

[(1-RR) * IR, (1-RG) * IG, (1-RB) * IB] * FF

But the problem is that the absorbed light, the final illumination of the patch would have a color "inverted" in comparison with the original color/reflexivity map.

To VladR:

Thanks for your tips VladR.

Quote:
 If you havent yet, read the Radiosity threads by me (VladR) and HellRaiZer at these forums. Everything you might need regarding implementing a full radiosity solution is there. It just awaits for you to be implemented.

Yep, I've already used a good helping of search tool and read most of your posts. Nice "Disney" screenshot :)

Share this post

Share on other sites
Quote:
 Original post by David HartBut the problem is that the absorbed light, the final illumination of the patch ...

I might be misunderstanding you here, but just to clarify: the absorbed light is effectively discarded, while the reflected light represents the visible colour of the patch.

Share this post

Share on other sites
Quote:
 Original post by David HartNow that I read my explanation again, I'm not sure if I did get something wrong in the end. Lets imagine I get my reflexivity value from a color map [RR, RG, RB], and that the incoming light is [IR, IG, IB].

Why do you have reflexivity value as a special map in the first place ? Isnt it enough to specify "rho" per object (e.g. wood/metal/concrete...) ?

Also, after you shoot the unsent radiance from the Shooter to all receivers, you have to clear the unsent radiance on the shooter so that it doesnt become a shooter in next pass again (where youll traverse all patches to find out the patch with highest unsent radiance (that shall become the shooter in that pass) ).

Share this post

Share on other sites
Quote:
 Original post by David HartNow that I read my explanation again, I'm not sure if I did get something wrong in the end. Lets imagine I get my reflexivity value from a color map [RR, RG, RB], and that the incoming light is [IR, IG, IB]. Following the standard formulee, the "reflected" light is:[RR * IR, RG * IG, RB * IB] * FFAnd the "absorbed" light is:[(1-RR) * IR, (1-RG) * IG, (1-RB) * IB] * FFBut the problem is that the absorbed light, the final illumination of the patch would have a color "inverted" in comparison with the original color/reflexivity map.

As the AP mentioned, the absorbed light is just discarded. It's the reflected light that becomes the final illumination. After all, you can only see the light that's reflected off a surface. For instance, a surface appears black because it absorbs a large amount of light, and you only see a little. Likewise, a white surface reflects a large amount of light and only absorbs a little. The absorbed light contributes to non-visual attributes such as temperature or conductivity, and other things you aren't interested in.

Share this post

Share on other sites
Thanks for the clarification! I understand everything much better now.

Quote:
 Why do you have reflexivity value as a special map in the first place ? Isnt it enough to specify "rho" per object (e.g. wood/metal/concrete...) ?

If I understood Zipster correctly, this helps to get color bleeding working correctly. Secondly, it allows you to specifiy a color map, an emissive map, and nothing else, as both the emissive and reflexivity values can be found by a simple texture lookup.

Share this post

Share on other sites
Quote:
 Original post by David HartIf I understood Zipster correctly, this helps to get color bleeding working correctly. Secondly, it allows you to specifiy a color map, an emissive map, and nothing else, as both the emissive and reflexivity values can be found by a simple texture lookup.

1. Color Bleeding is just a "free" (it just takes a lot of time) byproduct of whole radiosity lighting technique. You do not have to do anything special to "enable" it, other than let the most of the energy distribute all over the patches. Which is done by as many passes as is necessary for a given scene. Of couse, you dont necessarilly have to notice the color bleeding in each scene, it all depends on given scene. As in real life, color bleeding is almost impossible to see in real, unless you have a specific set like a blank white paper on your desk touching some brightly red object and the nearby lamp light is shining directly on that given red object, thus the first, direct reflections go straight to that white paper and so it becomes visible. Now try, to move the light source and/or red object further away and youll spot that at certain distance, this color bleeding disappears (its still there physically, just our eyes arent good enough at spotting such small amounts of energy - they have certain threshold below which you wont see it anymore - although it can be measured by machines).

2. How does your emissive map work ? Do you have a special texture for each object that specifies the reflectivity at given texel ? Why is this even needed ? For start, until you have some first correct nice results, just use e.g. rho=0.4f for all patches. This is usually enough.

3. Are you using Progressive Refinement Shooting to speed up your results ?

4. I dont know how long are you trying to get the grasp of this whole radiosity lighting technique, but dont expect all pieces to come together at once. It might take few days/weeks until everything makes sense.

Share this post

Share on other sites
Hi guys! With your help I was able to write a simple radiosity renderer today. Thx VladR for convincing me to start simple, I found more practical problems along the way than I thought. The renderer "seems" to work fine, execept from the fact that it's damn slow. Optimizations will come later.

Screenshot

But for now I have a problem. Basically, my form factors end up to be very small (about 0.0006 for a HIGH form factor), which means I have to put a crazy light value to even get a semi-lit scene. But that's not the most annoying problem. It also means that after one reflection, the light value is so small that no patch is visibly affected by second order reflections (ie, I get no ambient-like effect).

Light intensity has to be pushed high for the top to be lit (lower-rez patches).

Here is my C# code for calculating Form Factors. Can you check if anything is wrong?

private static float GetFormFactor(Patch transmitter, Patch receiver){	DX.Vector3 ray = receiver.Position - transmitter.Position;	float fDistanceSquared = ray.LengthSquared();	ray.Normalize();	float fCosTransmitter = Math.Max(DX.Vector3.DotProduct(transmitter.Normal, ray), 0);	float fCosReceiver = Math.Max(DX.Vector3.DotProduct(receiver.Normal, -ray), 0);	float fDifferentialArea = transmitter.Area / receiver.Area;	return fDifferentialArea * fCosTransmitter * fCosReceiver / (float)(fDistanceSquared * Math.PI);}`

cos values are always in the range [0,1], and the differential area ends up to be 1 as all patches are the same size. So my form factor is actually dividing 1 by a huge value (distance squared).

1) I thought color bleeding was the color bleeding off non-emissive patches, due to reflection. In that case, you would need to multiply the color (or reflection, same thing) to the reflected light to get that effect.

2) My emissive map works so that a surface can emit different colors over it's surface. I saw a paper that used that to give a nice effect to colored windows.

3) I am using progressive sorted-shooting. Refinement is where u refine patches if needed, right? I haven't got up to that level yet.

Share this post

Share on other sites

• Advertisement
• Advertisement
• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

(You must login to your GameDev.net account.)

• Popular Now

• 11
• 9
• 9
• 34
• 16
• Advertisement
• Forum Statistics

• Total Topics
634123
• Total Posts
3015656
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!