Lua Ray Tracer

Chapter 8
Login

Chapter 8 - Metal

In Chapter 7, the text introduced diffuse materials by hard-coding behavior into Ray and main. Chapter 8 is called 'Metal', but starts by focusing on the concept of a material. It suggests two critical aspects of a material:

  1. How it scatters rays
  2. How it attenuates the rays when they are scattered

As I write this, it's a bit confusing to think about absorbing some rays and attenuating rays. The text gives me the option to handle this as I see fit, but the code provided suggests

The first task is to reimplement our diffuse (Lambertian) material from Chapter 7 using this abstraction. The original C++ implements this as a class, material, with a method scatter, and re-uses hit_record to pass a bunch of parameters to the scatter method, and returns a boolean, destructively modifying a provided Ray to pass back the scattered ray. In Lua, I decided to pass back a Ray regardless:

-- Lambertian material

Lambertian = {}

function Lambertian:new(o)
   o = o or {}
   self.__index = self
   setmetatable(o, self)
   return o
end

-- Parameters:
--   ray: [Ray] The incoming ray to scatter
--   hit_record: [HitRecord] The HitRecord associated with its impact
--   attenuation: [Vector3] How much the ray's color should be attenuated
function Lambertian:scatter(ray, hit_record, attenuation)
   target = hit_record:p() + hit_record:normal() + random_in_unit_sphere()
   return Ray:new{hit_record:p(), target - hit_record:p(), ray:world()}
end