Radiosity Calculations => Lightmaps (???)

Started by
8 comments, last by shahinkey 12 years ago
Hey all... I''m trying to write a radiosity calculator for my lightmaps. My previous experience on lightmaps, is for point lights only, but i think i know the basics. Since now everything in my scenes were lightmaped my spherical or ellipsoid static lights. So, i decided to move forward and try radiosity!!! My question is simple. How can i convert pathces'' / vertices'' colors into lightmaps'' color values?? What i mean is... (the procedure) 1) i setup my patches (quads) 2) i do one pass for shooting and gathering, using the old way(!!!). No hemicubes, or such things. I just render all the patches from the center of i patch, with a fov of 89.0f degrees, and i check to see if every other patch (j) is in frustum. If it is, i calc a form factor(!!!) between i and j, and then i add the j->Color*FormFactor*j->Area/i->Area to i->Color. This is slow but for beginning, it have good results. 3) i repeat step 2 as many times i want (usually 2 or 3 passes are fine for a semi lit result) 4) i (would like to) save the results in a lightmap!!!! I know this is not the best way, but i don''t care right now. The problem is that saving to lightmaps appears to be very hard. Do you have any idea how i can do it. If you want more info tell it. Another question. Why every demo i saw on the net, doesn''t render the resulted "lightmaps" with some textures (multitexturing)??? May be they just render the patches, or they don''t??? Because if they just render the patches, and i see this great-but-fake result (!!!), i just done it so far!!! This was easy. The hard is to save a lightmap, and when you render with multitexturing, you can get the same result!!!!!! Another. How big must my lightmaps be? Must they be quads, or they can be rectangles too? Because with my point-light-lightmaps, i don''t have this limitation. The variable isn''t lightmap''s width or height, but lightmaps lumels per world unit. So lightmapWidth = 16, doesn''t mean that my lightmaps, will be 16 pixels wide, but 16*polygonWidth pixels wide!!! This way, i can use a very small lightmap, for very small polygon, and a very big for a very big. They just have same lumel density. And a problem with hemicubes!! I downloaded glutRad and i read the code. I realized that hemicubes'' images must have the same dims as window dims. Can i change that?? Is it necessary to have the same dimensions?? Because i''m working in fullscreen mode (800x600), i think that a hemicude with images with dims 800 x 600 can be very painfull!!! I mean from RAM point of view! HellRaiZer
HellRaiZer
Advertisement
For the most simple approach, a patch simply equals a lightmap texel. So, first create lightmaps for your scene, just as you did before. Try to keep them isotropic, ie. the texels should be more or less quadratic. This does not mean that the lightmap can't be rectangular, only the worldspace size of a mapped texel should be roughly a quad. That's for radiosity accuracy.

Then, you consider each lightmap texel to be a patch. Once your radiosity solution is computed, you have the radiance values for every patch (= for every lightmap texel). Note, that your patch radiosity will probably not be in the 0-255 range, so you'll have to remap it. Linear remapping gives pretty dull results, and will kill much of the 'radiosity touch'. You should use an exponential exposure funtion instead. This one, for example. Histogram based HDR remapping is even better, but a little more complex.

At this point, you simply assign the exposure corrected radiosity values to the lightmap texel colours. Done.

More advanced radiosity algorithms can combine several texels into a single patch (to shoot from, you get better speed from that) or subdivide texels into several patches while recieving (creating better visual quality). Adaptive subdivision is also possible, where you refine the resolution of your lightmaps according to the radiosity gradients on the object.


[edited by - Yann L on April 18, 2003 9:04:15 PM]
Thanks a lot Yann!!!!

I did what you said about lumels. Every lumel is a patch, so i hold a world position for every lumel (patch''s center), and i calculate patch''s area. Those two values seams to be enough. Also which byte in image data, a specific lumel represents, was usefull, because i didn''t want to mess up with recalculating pixel position, after radiosity calculations.

I realized that there is a problem with linear remapping, and i tried to solve it with restricting radiosity values to 255. But the results weren''t good. So now i''ll try exposure function!!!

Thanks again!!!

HellRaiZer
HellRaiZer
Hello again...

I think i''m in a good path. But, speed is veeeeeeeery low. Turtle speed... I''ll try to fix this.

I would like to know how fast must it be. I mean, with a good radiosity renderer, what is the time for an average (from polygon count point of view) scene, with full shadows, and RGB lightmaps??

So far, my calculator can generate 44 RGB lightmaps, for 44 polygons, with all of them casting and recieving shadows, in about 20 min!!!!!!!!! Total patches in scene are 4760!! Lightmaps have variable width and height, depending on polygon''s width and height, with constant lumel density. The smallest lightmap is 2x2 and the largest is 40x16, with DensityX = 2.0f and DensityY = 2.0f. I thought some ways for speeding things up, like in depth backface culling, lumel in polygon test (for sources not for recievers) etc. I don''t know the improvements on speed, but i think they won''t do much!!

Any suggestions accepted. Except hemicubes, unless you suggest a way of rendering hemicube''s faces, without having to resize the window!!!!

Thanks again.

HellRaiZer

PS. Exposure function did a good job. I have a little problem with adjacent polygons that aren''t co-planar, but it isn''t easy to see it... You have to look closely to understand the difference. I think, by finding same position lumels in the scene, and averanging there color can be an improvement. But... i don''t have time for this!!!

