Now that we can get intersections from our solids, we’re almost ready to start producing some images. We still need two things: first we need a little bit more information about the surrounding world and second we need a way to convert this information to color.
For the more information we’ll introduce a Ray_Path which looks like this:
data Ray_Path = Ray_Path {hit :: Maybe Intersection, light_hits :: [Light_Castback], shader :: Shader} |
A Ray_Path gives us everything we need to understand how a ray travelled through our scene (things will have to be added to what we have right now) and convert that to color. The hit field is just an intersection from the previous post. The light_hits contain Light_Castbacks which I’m not going to define just yet–they’ll be covered in a post called “Lighting”–for now let it suffice to say that a Light_Castback will tell you everything you need to know about how this ray interacted with the lights in the scene. However we are going to talk about the shader. Shaders are the second thing we need, they’re a way to convert a Ray_Path into color. In case you don’t trust me, here’s the type signature:
type Shader = Ray_Path -> Color |
Shaders are a pretty pervasive idea in graphics, and eventually I’m going to implement a full blown shader language. However for right now they’re just described in terms of a Haskell function.
This is all we need to start doing some really simple ray tracing, so here it is: this is a simple scene with a single sphere and a shader attached to it that always returns red. Nothing too fancy, but it proves that everything underneath the hood is working: