Help optimizing my raytracing

Started by
9 comments, last by cignox1 14 years, 1 month ago
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
Advertisement
Have you tried hitting stop in your debugger? You're probably stuck in this infinite loop:

while ( (xoffs*xoffs + yoffs*yoffs) > (diff_refl * diff_refl) );

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.
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.

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,

@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.

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,

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.
@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
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).
[TheUnbeliever]

This topic is closed to new replies.

Advertisement