Sign in to follow this  
svnstrk

Help optimizing my raytracing

Recommended Posts

hi, im currently trying to build my own raytracer, however i notice that i takes too long to render 1900*1200 image with only 21 triangles and 2 light source. everything was built using triangle. you can see the code here http://pastebin.org/101701 im curious is there any other spot i can enhance my code to boost the performance. currently i only handle diffuse, specular, soft shadow with monte carlo sampling, reflection, and diffuse reflection. i sample it with 100 point and i limit the ray depth to two. i try to render the scene and it took 12 hours and not yet finished. im using intel core duo 2.0 GHz, 2Gb Memory. any advice would be great. thanks in advance

Share this post


Link to post
Share on other sites
There might be some other bugs as well, but it's hard to tell without seeing more code. For instance it doesn't seem like you're testing for nearest intersecting triangle, just all of them (unless you're sorting, or checking distance in the triangle intersect function you're not showing).
As far as optimization goes, try to reduce the number of intersection tests as much as possible, and try to make the test as fast as possible since you're doing an insane number of intersection tests. Also, don't use your intersect function to find shadows. All you need to know is if there is line of sight, so return at the first intersection instead of finding the closest.
And I hope those getters/setters (which are overkill for simple data types) are inline.

That would be a start at least.

Share this post


Link to post
Share on other sites
You don't even have basic optimizations, of course it will run slowly.
Try this optimization:
1. Find the bounding box of your scene.
2. Divide the bounding box into voxels.
3. Instead of checking intersections with all the triangles, only check intersection with triangles that are in voxels which the ray pass through.

This will probably reduce the run time to a few minutes.
You can try using threads to get more speedup.

Share this post


Link to post
Share on other sites

Quote:Original post by svnstrk hi, im currently trying to build my own raytracer, however i notice that i takes too long to render 1900*1200 image with only 21 triangles and 2 light source. everything was built using triangle. you can see the code here http://pastebin.org/101701 im curious is there any other spot i can enhance my code to boost the performance. currently i only handle diffuse, specular, soft shadow with monte carlo sampling, reflection, and diffuse reflection. i sample it with 100 point and i limit the ray depth to two. i try to render the scene and it took 12 hours and not yet finished. im using intel core duo 2.0 GHz, 2Gb Memory. any advice would be great. thanks in advance

 

First of all great you are working on a ray tracer. It's the current frontier in graphics programming. Anyways. There are many ways to improve the speed. 1) Raster the z or t-buffer of the camera so that you only have to calculate the outgoing rays and shadow rays using ray tracing. 2) You have 21 triangles so you can either build a BVH or KD-tree. A grid is not going to speed up things as you are spending most time in traversing voxels. 3) Pre-calc all you can. Intersection and shading parameters. Try to separate those parameters that are re-used in the intersection, shading and shadow calculations. 4) 100 samples on such a big resolution is going to take time no matter what. Is there no way of using another sampling scheme? Can it be less samples for details further into the screen, can it be based on another distribution? 5) SIMD and other low-level optimizations will not help here as you need to think big picture before you can use those. It could help but also it complicates the code and makes it hard to maintain and improve. Basically overview and flexibility is lost. 6) If you have a multi-core computer you can thread your application in which case you can distribute the computation and lessen the time. 7) Spread the work on different computers. Parts of the image could be rendered elsewhere. Good luck with your implementation and please tell us what you did! Cheers, 

Edited by jbadams
Restored post contents from history.

Share this post


Link to post
Share on other sites
@fbmachine
those does not create an infinite loop. statistically just produce 2 loop max, 1 loop mostly. i found its weird too but somehow its working properly. i found it from the tutorial im following. its some kind of random generator but faster.
the intersection works perfectly and yes it finds the closest.

@shmok123
im considering it but not my first priority right now, since im trying to build a small scene. i've read it somewhere that using bounding box alike optimization to reduce the calculation may become an overhead instead of optimizing a small scene, such as mine.

@spinningcube
im kinda new in this kind of thing, can you give more information or maybe a link where i can find how to implement those things? especially the precalc thing which is most interest for me.

also can you help me finding a good diffuse, specular, reflection, diffuse reflection value for a convincing image, ie. the value of painted wall or shiny floor, etc. im having trouble finding a good value to make a convincing image.

thanks in advance. really helpfull.

Share this post


Link to post
Share on other sites

Quote:Original post by svnstrk @spinningcube im kinda new in this kind of thing, can you give more information or maybe a link where i can find how to implement those things? especially the precalc thing which is most interest for me. also can you help me finding a good diffuse, specular, reflection, diffuse reflection value for a convincing image, ie. the value of painted wall or shiny floor, etc. im having trouble finding a good value to make a convincing image. thanks in advance. really helpfull.

 

