Materials and metals
This commit is contained in:
parent
5c2ad78ce2
commit
60f3009702
2 changed files with 72044 additions and 71962 deletions
96
main.go
96
main.go
|
@ -74,6 +74,11 @@ func (v Vec3) Length_squared() float32 {
|
||||||
return v.E[0]*v.E[0] + v.E[1]*v.E[1] + v.E[2]*v.E[2]
|
return v.E[0]*v.E[0] + v.E[1]*v.E[1] + v.E[2]*v.E[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v Vec3) Near_zero() bool {
|
||||||
|
var s float64 = 1e-8
|
||||||
|
return (math.Abs(float64(v.E[0])) < s && math.Abs(float64(v.E[1])) < s && math.Abs(float64(v.E[2])) < s)
|
||||||
|
}
|
||||||
|
|
||||||
// Vector utility functions
|
// Vector utility functions
|
||||||
|
|
||||||
func (v Vec3) String() string {
|
func (v Vec3) String() string {
|
||||||
|
@ -141,6 +146,10 @@ func RandomOnHemisphere(normal Vec3) Vec3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Reflect(v Vec3, n Vec3) Vec3 {
|
||||||
|
return v.Sub(n.Mult(2*Dot(v,n)))
|
||||||
|
}
|
||||||
|
|
||||||
const pi float32 = 3.1415926535897932385
|
const pi float32 = 3.1415926535897932385
|
||||||
|
|
||||||
func Degrees_to_radians(degrees float32) float32 {
|
func Degrees_to_radians(degrees float32) float32 {
|
||||||
|
@ -270,6 +279,7 @@ type Hit_record struct {
|
||||||
normal Vec3
|
normal Vec3
|
||||||
t float32
|
t float32
|
||||||
front_face bool
|
front_face bool
|
||||||
|
mat Material
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rec *Hit_record) Set_face_normal(r *Ray, outward_normal Vec3) {
|
func (rec *Hit_record) Set_face_normal(r *Ray, outward_normal Vec3) {
|
||||||
|
@ -288,6 +298,7 @@ func (rec *Hit_record) Set_face_normal(r *Ray, outward_normal Vec3) {
|
||||||
type Sphere struct {
|
type Sphere struct {
|
||||||
center Vec3
|
center Vec3
|
||||||
radius float32
|
radius float32
|
||||||
|
mat Material
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Sphere) Hit_sphere(r *Ray, ray_t *Interval, rec *Hit_record) bool {
|
func (s Sphere) Hit_sphere(r *Ray, ray_t *Interval, rec *Hit_record) bool {
|
||||||
|
@ -314,6 +325,7 @@ func (s Sphere) Hit_sphere(r *Ray, ray_t *Interval, rec *Hit_record) bool {
|
||||||
rec.p = r.At(rec.t)
|
rec.p = r.At(rec.t)
|
||||||
outward_normal := rec.p.Sub(s.center).Div(s.radius)
|
outward_normal := rec.p.Sub(s.center).Div(s.radius)
|
||||||
rec.Set_face_normal(r, outward_normal)
|
rec.Set_face_normal(r, outward_normal)
|
||||||
|
rec.mat = s.mat
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,6 +361,55 @@ func (hl Hittable) Hit(r *Ray, ray_t Interval, rec *Hit_record) bool {
|
||||||
return hit_anything
|
return hit_anything
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============== MATERIAL =================
|
||||||
|
type Material struct {
|
||||||
|
lambertian bool
|
||||||
|
metal bool
|
||||||
|
albedo Vec3
|
||||||
|
fuzz float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMaterial(l bool, m bool, a Vec3, f float32) Material {
|
||||||
|
if f >= 1.0 {
|
||||||
|
return Material{
|
||||||
|
lambertian: l,
|
||||||
|
metal: m,
|
||||||
|
albedo : a,
|
||||||
|
fuzz: 1.0,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Material{
|
||||||
|
lambertian: l,
|
||||||
|
metal: m,
|
||||||
|
albedo : a,
|
||||||
|
fuzz: f,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mat Material) Scatter(r_in *Ray, rec *Hit_record, attenuation *Vec3, scattered *Ray) bool {
|
||||||
|
if (mat.lambertian) {
|
||||||
|
scatter_direction := rec.normal.Add(RandomUnitVector())
|
||||||
|
// Catch degenerate scatter direction
|
||||||
|
if scatter_direction.Near_zero() {
|
||||||
|
scatter_direction = rec.normal
|
||||||
|
}
|
||||||
|
|
||||||
|
*scattered = *NewRay(rec.p, scatter_direction)
|
||||||
|
*attenuation = mat.albedo
|
||||||
|
} else if (mat.metal) {
|
||||||
|
var reflected Vec3 = Reflect(Unit_vector(r_in.Direction()), rec.normal)
|
||||||
|
*scattered = *NewRay(rec.p, reflected.Add(RandomUnitVector().Mult(mat.fuzz)))
|
||||||
|
*attenuation = mat.albedo
|
||||||
|
if !(Dot(scattered.Direction(), rec.normal) > 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =============== CAMERA ===================
|
// =============== CAMERA ===================
|
||||||
|
|
||||||
type Camera struct {
|
type Camera struct {
|
||||||
|
@ -374,9 +435,12 @@ func Ray_color(r Ray, depth int, world *Hittable) Vec3 {
|
||||||
return NewColor(0,0,0)
|
return NewColor(0,0,0)
|
||||||
}
|
}
|
||||||
if (world.Hit(&r, *NewInterval(0.001, float32(math.Inf(1))), &rec)) {
|
if (world.Hit(&r, *NewInterval(0.001, float32(math.Inf(1))), &rec)) {
|
||||||
//direction := RandomOnHemisphere(rec.normal)
|
var scattered Ray
|
||||||
direction := rec.normal.Add(RandomUnitVector())
|
var attenuation Vec3
|
||||||
return Ray_color(*((NewRay(rec.p, direction))), depth-1, world).Mult(0.5)
|
if ((rec.mat).Scatter(&r, &rec, &attenuation, &scattered)) {
|
||||||
|
return attenuation.MultVec(Ray_color(scattered, depth-1, world))
|
||||||
|
}
|
||||||
|
return NewColor(0.0,0.0,0.0)
|
||||||
}
|
}
|
||||||
unit_direction := Unit_vector(r.Direction())
|
unit_direction := Unit_vector(r.Direction())
|
||||||
a := (unit_direction.Y() + 1.0)*0.5
|
a := (unit_direction.Y() + 1.0)*0.5
|
||||||
|
@ -447,16 +511,34 @@ func (cam *Camera) Pixel_sample_square() Vec3 {
|
||||||
|
|
||||||
// =============== MAIN =====================
|
// =============== MAIN =====================
|
||||||
func main() {
|
func main() {
|
||||||
|
// Materials
|
||||||
|
material_ground := NewMaterial(true, false, NewColor(0.8, 0.8, 0.0), 0.0)
|
||||||
|
material_center := NewMaterial(true, false, NewColor(0.7, 0.3, 0.3), 0.0)
|
||||||
|
material_left := NewMaterial(false, true, NewColor(0.8, 0.8, 0.8), 0.3)
|
||||||
|
material_right := NewMaterial(false, true, NewColor(0.8, 0.6, 0.2), 1.0)
|
||||||
|
|
||||||
// World
|
// World
|
||||||
|
|
||||||
world := NewHittable()
|
world := NewHittable()
|
||||||
world.Add(Sphere{
|
|
||||||
center: NewVec3(0, 0, -1),
|
|
||||||
radius: 0.5,
|
|
||||||
})
|
|
||||||
world.Add(Sphere{
|
world.Add(Sphere{
|
||||||
center: NewVec3(0, -100.5, -1),
|
center: NewVec3(0, -100.5, -1),
|
||||||
radius: 100,
|
radius: 100,
|
||||||
|
mat: material_ground,
|
||||||
|
})
|
||||||
|
world.Add(Sphere{
|
||||||
|
center: NewVec3(0, 0, -1.0),
|
||||||
|
radius: 0.5,
|
||||||
|
mat: material_center,
|
||||||
|
})
|
||||||
|
world.Add(Sphere{
|
||||||
|
center: NewVec3(-1.0, 0, -1.0),
|
||||||
|
radius: 0.5,
|
||||||
|
mat: material_left,
|
||||||
|
})
|
||||||
|
world.Add(Sphere{
|
||||||
|
center: NewVec3(1.0, 0, -1.0),
|
||||||
|
radius: 0.5,
|
||||||
|
mat: material_right,
|
||||||
})
|
})
|
||||||
// Image
|
// Image
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue