H3-r3
wrote:
Both raytracing and raymarching work by casting rays. Usually these rays start from the point of view and proceed "backwards", bouncing on the objects of the scene.
At each intersection additional rays are traced in order to compute lighting, reflection, refraction, etc.
You usually cast a ray for each pixel of the screen and use the subsequent steps to compute the color of that pixel.
In raytracing you compute the exact analytical intersection between the ray and the objects in the scene. This is the most straightforward solution to the problem, but requires you to write intersection function for each kind of primitive you intend to use in the scene (ray/sphere intersection, ray/triangle intersection, etc.). These functions can become very complex to write and are not very flexible (you can't easily modify one of these functions to add additional details to an object, for example, or to blend two different primitives).
Today many raytracers simply use objects composed of many triangles. In this case you must subdivide the space in order to limit the number of intersections you have to compute for each ray. There are many different way to tackle this problem and there is still much research on this topic.
Raymarching is different because intersections between rays and objects are not computed directly. A raymarcher starts from the origin of the ray and proceeds on its trajectory in subsequent steps. At each step the length traveled by a ray is increased, and the point it reaches is checked in order to determine if an object has been reached (you simply check if this point is now "inside" a object). This way you don't have to write intersection functions, you only need functions that check if you are inside or outside a primitive.
The nice thing about these functions is that they are more simple and can be composed more easily: you can blend, twist, deform, primitives very easily.
You can also use objects that can't be described by a analytical function (for example a terrain or a 3D scan of a human body).
The variant of raymarching that I'm using is based on functions that also compute the distance between the point reached by the ray and the nearest object. This allows some nice optimizations and special effects, like soft shadows and ambient occlusion (more realistic lighting).
I'm going to further explore raymarching because I think it is more fun to use when writing a demo. It gives you more interesting and "abstract" 3D effects and requires less code and math.