Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Gammastrahler

Radiosity for Beginners: Concerning form factors

This topic is 5294 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

Hi, i´m just reading a while about Radiosity Lighting and i have decided to implement it in my indoor rendering engine for static lighting, since my current lighting method handles shadows very badly. Although im still reading and need to get more knowledge, i have a question concerning form factors: Which approach is esier to implement? Im very confused by the Hemicube algorithm (i found a link here to a very good tutorial, but i have read it several times, the more foten i read about the hemicube stuff, the more i get confused about it ) So i think about determining the form factors by raytracing. what are the performance and accurracy issues compared to the hemicube algorithm. can someone tell me which method produces better quality? and what about the matrix solution? how is it actually performed? thanks for any help! greets Gammastrahler

Share this post


Link to post
Share on other sites
Advertisement
quote:
Original post by Gammastrahler
Which approach is esier to implement?

Raytraced FFs.

quote:

So i think about determining the form factors by raytracing. what are the performance and accurracy issues compared to the hemicube algorithm. can someone tell me which method produces better quality?

Raytracing achieves better quality (more precise), but is slower (but not always, depends on how you implement it). Hemicubes are an image space method, and suffer from the usual quality tradeoffs. Raytracing is object space, but you''ll need to shoot/gather lots of rays to get good soft shadows.

quote:

and what about the matrix solution? how is it actually performed?

It''s a theoretical model, used to derive the more advanced radiosity algorithms, but is unusable in pratice. You could solve it with a Gauss Seidel relaxation or something similar, but the memory requirements for using matrix radiosity directly are totally insane.

Share this post


Link to post
Share on other sites
I have coded a very simple app in which i "tried" to implement radiosity. I render a hollow cube.

I´think i post my code here (i know that it is not correct), but maybe you could give me the right formulas.

The form factor calculation is very cheap and slow... it is currently only for testing purposes. I also don´t take into account the patch´s differential area since each of my patch has the same size.

Another problem in my form factor calculation is: i get negative form factors! I dont´know why... therefore, i use fabs to flip the sign.

The rad_calc function should then calculate the radiosity for each patch, but i have problems solving the solution... how is p calculated? and how is E updated... i just don´t get agrip on it...

i would be very happy if someone could guide me !

thanks
Gammastrahler


void calc_form_factors()
{
for (int i = 0; i < patches.size(); i++)
{
float ff = 0.0f;

for (int j = 0; j < patches.size(); j++)
{
if (i != j)
{
vec3 ci = patches[i].center();
vec3 cj = patches[j].center();

vec3 r = ci - cj;

float l = r.length();

r.normalize();

float cosA = r.dot(patches[i].p._normal);
float cosB = r.dot(patches[j].p._normal);

ff += fabs((cosA * cosB) / 3.1415926 * l*l);
}
}

patches[i].formFactor = ff * 0.00015f;
}
}

void rad_calc()
{
for (int k = 0; k < 3; k++)
{
for (int i = 0; i < patches.size(); i++)
{
float incident = 0.0f;

for (int j = 0; j < patches.size(); j++)
{
if (i != j)
{
incident += patches[j].radiosity * patches[j].formFactor;
}
}

patches[i].radiosity = patches[i].emission + incident;
}
}
}


[edited by - Gammastrahler on April 13, 2004 8:26:36 AM]

Share this post


Link to post
Share on other sites
Here is my code to get the formfactors between two patches (S = sender, R = receiver). It''s slow, but it works great.



// Make sure sender and receiver aren''t the same

if( S == R ) continue;

// get vector V, pointing from the center of S to the center of R

V = R->position - S->position;

// get length(V) and normalize it

r = V.length();
V.normalize();

// Compute shadow factor

// TODO: multisampling

Hij = Raytracer->TestShadowRay(S->position, R->position);
if( Hij == 0 ) continue;

// compute geometric formfactor between S and R (range: 0..1)

phi_p = S->normal * V;
phi_r = -(R->normal * V);

if( phi_p <= 0 || phi_r <= 0 ) continue;

double ff = (phi_p*phi_r) / (pi*r*r);

// Take differential area and shadow factor into account

ff *= Hij * S->area;

// Make sure we are using sane values

assert( ff <= 1.0 && ff >= 0.0 );

// Consider monochromatic energy absorption

ff *= GeneralPatchReflectance;

// shoot energy to R->energy and R->radiance, modulated by the receiving patch colour

RGB<double> d = S->energy * ff * R->colour;
R->energy += d;
R->radiance += d;

// Reset sender energy

S->energy = 0;

Share this post


Link to post
Share on other sites
Thanks for your answer

I have oriented my code on your´s and as well took some pseudo code from "Computer Graphics & Principles" to use it in my current application:

My radiosity processor now looks like this:


void do_radiosity()
{
for (int i = 0; i < patches.size(); i++)
{
for (int j = 0; j < patches.size(); j++)
{
if (i == j) continue;

vec3 ci = patches[i].center();
vec3 cj = patches[j].center();

vec3 r = ci - cj;

float l = r.length();
r.normalize();

float cosA = -r.dot(patches[i].p._normal);
float cosB = r.dot(patches[j].p._normal);

if (cosA <= 0 || cosB <= 0) continue;

patches[j].formFactor = (cosA * cosB) /(3.14159265358979323846 * l*l);
}

for (int j = 0; j < patches.size(); j++)
{
float Radiosity = patches[i].deltaB * patches[j].formFactor * 0.3;

patches[j].deltaB += Radiosity;
patches[j].B += Radiosity;
}

patches[i].deltaB = 0.0;
}
}


But the output looks somewhat wired!



Can someone tell me the error?

Thanks
Gammastrahler

[edited by - Gammastrahler on April 13, 2004 2:51:33 PM]

Share this post


Link to post
Share on other sites
Weird. Are you sure that your patch centers and normals are correctly computed ? It looks like something is wrong with them, especially on the back wall.

Share this post


Link to post
Share on other sites
I have checked all patch normals and patch centers... they seem to be okay.

Can you find any potentional errors in my code?

Or is the problem with the scaling of my final radiosity values to RGB values?

i do this

glColor3f(patches.radiosity * 0.000025, patches[i].radiosity * 0.000025, patches[i].radiosity * 0.000025);

to get acceptable results.

thanks
Gammastrahler


[edited by - Gammastrahler on April 14, 2004 6:53:07 AM]

Share this post


Link to post
Share on other sites
Is it point sampled?? It looks like a lightmap of 16x16 pixels (count the rasters). Try switching linear point sampling on.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!