John Carmack on Ray Tracing

Started by
138 comments, last by AndyTX 16 years ago
Quote:Original post by phantomus
I agree that all but the most trivial features of current 'real-time ray tracers' are either very slow or need hacks. However, there is a difference: In rasterization, many tricks are needed not because of performance, but because it's the only way to achieve the goal in the first place.

That's not exactly true... as I mentioned you can certainly rasterize one ray (1x1 "framebuffer) if you want to, and stuff like REYES-like rasterization blurs this line even a bit more. These are all "rasterization"-based techniques though and will produce the exact same results as ray tracing. Thus let me reiterate that the only important axis of comparison is speed for a given task. It just so happens that if you rays are incoherent, the scatter approach (rasterization) is slow compared to the sampling approach (ray tracing).

Quote:Original post by phantomus
ray packet traversal (breaks in recursive situations, so definitely a hack)

Ah but here's the rub... not only does it "break" (or rather, fall back on non-packet performance) in the recursive situations, it "breaks" in the incoherent situations. I hate to keep harping on this point, but the only reasonable distinction between modern, efficient ray tracing and rasterization is coherence of control flow and memory accesses.

Hell you can ray trace really well on a GPU (I'm qualified to say this having contributed to exactly such a product), and it's very efficient as long as the rays are relatively coherent. Incoherent rays cause control flow and memory access divergence which tanks performance on a wide-SIMD architecture (i.e. GPUs, and I hate to say, Larrabee too...). This is just a fundamental computational problem and it's not something that can be magically overcome by either rasterizers or ray tracers.

Anyways the point that I'm trying to make is that once you've used both rasterization and ray tracing together, and mixed and matched them in the same renderer, and played with which one to use to resolve specific queries, you start to see similar patterns in how they work. From a high level they may appear to be very different beasts, but they're really just different tools in the "rendering box", and not all that different at that.

In the end I've yet to see a compelling reason why to use ray tracing for coherent rays now or ever, and conversely I've yet to see a compelling reason to rasterize coherent rays. Thus the only discussion is really in the middle area of "what's coherent enough for rasterization to be efficient on a given architecture", and "what incoherent rays can be approximated well by a set of coherent rays".

And as an aside, I'm still not sure why people are so obsessed with ray traced shadows. At the same speed that they can be ray traced, I can easily get sub-pixel accuracy with a ridiculous amount of filtering out of rasterization/shadow maps, something which would take many, many rays and a lot of super-sampling to accomplish with ray traced shadows. The situation gets even worse for ray tracing with soft shadows, as rendering and accumulating many shadow maps of the light will give you "physically accurate" results that are completely the same as what you'd get with many shadow rays, and generally faster as well. The point is that shadow rays are generally pretty coherent, and thus handled efficiently by a rasterizer. I'd love to see an amazing real-time ray traced shadows implementation prove me wrong, but indeed the quality delta of what you can do with shadows in a given time slice has been getting even larger in favour of rasterization-based techniques in the past few years...

As a second aside, lets leave gameplay discussions completely out of this. They are entirely unrelated to graphics and are a resource-management decision that the game producers/publishers make. Our job as graphics people is to make available the best tools possible to the game designers so that they can realize their creative and artistic visions. If they decide to go with a simple art style, fantastic. If they want to realize their amazing game idea using realistic graphics, that's great too. If they want to make a game about looking through glass spheres at checkerboards, we'd damn well better be ready to do some ray tracing ;)
Advertisement
I am not familiar with the REYES method, so I can't really comment on that. I am not sure however I understand your 1x1 statement: Rasterizing a 1x1 area is not the same as ray tracing it. It is for the primary ray, but for the secondary rays, it is very different: In a ray tracer, calculating the new ray direction is trivial, natural and straight-forward; in a rasterizer, you have to work around the fact that a rasterizer operates on local data. In that sense, in my opinion a ray tracer is not like rasterization at all.

Regarding your statement that the only important axis of comparison is speed: I don't agree there. There are several other important issues that may make one approach more suitable than the other: Ease of implementation, hardware support, and expectations about the future. Ease of implementation: I mentioned the 'bag of tricks' several times; this is one thing that I really don't like about rasterization. It leads to 300k lines of code in the Unreal engine, countless books on shader tricks, and a hard-to-enter profession (teacher speaking here). Moving all those books aside, exchanging them for physics books, and doing it the way God intended it, somehow feels like a justification for losing some speed. :) Expectations about the future: Using a 'trick' in a ray tracer (similar to what you would do in a rasterizer) is different when you know that the next generation of hardware will not need the trick, because it can do the 'real thing'. As I mentioned, ray tracing is limited only by raw performance right now; rasterization is limited by the availability of (even more) smart ideas. In the long run, I expect raw performance to outrun the people of the smart tricks. Then again, people expected AI to reach an IQ of 120 somewhere this decade, didn't they? ;)

- Jacco.
I too think you're all missing the most important point of the interview. He's going to to use ray-casting (note the distinction; not ray-tracing) to get "infinite" amount of detail into the games. No more resource restrictions (aside from the physical storage of the game).
When a node that isn't in memory is required, the next lower MIP map of the voxel structure is used instead (and you just visited this so you know where it is), and a "page fault" is asynchronously triggered, which loads in the data. This is pretty cool IMO, and even if this comes at a cost of simpler shaders running at each visible fragment.

When you can bake in unique millimeter level of lightmaps (even with some view dependent stuff, like maybe one or two spherical radial basis functions for the brightest static lights) the quality will be so excellent for 99% of the scenarios that you don't really need too many fancy shaders (i.e. it's perfectly justifiable to spend most of your horse power doing that ray casting)... I think he's right in his overall philosophy that freeing up artists to create and display massive amounts of unique data is way more important for graphical fidelity then a bunch of fancy shaders.
Quote:Original post by Matt Aufderheide
Quote:Original post by Promit
Quote:Original post by cignox1
I think that raytracing will not be a viable options until rasterization will reach that borderline where the quality provided by all those hacks (i.e. fake soft shadows) will no longer satisfy users.
Cue argument that our graphics is already as good as it's worth bothering and people should be working on gameplay...


That's not the argument at all...the point is that rasterization will continue to improve along with other methods.


Perhaps I was misundertood... what I wanted to say is that once rasterization will reach the quality (don't get me wrong, I'm just talking about the same features, reflections, refractions and so on and not the global visual quality) easily provided by a basic raytracer, then perhaps performance will be so close that developers will decide to move to RT, just because it is far easier to implement and for high quality scenes the speed difference may become less obvious.

Differen people, different ideas, but come on, don't say me that a game that after 5 years can look way better on newer HW by just setting a higher sampling rate is not a nice dream :-)

On a side note I want to mention that even if Pixar is still using rasterization for their movies (and I would do the same thing considering the impressive amount of codebase they have and the fact that they actually sell Renderman in the whole world), they are gradually adding RT functionalities. To me, this means that (they think) once you want high quality results, there is no longer point to not using RT. In addition, Blu Sky studios already used RT for the whole rendering of Robots and Age of Ice.

I suppose that since what we currently see in those movies is what we should expect in future games (movies like Toy Story have been already overcomed by recent games), we should also expect that the technologies they used are those that will be used tomorrow for games.

Quote:Original post by phantomus
I am not sure however I understand your 1x1 statement: Rasterizing a 1x1 area is not the same as ray tracing it. It is for the primary ray, but for the secondary rays, it is very different: In a ray tracer, calculating the new ray direction is trivial, natural and straight-forward; in a rasterizer, you have to work around the fact that a rasterizer operates on local data. In that sense, in my opinion a ray tracer is not like rasterization at all.

You're thinking at far too high a level, but making arguments about the low level. Stop thinking about details like shaders shooting secondary rays, etc. and consider what the fundamental differences are between rasterization and ray tracing: both are simply intersection queries of the scene. i.e. "if I shoot off a bunch of rays, give me back what they hit". Both algorithms answer this question, both return the 100% exact same result. The difference is that ray tracing does it on the input rays, one by one, by sampling the scene data, while rasterization does it by scattering the scene data onto the frame/depth buffer.

Thus when you say that "for secondary rays it is very different"... no it isn't, not at all! What algorithm you choose to resolve secondary rays is entirely irrelevant to primary rays, or any other rays in the scene. Consider if your rasterizer is asked to resolve intersections for a bunch of secondary rays... if they are coherent, great we'll resolve them all at once. If not, fine, we'll do them one at a time, effectively re-rasterizing the scene into a 1x1 framebuffer for each one. It would be equivalent to rendering your entire scene using OpenGL picking as an intersection test for each framebuffer pixel. i.e. quite slow for incoherent rays, but it is really important to realize that the result is the same, and the only difference is speed!

Quote:Original post by phantomus
Ease of implementation: I mentioned the 'bag of tricks' several times; this is one thing that I really don't like about rasterization. It leads to 300k lines of code in the Unreal engine, countless books on shader tricks, and a hard-to-enter profession (teacher speaking here).

While I can accept some of the "simplicity" argument here, it's code we're talking about... rasterization can be exposed to the users in the same way that ray tracing is if desired. They can be used together either implicitly or explicitly as well. In the aforementioned GPU ray tracer, you can flick a switch and rasterize or ray trace primary rays, and incoherent secondary rays can be shot arbitrarily and directly from your fragment shader - all on the GPU. This isn't particularly hard, either... the basics of rasterization and ray tracing are quite simple. Once you start to layer stuff on, both get complicated and there's really no avoiding that.

Furthermore even if you do accept that shooting incoherent secondary rays is useful (and I agree 100%), there's still zero argument to ray trace the coherent rays (i.e. primary and arguably shadow rays). So while I'll accept that I like to shoot arbitrary rays to get pretty pictures (as I said, I like ray tracing too!), that's no reason to throw out rasterization for the coherent rays. If you want, think of rasterization as an extremely-optimized packet tracer... there are more real similarities there than you know ;)

Quote:Original post by phantomus
Moving all those books aside, exchanging them for physics books, and doing it the way God intended it, somehow feels like a justification for losing some speed. :)

Well just to throw a little wrench into your "physical correctness" world, ray tracing is actually uncomputable, so you'll never actually get there ;) Not a particularly useful result in practice, but I like to bring it up when people start to take the "high road" too much.

As I mentioned previous though, this is the sort of misunderstanding of the underlying queries/techniques that leads to ray tracing dogma... you can complain about how cube maps are bad approximations to incoherent reflection/refraction rays (and please do!), but at best that only motivates the need to efficiently query incoherent ray intersections. Great, I agree... we need to be able to ray trace secondary rays well. As explained above, we very well could resolve even these incoherent queries with a rasterizer and you would get back 100% the same results as ray tracing - it would just be kind of slow :)

Perhaps you understand what I'm saying now: think of ray tracing and rasterization as different ways to execute intersection queries, and use the fastest one for a given set of rays. It really is that simple, and that's exactly what I mean by the only useful axis of comparison is speed. People just get so caught up in the high level details that they totally miss what the real comparison is between the techniques, and thus on one hand spend too much time reinventing rasterizers (and calling it "packet tracing") or on the other hand spend too much time trying to avoid tracing a bunch of incoherent rays (as you would argue, and I would agree!).

So really it's a simple as having two functions, each of which returns the same result but may be more or less efficient depending on the inputs. It's comparable to - although admittedly more complicated than - different containers... say vectors versus hash tables. Indeed the difference between the two algorithms is just the acceleration structure and how it is queried.

Everything else - such as how you implement effects on top of this framework, etc. - is interesting, but besides the point. As with every graphical effect, implement it as efficiently as possible (using ray tracing or rasterization or otherwise), and if it's too slow find an approximation that's faster.

Quote:Original post by phantomus
As I mentioned, ray tracing is limited only by raw performance right now; rasterization is limited by the availability of (even more) smart ideas.

Even leaving my incoherent rasterization example above alone, there's no reason why you need to use one or the other. As I stated before: rasterize coherent rays and ray trace incoherent ones. Anything less is just throwing performance out the window!
Quote:and doing it the way God intended it,
... lol I am sure God plays GTA and desparately awaits GTA IV now :-) ... but I don't think he cares about the fact if a rasterizer or raytracer is used :-) ...
If you want it easy and simple go for a mobile platform :-). I bet if we all get into raytracers, we will reach a similar level of detail as we do now with rasterizers and ShaderX and GPU Gems will still make sense :-)
What a refreshing discussion!
Quote:Original post by AndyTX
both are simply intersection queries of the scene. i.e. "if I shoot off a bunch of rays, give me back what they hit". Both algorithms answer this question, both return the 100% exact same result. The difference is that ray tracing does it on the input rays, one by one, by sampling the scene data, while rasterization does it by scattering the scene data onto the frame/depth buffer.


It is correct that rasterization can be viewed as a special case of a bunch of implicit primary ray hits that are simply interpolated. But raytracing and rasterization live in different worlds. Raytracing does have access to much more data at time of sampling, which is one good reason why its trivial to do reflections and shadows with it. Not so with rasterization: any effect that (partly) operates outside the local rasterizer domain is hard to do.

A rasterizer with pixel shaders capable of shooting secondary rays, now THIS is something :-)
~dv();
Quote:Original post by sebastiansylvan
I too think you're all missing the most important point of the interview. He's going to to use ray-casting (note the distinction; not ray-tracing) to get "infinite" amount of detail into the games. No more resource restrictions (aside from the physical storage of the game).

Yeah, I'm not sure why this turned into an argument about RT vs raster...

JC pretty much just said "lets use RT along with raster for things that raster can't easily do". He specifically said he wasn't talking about lighting or shadows or reflections (as current raster techniques are "good enough" even if not correct). The man just wants to play with voxels!
Quote:Original post by dv
Raytracing does have access to much more data at time of sampling, which is one good reason why its trivial to do reflections and shadows with it. Not so with rasterization: any effect that (partly) operates outside the local rasterizer domain is hard to do.

Certainly that's the case when you look at "pure ray tracing" and "pure rasterization". The point that I was trying to make - albeit potentially in a round-about manner - is that both are simply ways to resolve queries into a scene database. Rasterization resolves many of these queries "at once" when the queries meet some simple conditions, and ray tracing resolves them separately but in the general case. Rasterization can be implemented in terms of raytracing and vice versa, although neither is efficient when implemented that way ;)

So my point is really that you have to think of it in these terms... it's certainly useful to allow shaders to make arbitrary queries into the scene database themselves, and these "secondary" queries can be resolved using raytracing, or if you're clever sometimes you can recapture some "coherence" in them and use rasterization (for instance, shadow rays).

Considering things in these terms not only allows one to see a larger view than "I have to choose between ray tracing or rasterization for my application", but also to stop comparing them uselessly and arguing that one is going to go away.

The situation really is analogous to arguing between using a linked list or an array. One does some operations faster than the other, so you choose which to use based on the operations that you plan on performing, or more often you use both together as part of a larger algorithm. It's the same with this "debate" and people need to stop making arguments to the effect of "linked lists are better than vectors because they do O(1) inserts and deletes" or "arrays are better than linked lists because they do O(1) random access". Let's just use them both as appropriate!

Quote:Original post by dv
A rasterizer with pixel shaders capable of shooting secondary rays, now THIS is something :-)

It can already be done in a fairly straightforward and efficient manner :)

Quote:Original post by Hodgman
Yeah, I'm not sure why this turned into an argument about RT vs raster...

Don't forget that the article was a direct response to exactly that argument, as were John's answers. You need to read them in that context. He was potentially being a bit hard on ray tracing just because the previous articles were so ridiculously on the other end of the scale.

Quote:Original post by Hodgman
JC pretty much just said "lets use RT along with raster for things that raster can't easily do".

Indeed!
Quote:Original post by dv
It is correct that rasterization can be viewed as a special case of a bunch of implicit primary ray hits that are simply interpolated. But raytracing and rasterization live in different worlds. Raytracing does have access to much more data at time of sampling, which is one good reason why its trivial to do reflections and shadows with it. Not so with rasterization: any effect that (partly) operates outside the local rasterizer domain is hard to do.


You're not really comparing like with like. In order to be efficient at all with any kind of vaguely complex scene a raytracer needs high level global knowledge of the scene so it can build efficient acceleration data structures. Typically when people make these misleading comparisons between the supposed benefits of ray tracing vs. rasterization they're assuming the presence of these acceleration structures and comparing to rasterization as exposed by a low level API like DirectX or OpenGL that you just throw unprocessed batches of triangles at.

The reality is that any real game engine has a bunch of acceleration data structures that govern what raw triangles are dispatched to the hardware. If you're going to compare rasterization with ray tracing in any meaningful way you need to compare against a higher level graphics engine with the kind of scene level knowledge that you're allowing the raytracer. Most of the claimed benefits of raytracing disappear when you start comparing to a rasterizer that has high level scene management with visibility and occlusion culling, instancing functionality, level of detail mechanisms and all the other common features of a modern graphics engine. Viewed in the context of a higher level graphics API/system that has scene level knowledge, the differences between rasterization and ray tracing are just in the details of how they arrange their data structures to efficiently reduce the amount of work needed to render a scene. They both apply similar spatial partitioning principles and hierarchical level of detail techniques to accelerate rendering the scene.

As AndyTX has done a great job of explaining, the only significant difference between rasterization and ray tracing when viewed at the high level of rendering complex scenes is in how efficient they are at answering ray intersection queries with different levels of coherency. Really both are quite simple from a software engineering point of view at the low level by comparison to the task of creating a software architecture that can efficiently render scenes of the complexity of a modern game, never mind the far more complex scenes needed to get closer to approximating reality.

Game Programming Blog: www.mattnewport.com/blog

This topic is closed to new replies.

Advertisement