Ok for the pre-calc stuff think like this. What is constant per frame? What is constant per ray origin, per ray direction. What is constant per triangle in testing versus a generic ray, versus a ray with constant origin or direction. Cannot help you with values for a convincing image. That is purely artistic and trial and error. I suggest rendering in low resolution to test many values. For more questions and professional answers go to www.ompf.org :-) They have a whole section devoted to implementations and you can search a vast database of answers. Cheers, 

Edited by jbadams
Restored post contents from history.

Share this post


Link to post
Share on other sites
That amount of time is really strange. I suppose that with your setup you should wait for a few minutes... what happens if you reduce your samples count to 10? Does the output look well?

A stupid question: are you running it in a release build, aren't you?

There is something I don't quite understand in your code: if sample is equal to 100, then you are sampling 100 times for the shadow test and 100 times for the reflections (I hope you don't also call radiance 100 times for antialiasing). As far as I can tell, this is way too much, unless you lights are very large and your reflectors very rought. Might be this one of the reason for your long times?

EDIT: as a test, try rendering your scene with 128 rays for antialiasing, but only one ray for shadows and reflections. In addition, try to use jiittered sampling when you can, this will improve the quality with the same computation time.

Share this post


Link to post
Share on other sites
@spinningcube
thx, will do

@cignox
im not quite understand the antialiasing part. can you give me a hint? well yes there is not much difference between 10, 20, or 100 except the soft shadow at 10 or 20 sample looks 'ugly'. and yes im doing it on release build :D
what is the definition of large light? is there some kind of measurement?

im curious why 3d apps renderer is so damn fast, rendering stuff within 2 minutes with such amount of triangle, and mine is like hours to build. any advice?


thanks in advance

Share this post


Link to post
Share on other sites
Quote:
Original post by svnstrk
also can you help me finding a good diffuse, specular, reflection, diffuse reflection value for a convincing image, ie. the value of painted wall or shiny floor, etc. im having trouble finding a good value to make a convincing image.


The problem is that, for images to be really convincing, these aren't generally constant - they vary with the angle of incidence (the angle the light is hitting the surface) and the angle of reflection (the angle the surface is being viewed from) which yields the bidirectional reflectance function (BRDF). It's a long name, but it's a fairly straightforward concept. It's also expanded to take into account other effects, so for example you can have the BSSRDF - which also takes into account subsurface scattering.

By default, you're probably implementing two basic BRDFs - pure specular (angle of incidence = angle of reflection) and Lambertian. Two models that you might want to look up are Oren-Nayar (which improves on the Lambertian model for diffuse reflection by statistically modelling rough surfaces as being made of of many small smooth surfaces - look at the images in the Wikipedia article linked) and Phong (which is a variation on specular for 'glossy' surfaces).

Share this post


Link to post
Share on other sites
Quote:
Original post by svnstrk
im not quite understand the antialiasing part. can you give me a hint? well yes there is not much difference between 10, 20, or 100 except the soft shadow at 10 or 20 sample looks 'ugly'. and yes im doing it on release build :D
what is the definition of large light? is there some kind of measurement?


Look at the two Sponza renders: IIRC I did use 32 samples per pixel for antialiasing, and something between 15-25 samples for the two area lights (sky and sun). Another poin light provides an ambient term (one more shadow ray). 10 minutes each, for a 640x480 resolution. If I had a 1900 x 1200 this would have required more than an hour, close to 5 hours if I used only 1 core on a 2.6Ghz CPU. If I also had reflective/transmissive objects, the rendering times would have been even higher. Doing antialiasing means shooting more primary rays per pixel, as you do with lights, and 'averaging' the result. This reduces aliasing in the image. From your code is not clear if you do this or not, but if you do and use 100 spp, then you have way too many rays.

Quote:

im curious why 3d apps renderer is so damn fast, rendering stuff within 2 minutes with such amount of triangle, and mine is like hours to build. any advice


The numberr of triangles becomes less of a problem once you have an acceleration structure (BIH/BVH/Kd-tree), but 21 triangles is not so far from the number of triangles you would test in a medium sized scene anyway, so it could be considered a good test. And 12 hours are simply too much. Post more code, perhaps the problem is elsewere (i.e. your intersection code).

EDIT: try by setting sample=1. This should be really fast to render. What timing do you get?

EDIT: to answer your last question, raytracers often use advanced techniques to speed up the computations. They heavily optimize the core routines up to the assembly level, making use of vector instructions (i.e. SSE) where available. In addition, the optimize cache behaviour, and sometimes trace more rays at the same time when CPU instructions make them able to process them in parallel.
Another trick is adaptive AA (you trace AA rays only where required).

I'm currently fighting against my BIH builder because no matter what I do, I can't speed it up even while it is clearly quite slow :-(

[Edited by - cignox1 on March 8, 2010 9:26:03 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this