diff options
| author | Martin Lehoux <martin@lehoux.net> | 2020-04-04 19:41:57 -0700 |
|---|---|---|
| committer | Martin Lehoux <martin@lehoux.net> | 2020-04-04 19:41:57 -0700 |
| commit | 13be7ded788fe88d5ac8d6759273516652bf1a80 (patch) | |
| tree | 57d7eabb022e500e8b06089fb935c4a17c7cfbb3 | |
| parent | d233910be5eb6bdf9bb9deb6ffa0fa79f659e902 (diff) | |
feat - Add Lambertian material
| -rw-r--r-- | color.go | 6 | ||||
| -rw-r--r-- | hitable.go | 18 | ||||
| -rw-r--r-- | main.go | 7 | ||||
| -rw-r--r-- | material.go | 16 |
4 files changed, 33 insertions, 14 deletions
@@ -32,10 +32,8 @@ func RayColor(ray Ray, hitable_list HitableList, depth int) Color { } hit := hitable_list.Hit(ray, T_MIN, T_MAX) if hit.time > 0.0 { - // TODO: Use the correct distribution - direction := AddVec3D(hit.normal, RandomInUnitSphere()) - scattered := Ray{hit.point, direction} - return AttenuateColor(Color{0.5, 0.5, 0.5}, RayColor(scattered, hitable_list, depth+1)) + scattered, attenuation := hit.material.Scatter(ray, hit) + return AttenuateColor(attenuation, RayColor(scattered, hitable_list, depth+1)) } param := 0.5 * (ray.direction.Unit().y + 1) return LinearBlend(Color{0.5, 0.7, 1.0}, Color{1.0, 1.0, 1.0}, param) @@ -3,9 +3,10 @@ package main import "math" type HitRecord struct { - time float64 - point Vec3D - normal Vec3D + time float64 + point Vec3D + normal Vec3D + material Material } type Hitable interface { @@ -16,7 +17,7 @@ type Hitable interface { type HitableList []Hitable func (hitable_list HitableList) Hit(ray Ray, t_min float64, t_max float64) HitRecord { - closest_hit := HitRecord{T_MAX, Vec3D{}, Vec3D{}} + closest_hit := HitRecord{T_MAX, Vec3D{}, Vec3D{}, nil} for _, hitable := range hitable_list { hit := hitable.Hit(ray, t_min, closest_hit.time) if hit.time > 0 { @@ -31,8 +32,9 @@ func (hitable_list HitableList) Hit(ray Ray, t_min float64, t_max float64) HitRe } type Sphere struct { - center Vec3D - radius float64 + center Vec3D + radius float64 + material Material } func (sphere Sphere) Normal(point Vec3D, ray Ray) Vec3D { @@ -55,12 +57,12 @@ func (sphere Sphere) Hit(ray Ray, t_min float64, t_max float64) HitRecord { time := (-b - root) / (2.0 * a) if t_min < time && time < t_max { point := ray.PointAt(time) - return HitRecord{time, point, sphere.Normal(point, ray)} + return HitRecord{time, point, sphere.Normal(point, ray), sphere.material} } time = (-b + root) / (2.0 * a) if t_min < time && time < t_max { point := ray.PointAt(time) - return HitRecord{time, point, sphere.Normal(point, ray)} + return HitRecord{time, point, sphere.Normal(point, ray), sphere.material} } } return HitRecord{} @@ -20,8 +20,11 @@ func main() { VERTICAL := Vec3D{0.0, 2.0, 0.0} CAMERA := Camera{LOWER_LEFT_CORNER, ORIGIN, HORIZONTAL, VERTICAL} - SPHERE := Sphere{Vec3D{0.0, 0.0, -1.0}, 0.5} - EARTH := Sphere{Vec3D{0.0, -100.5, -1.0}, 100.0} + MAT_RED := Lambertian{Color{0.7, 0.3, 0.3}} + MAT_GREEN := Lambertian{Color{0.8, 0.8, 0.0}} + + SPHERE := Sphere{Vec3D{0.0, 0.0, -1.0}, 0.5, MAT_RED} + EARTH := Sphere{Vec3D{0.0, -100.5, -1.0}, 100.0, MAT_GREEN} WORLD := HitableList{EARTH, SPHERE} frame := Frame{} diff --git a/material.go b/material.go new file mode 100644 index 0000000..db1e4d6 --- /dev/null +++ b/material.go @@ -0,0 +1,16 @@ +package main + +type Material interface { + Scatter(ray Ray, hit HitRecord) (Ray, Color) +} + +type Lambertian struct { + albedo Color +} + +func (lambertian Lambertian) Scatter(ray Ray, hit HitRecord) (Ray, Color) { + // TODO: Use the correct distribution + direction := AddVec3D(hit.normal, RandomInUnitSphere()) + scattered := Ray{hit.point, direction} + return scattered, lambertian.albedo +} |
