Adventures with Raytracing

Posted by Astryl on May 9, 2012, 9:25 a.m.

Yesterday was a good day.

~Mega sits leans back in his seat, wipes his monocle, and pauses for a moment to sample the wine he has in front of him. He grimaces and hastily returns the glass to it's place on the table, and opts for his pipe instead…~

Caution: Serious blog follows

I sat down, thought of an abstract problem, and came up with a solution that worked. The problem is an old one: Implement a Raytracing algorithm.

I've tried to follow raytracing 'tutorials' before, and even read a few documents on the subject. All of these methods only served to addle my poor brain, so I gave up on that a while back.

But I know more math now.

Anyways, I present here a few types of data:

(Java/C# type Pseudocode, because it's readable)

class Primitive;
class Sphere extends Primitive;

// Some of Sphere's members:
Sphere::position; // Vector
Sphere::radius;   // Float

Now imagine a randomly generated 'scene' containing a number of these Sphere objects, with randomly initialized data for position and radius.

The scene is merely an array of Primitive pointers.

So how the heck does one translate this into a raytraced scene? That's where the fun begins!

Let's simplify the problem

What is raytracing? The process of shooting a 'line' through every pixel on the view-plane, finding out if it intersects objects, and rendering the pixel based on various factors (Such as object material, secondary rays, lighting, etc).

Creating a ray for each pixel on the screen is the easy part (Two for loops), and drawing a pixel is hardly a challenge (For most).

It's the intersection we need.

Note that we're not only wanting to know if the ray intersects the objects we have in our scene, but we want to know exactly where it hits on the surface of the object. If this sounds familiar, then you get a +1.

Because Collision Detection and Raytracing are (almost) one and the same problem.

The only difference is that you're not dealing with Object//Object collisions, but rather Line//Object collisions, and you don't want penetration information, you want information about the Material of the object, it's surface normal (For spawning secondary rays) and perhaps it's lighting values.

So given the data above, detecting whether a given point in 3D space lies within the sphere becomes a mere distance check.

Long story short:

I know it doesn't look impressive (Because it's not); it's missing one key feature: Lighting. But it does a remarkable job of tracing the surface of a sphere defined with only a Vector and a Scalar. (I used some fake lighting, with view-orientated falloff shading. It glitched, as you can see by the bright white spheres).

Anyway, the next features I intend to implement are both Lights and Planes.

A light is merely a Primitive with an intensity and color.

A plane can be defined as a Vector and a Scalar (Like the sphere). Normal and Direction.

As you can see, I'm still wasting my time on useless-but-mentally-stimulating projects, even in the middle of a competition

~Mega stands up, and with a quick motion of his hand throws something towards you. Bending over, you notice it's a card with the words "Watch your back". When you look up, Mega is gone. Two hours later, you realize your wallet is gone too.~

Comments

Astryl 12 years, 6 months ago

Just rediscovered SIGGRAPH. Great materials there. Suggest you give them a read if you're interested in this sort of thing (Also has articles on Raycasting, and general 3D/Shader programming etc).

I forgot to mention what's going on with my game: Nothing. :P

I'm kinda stuck at the moment, waiting for my mind to jump out of technical mode and back into creative mode.

Mordi 12 years, 6 months ago

Pretty cool. You should try making a fancy tech-demo out of it. Maybe make an animatied sphere-dude to go with it?

Astryl 12 years, 6 months ago

@Cyrus: I fail to see how OpenCL/CUDA are going to accelerate a software buffered SDL app. >;3

@Mordi: I'm thinking of doing just that, probably in Assembly, which means it'll be a VGA demo. Why DOS? Because I can use more assembly, and get tighter speedups without the overhead of SDL/Windows.