PS2. Is there any way to upload a screenshot, so you can tell me your opinion???

HellRaiZer
HellRaiZer
Well, speed is very hard to compare with radiosity systems, as different approaches can greatly differ. Even if you don''t like it, hemicubes are a good way to speed up formfactor calculations. Other methods include progressive refinement (which greatly minimizes the number of shooting patches required). Adaptive patch subdivision is also very important for speed: start with few large patches, and subdivide them only if needed.

About that viewport rescaling: well, yes, if you want a lower resolution hemicube view, you''ll need to rescale the viewport (in OpenGL, for example, that''s a simple glViewport() command). But you don''t have to resize the window, where did you get that idea ?

quote:
PS2. Is there any way to upload a screenshot, so you can tell me your opinion???

You''ll need to upload it on your own webspace (or some free webspace provider), and link it here in the forums. GDNet does not offer direct image hosting, though.
I think i''ll go with hemicubes!!!!

Do you have anything detailed on hemicubes, to suggest??? I searched at Google.com and i didn''t found something like a tutorial. Only papers, with a lot bla bla...

HellRaiZer
HellRaiZer
And...

If you can''t tell something about the speed of a radiosity renderer, what about patch count??? I mean for real-life sized levels, what''s the averange patch count for an average scene???

Thanks again.

HellRaiZer
HellRaiZer
quote:
Do you have anything detailed on hemicubes, to suggest??? I searched at Google.com and i didn't found something like a tutorial. Only papers, with a lot bla bla...

Heh Have a look at Huge Elias' radiosity tutorial. There are few more links in the forum FAQ.

quote:
If you can't tell something about the speed of a radiosity renderer, what about patch count??? I mean for real-life sized levels, what's the averange patch count for an average scene???

Define 'average real-life scene'. I depends on the size, and especially on the resolution of your lightmaps. But as I mentioned before, if you want a speedy radiosity solver, you should use adaptive subdivision. You start with very few patches, and subdivide them as needed, during the radiosity process. That, combined with hemicubes and progressive refinement, will already yield significant performance improvements.


[edited by - Yann L on April 20, 2003 10:42:00 AM]
I'm trying to understand how patch subdivision works.
I read an article titled "Radiosity Methods" that refers to Hierarchical Radiosity, so i'm trying to prove it in action. The author suggests, if i understood right, using a quad tree for holding the patches of a polygon. So i started by calculating, using planar mapping, 4 initial patches for every polygon. But i have a problem with further subdivisions. What i mean is, for the 4 initial patches its easy to calculate positions in 3D space. But, how can i calculate new positions, for a patch's children?? I can't think of a way, i can do it, without recalculating patches from the beginning, for a specified polygon!!! And if i do that there is no need for adaptive subdivision!!!

Also, he suggests, a way refinement can be done. With a recursive way using this function:

void Refine(Patch *p, Patch *q, double Fe, double Ae)
{
double Fpq, Fqp;

Fpq = FormFactor(p, q);
Fqp = FormFactor(q, p);

if (Fpq < Fe && Fqp < Fe)
Link(p, q);
else {
if (Fpq > Fqp) {
if (Subdivide(q, Ae)) {
Refine(p, q->ne, Fe, Ae);
Refine(p, q->nw, Fe, Ae);
Refine(p, q->se, Fe, Ae);
Refine(p, q->sw, Fe, Ae);
} else Link(p, q);
} else {
if (Subdivide(p, Ae)) {
Refine(q, p->ne, Fe, Ae);
Refine(q, p->ne, Fe, Ae);
Refine(q, p->ne, Fe, Ae);
Refine(q, p->ne, Fe, Ae);
} else Link(p, q);
}
}
}

The problem is, what will the initial values must be?? Do i have to call Refine in a way like :

vector PatchList;

/* PatchList have been filled when generating initial Patches.*/
int numPatches = PatchList.size();
for(int i=0;i{
for(int j=i+1; j {
Refine(PatchList, PatchList[j],FormFactorEpsilon, AreaEpsilon);
}
}

and must i push_back() every new patch generated by Subdivide(), or the initial patches are enough???

So, resuming.

Problem 1) Any suggestions on Subdivide() function. How must it be??? My RadPatch struct is:

struct RadPatch
{
float Rad[3]; // RGB Radiosity values
float DeltaRad[3]; //
float Area; // Area of the patch
float Reflect; // Reflectivity
RadPolygon* Parent; // Parent Polygon
GEVector3D Pos; // 3D Position
RadPatch* Child[4]; // Children generated after subdivision
vector Interactions; // Patches visible from current patch
GETexCoord UV; // Lightmap coords of current patch. This is the problem with subdivision. How can i calculate childred UVs???
};

Problem 2) Calling Refine()!!!!! Initial values.

Thanks in advance.

HellRaiZer


[edited by - HellRaiZer on April 20, 2003 2:17:47 PM]


[edited by - HellRaiZer on April 20, 2003 2:18:50 PM]
HellRaiZer
Dear All,
I really need to implement Radiosity. Who can help me for implementation. Is there any open source code radiosity? I read more paper about it. I know wat it is but I cannot implement it.
Thank you
Hoshang

This topic is closed to new replies.

Advertisement