Raytracing done :3

This commit is contained in:
Luxdragon 2024-03-10 18:01:37 +01:00
parent 95c7fcaa33
commit 64449e18f7
2 changed files with 809675 additions and 89648 deletions

899204
image.ppm

File diff suppressed because it is too large Load diff

119
main.go
View file

@ -164,7 +164,7 @@ func Reflect(v Vec3, n Vec3) Vec3 {
func Refract(uv, n Vec3, etai_over_etat float32) Vec3 {
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_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)
}
@ -347,6 +347,15 @@ func (s Sphere) Hit_sphere(r *Ray, ray_t *Interval, rec *Hit_record) bool {
return true
}
func NewSphere(center Vec3, radius float32, mat Material) Sphere {
return Sphere{
center: center,
radius: radius,
mat: mat,
}
}
// =============== HITTABLE ==================
type Hittable struct {
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
*attenuation = NewColor(1.0, 1.0, 1.0)
var refraction_ration float32
var refraction_ration float32 = 1.0
if rec.front_face {
refraction_ration = 1.0/mat.ir
refraction_ration /= mat.ir
} else {
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))
sin_theta := float32(math.Sqrt(float64(1.0 - cos_theta*cos_theta)))
var cannot_refract bool
var direction Vec3
if (refraction_ration * sin_theta > 1.0) {
cannot_refract = true
}
cannot_refract := refraction_ration*sin_theta > 1.0
if (cannot_refract || Reflectance(cos_theta, refraction_ration) > RandomDouble()) {
direction = Reflect(unit_direction, rec.normal)
@ -597,56 +603,77 @@ func (cam *Camera) Pixel_sample_square() Vec3 {
// =============== 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()
groundMaterial := NewMaterial(0, NewColor(0.5, 0.5, 0.5), 0.0, 0.0)
world.Add(Sphere{
center: NewVec3(0.0, -100.5, -1.0),
radius: 100.0,
mat: material_ground,
center: NewVec3(0, -1000, 0),
radius: 1000,
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{
center: NewVec3(0, 0, -1),
radius: 0.5,
mat: material_center,
center: NewVec3(0, 1, 0),
radius: 1.0,
mat: material1,
})
material2 := NewMaterial(0, NewColor(0.4, 0.2, 0.1), 0.0, 0.0)
world.Add(Sphere{
center: NewVec3(-1, 0, -1),
radius: 0.5,
mat: material_left,
center: NewVec3(-4, 1, 0),
radius: 1.0,
mat: material2,
})
material3 := NewMaterial(1, NewColor(0.7, 0.6, 0.5), 0.0, 0.0)
world.Add(Sphere{
center: NewVec3(-1, 0, -1),
radius: -0.4,
mat: material_left,
center: NewVec3(4, 1, 0),
radius: 1.0,
mat: material3,
})
world.Add(Sphere{
center: NewVec3(1.0, 0, -1.0),
radius: 0.5,
mat: material_right,
})
// Image
cam := NewCamera()
cam.aspect_ratio = 16.0 / 9.0
cam.image_width = 400
cam.samples_per_pixel = 100
cam.max_depth = 50
cam.image_width = 1200
cam.samples_per_pixel = 200
cam.max_depth = 45
cam.vfov = 20
cam.lookfrom = NewVec3(-2,2,1)
cam.lookat = NewVec3(0,0,-1)
cam.vup = NewVec3(0,1,0)
cam.defocus_angle = 10.0
cam.focus_dist = 3.4
cam.lookfrom = NewVec3(13, 2, 3)
cam.lookat = NewVec3(0, 0, 0)
cam.vup = NewVec3(0, 1, 0)
cam.defocus_angle = 0.6
cam.focus_dist = 10.0
cam.Render(world)
// INFO: The pixels are written out in rows.
// Image file can be created with
// go run main.go > image.ppm
}
}