Implementing fast, ray-traced soft shadows in a game engine
blog.imgtec.com
blog.imgtec.com
The main idea is that you represent a 3D object using not triangles, but a function f(x,y,z) stored on the GPU. The function should return the approximate distance from point (x,y,z) to the object in question, so it's zero on the object's surface and negative on the inside.
It's easy to construct such functions for spheres, boxes, etc. [1] It's also easy to define combinators for moving, adding and subtracting different objects, adding rounded corners, etc.
That representation is well suited for raymarching [2], because the value of f(x,y,z) at your current position along the ray can be safely used as the length of the next raymarching step, so you automatically get larger steps when you're far from the object.
It's also well suited for rendering shadows with penumbras, because the minimum value of f(x,y,z) as you march along the ray gives you the distance between the ray and the object [3]. A slight modification of that trick can give you ambient occlusion as well.
[1] http://iquilezles.org/www/articles/distfunctions/distfunctio...
[2] http://iquilezles.org/www/material/nvscene2008/rwwtt.pdf
[3] http://iquilezles.org/www/articles/rmshadows/rmshadows.htm
You can find the sample code here http://cdn.imgtec.com/OpenRLSDK/OpenRL-Hybrid-Example.zip
And how well is the hardware currently handling highly divergent rays? Such as those used in GI or reflections?
But I don't see evidence of blockiness that such a pixelized distance map would produce. It's hard to tell what they're doing. One thing I'm sure they're not doing is real ray casting from each hit point to the light source. I don't see how they could test each such ray against the whole scene, and do that using the GPU.
While I'm on the topic, the soft shadows they compute are not exact, since they assume the light source is a circle, and their analytic formula for the penumbra angle is an approximation. Shadows would look different for linear lights like fluorescent tubes.
But hey, if you're in the middle of a game, dodging enemies, you won't stop to criticize the slightly incorrect shadows. In an architectural rendering, the difference might be noticeable.
We are in fact casting a real ray from each non-trivially shadowed pixel towards the light source. We're using the PowerVR Wizard GPU's hardware ray tracing unit to accelerate process. Pixels who's surface is back-facing WRT the light (i.e. N dot L < 0) we know are shadowed so there's no need to cast any rays.
This article on AnandTech presents the architecture in more detail: http://www.anandtech.com/show/7870/imagination-announces-pow...
Edit for those that are out of the loop: shadows are notoriously finicky. There are a bunch of approaches to them that, while a heroic effort, suck. They all compromise on different things and yet fail to be really good at what they are supposed to be perfect at. You can spend a week tweaking constants only to get something passable for your engine. They are the bane of an engine dev's life.
This approach is so clean and, in theory, comes very close to a one-size-fits-all-golden-hammer. Not perfect, but worlds apart from what games are doing today. Catch is: this specific clean implementation of raytraced shadows can only be done with PowerVR (AFAIK).
http://www.techeye.net/chips/imagination-to-buy-caustic-grap...
Not sure if this will work, I thought about this years ago when I was still in the demoscene but never had the time to implement it.
Even if you could, the penumbra size is a function of not only the light size but also the distance from the shadowed surface to the occluding edge, which is fundamentally something you cannot know during shadow occluder rendering time.
Deleted comment
Deleted comment