| |
| Posted by ketmar in reply to karabuta | PermalinkReply |
|
ketmar
Posted in reply to karabuta
| > This is the kind of maths I hoped I could try to understand. The spirit is not there :)
it's very easy, actually.
the basic idea is this: our "primitive" functions returns distance from a given point to the primitive. i.e.
auto point(1, 2, 3);
float dist = BoxPrimitive(point);
now `dist` is a distance from `point` to our box. it's by definition a shortest possible distance, of course.
now, to trace a ray, we are doing basically this:
try all primitives and find the minimal distance to ray origin.
then we know that we can safely move ray forward by that distance, 'cause it won't hit anything by the way. so move it, and repeat the process.
stop when we made some number of steps or minimal distance is less then some threshold.
whoa, we succesfully found our hitpoint! (and with some trick we also know wich primitive we hit)
basically, that's all. now just fire rays for all screen pixels, and color the pixels according to primitive color, adding some lighting to make image sexy.
the math is our ordinary vector algebra and light calculation, nothing arcane.
to calculate lights, we can use the same "find minimal distance" function to get light intencity for the given point. this is a win, 'cause we don't have to really trace a ray here.
of course, this is the simpliest case: light without shadow casting. to cast shadows, we have to trace a ray for real.
using "distance field" will allow us to do some more tricks too: easy soft shadows, ambient occlusion and others. they are, of course, possible with traditional raytracing too, but more expensive.
of course, the more objects our scene has, the slower it renders, as we don't try to do any space partitioning.
something like that. the code is really simple, just try to work out some simple primitive formula, and you'll get it.
|