Raytracing done :3
This commit is contained in:
parent
95c7fcaa33
commit
64449e18f7
2 changed files with 809675 additions and 89648 deletions
119
main.go
119
main.go
|
@ -164,7 +164,7 @@ func Reflect(v Vec3, n Vec3) Vec3 {
|
||||||
func Refract(uv, n Vec3, etai_over_etat float32) Vec3 {
|
func Refract(uv, n Vec3, etai_over_etat float32) Vec3 {
|
||||||
cos_theta := float32(math.Min(float64(Dot(uv.Neg(), n)), 1.0))
|
cos_theta := float32(math.Min(float64(Dot(uv.Neg(), n)), 1.0))
|
||||||
r_out_perp := uv.Add(n.Mult(cos_theta)).Mult(etai_over_etat)
|
r_out_perp := uv.Add(n.Mult(cos_theta)).Mult(etai_over_etat)
|
||||||
r_out_parallel := n.Mult(-float32(math.Sqrt(math.Abs(1.0 - float64(r_out_perp.Length_squared())))))
|
r_out_parallel := n.Mult(float32(math.Sqrt(math.Abs(1.0 - float64(r_out_perp.Length_squared())))))
|
||||||
return r_out_perp.Add(r_out_parallel)
|
return r_out_perp.Add(r_out_parallel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,6 +347,15 @@ func (s Sphere) Hit_sphere(r *Ray, ray_t *Interval, rec *Hit_record) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSphere(center Vec3, radius float32, mat Material) Sphere {
|
||||||
|
return Sphere{
|
||||||
|
center: center,
|
||||||
|
radius: radius,
|
||||||
|
mat: mat,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =============== HITTABLE ==================
|
// =============== HITTABLE ==================
|
||||||
type Hittable struct {
|
type Hittable struct {
|
||||||
spheres []Sphere
|
spheres []Sphere
|
||||||
|
@ -432,9 +441,9 @@ func (mat Material) Scatter(r_in *Ray, rec *Hit_record, attenuation *Vec3, scatt
|
||||||
}
|
}
|
||||||
} else if (mat.material == 2) { //Dielectric
|
} else if (mat.material == 2) { //Dielectric
|
||||||
*attenuation = NewColor(1.0, 1.0, 1.0)
|
*attenuation = NewColor(1.0, 1.0, 1.0)
|
||||||
var refraction_ration float32
|
var refraction_ration float32 = 1.0
|
||||||
if rec.front_face {
|
if rec.front_face {
|
||||||
refraction_ration = 1.0/mat.ir
|
refraction_ration /= mat.ir
|
||||||
} else {
|
} else {
|
||||||
refraction_ration = mat.ir
|
refraction_ration = mat.ir
|
||||||
}
|
}
|
||||||
|
@ -442,11 +451,8 @@ func (mat Material) Scatter(r_in *Ray, rec *Hit_record, attenuation *Vec3, scatt
|
||||||
|
|
||||||
cos_theta := float32(math.Min(float64(Dot(unit_direction.Neg(), rec.normal)), 1.0))
|
cos_theta := float32(math.Min(float64(Dot(unit_direction.Neg(), rec.normal)), 1.0))
|
||||||
sin_theta := float32(math.Sqrt(float64(1.0 - cos_theta*cos_theta)))
|
sin_theta := float32(math.Sqrt(float64(1.0 - cos_theta*cos_theta)))
|
||||||
var cannot_refract bool
|
|
||||||
var direction Vec3
|
var direction Vec3
|
||||||
if (refraction_ration * sin_theta > 1.0) {
|
cannot_refract := refraction_ration*sin_theta > 1.0
|
||||||
cannot_refract = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cannot_refract || Reflectance(cos_theta, refraction_ration) > RandomDouble()) {
|
if (cannot_refract || Reflectance(cos_theta, refraction_ration) > RandomDouble()) {
|
||||||
direction = Reflect(unit_direction, rec.normal)
|
direction = Reflect(unit_direction, rec.normal)
|
||||||
|
@ -597,56 +603,77 @@ func (cam *Camera) Pixel_sample_square() Vec3 {
|
||||||
|
|
||||||
// =============== MAIN =====================
|
// =============== MAIN =====================
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// Materials
|
|
||||||
material_ground := NewMaterial(0, NewColor(0.8, 0.8, 0.0), 0.0, 0.0)
|
|
||||||
material_center := NewMaterial(0, NewColor(0.1, 0.2, 0.5), 0.0, 0.0)
|
|
||||||
material_left := NewMaterial(2, NewColor(1.0, 1.0, 1.0), 0.0, 1.5)
|
|
||||||
material_right := NewMaterial(1, NewColor(0.8, 0.6, 0.2), 0.0, 0.0)
|
|
||||||
|
|
||||||
// World
|
|
||||||
|
|
||||||
world := NewHittable()
|
world := NewHittable()
|
||||||
|
|
||||||
|
groundMaterial := NewMaterial(0, NewColor(0.5, 0.5, 0.5), 0.0, 0.0)
|
||||||
world.Add(Sphere{
|
world.Add(Sphere{
|
||||||
center: NewVec3(0.0, -100.5, -1.0),
|
center: NewVec3(0, -1000, 0),
|
||||||
radius: 100.0,
|
radius: 1000,
|
||||||
mat: material_ground,
|
mat: groundMaterial,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
for a := -11; a < 11; a++ {
|
||||||
|
for b := -11; b < 11; b++ {
|
||||||
|
chooseMat := RandomDouble()
|
||||||
|
center := NewVec3(float32(a)+0.9*RandomDouble(), 0.2, float32(b)+0.9*RandomDouble())
|
||||||
|
|
||||||
|
if (center.Sub(NewVec3(4, 0.2, 0)).Length() > 0.9) {
|
||||||
|
var sphereMaterial Material
|
||||||
|
|
||||||
|
if chooseMat < 0.8 {
|
||||||
|
// diffuse
|
||||||
|
albedo := RandomVec3().MultVec(RandomVec3())
|
||||||
|
sphereMaterial = NewMaterial(0, albedo, 0.0, 0.0)
|
||||||
|
} else if chooseMat < 0.95 {
|
||||||
|
// metal
|
||||||
|
albedo := RandomVec3(0.5, 1)
|
||||||
|
fuzz := RandomDoubleInRange(0, 0.5)
|
||||||
|
sphereMaterial = NewMaterial(1, albedo, fuzz, 0.0)
|
||||||
|
} else {
|
||||||
|
// glass
|
||||||
|
sphereMaterial = NewMaterial(2, NewColor(1.0, 1.0, 1.0), 0.0, 1.5)
|
||||||
|
}
|
||||||
|
world.Add(Sphere{
|
||||||
|
center: center,
|
||||||
|
radius: 0.2,
|
||||||
|
mat: sphereMaterial,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
material1 := NewMaterial(2, NewColor(1.0, 1.0, 1.0), 0.0, 1.5)
|
||||||
world.Add(Sphere{
|
world.Add(Sphere{
|
||||||
center: NewVec3(0, 0, -1),
|
center: NewVec3(0, 1, 0),
|
||||||
radius: 0.5,
|
radius: 1.0,
|
||||||
mat: material_center,
|
mat: material1,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
material2 := NewMaterial(0, NewColor(0.4, 0.2, 0.1), 0.0, 0.0)
|
||||||
world.Add(Sphere{
|
world.Add(Sphere{
|
||||||
center: NewVec3(-1, 0, -1),
|
center: NewVec3(-4, 1, 0),
|
||||||
radius: 0.5,
|
radius: 1.0,
|
||||||
mat: material_left,
|
mat: material2,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
material3 := NewMaterial(1, NewColor(0.7, 0.6, 0.5), 0.0, 0.0)
|
||||||
world.Add(Sphere{
|
world.Add(Sphere{
|
||||||
center: NewVec3(-1, 0, -1),
|
center: NewVec3(4, 1, 0),
|
||||||
radius: -0.4,
|
radius: 1.0,
|
||||||
mat: material_left,
|
mat: material3,
|
||||||
})
|
})
|
||||||
world.Add(Sphere{
|
|
||||||
center: NewVec3(1.0, 0, -1.0),
|
|
||||||
radius: 0.5,
|
|
||||||
mat: material_right,
|
|
||||||
})
|
|
||||||
// Image
|
|
||||||
|
|
||||||
cam := NewCamera()
|
cam := NewCamera()
|
||||||
cam.aspect_ratio = 16.0 / 9.0
|
cam.aspect_ratio = 16.0 / 9.0
|
||||||
cam.image_width = 400
|
cam.image_width = 1200
|
||||||
cam.samples_per_pixel = 100
|
cam.samples_per_pixel = 200
|
||||||
cam.max_depth = 50
|
cam.max_depth = 45
|
||||||
cam.vfov = 20
|
cam.vfov = 20
|
||||||
cam.lookfrom = NewVec3(-2,2,1)
|
cam.lookfrom = NewVec3(13, 2, 3)
|
||||||
cam.lookat = NewVec3(0,0,-1)
|
cam.lookat = NewVec3(0, 0, 0)
|
||||||
cam.vup = NewVec3(0,1,0)
|
cam.vup = NewVec3(0, 1, 0)
|
||||||
cam.defocus_angle = 10.0
|
cam.defocus_angle = 0.6
|
||||||
cam.focus_dist = 3.4
|
cam.focus_dist = 10.0
|
||||||
|
|
||||||
cam.Render(world)
|
cam.Render(world)
|
||||||
// INFO: The pixels are written out in rows.
|
}
|
||||||
// Image file can be created with
|
|
||||||
// go run main.go > image.ppm
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue