Camera struct

This commit is contained in:
Luxdragon 2024-02-27 20:04:26 +01:00
parent 93ff66ada9
commit 218a0340bc

138
main.go
View file

@ -277,75 +277,99 @@ func (hl Hittable) Hit(r *Ray, ray_t Interval, rec *Hit_record) bool {
return hit_anything
}
func Ray_color(r Ray, world *Hittable) Vec3 {
// =============== CAMERA ===================
type Camera struct {
aspect_ratio float32
image_width int
image_height int
center Vec3
pixel00_loc Vec3
pixel_delta_u Vec3
pixel_delta_v Vec3
}
func NewCamera() *Camera {
return &Camera{}
}
func Ray_color(r Ray, world *Hittable) Vec3 {
var rec Hit_record
if (world.Hit(&r, *NewInterval(0, float32(math.Inf(1))), &rec)) {
return rec.normal.Add(NewColor(1,1,1)).Mult(0.5)
}
unit_direction := Unit_vector(r.Direction())
a := (unit_direction.Y() + 1.0)*0.5
return NewColor(1.0,1.0,1.0).Mult(float32(1.0-a)).Add(NewColor(0.5,0.7,1.0).Mult(a))
}
func (cam *Camera) Initialize() {
// Calculate the image height
cam.image_height = int(float32(cam.image_width) / cam.aspect_ratio)
if cam.image_height < 1 {
cam.image_height = 1
}
// Viewport
var focal_length float32 = 1.0
var viewport_height float32 = 2.0
var viewport_width float32 = viewport_height * float32(cam.image_width)/float32(cam.image_height)
cam.center = NewVec3(0,0,0)
// Calculate the vectors across the horizontal and down the vertical viewport edges
viewport_u := NewVec3(viewport_width, 0, 0)
viewport_v := NewVec3(0, -viewport_height, 0)
//Calculate the horizontal and vertical delta vectors from pixel to pixel
cam.pixel_delta_u = viewport_u.Div(float32(cam.image_width))
cam.pixel_delta_v = viewport_v.Div(float32(cam.image_height))
// Calculate the location of the upper left pixel
viewport_upper_left := cam.center.Sub(cam.center).Sub(NewVec3(0, 0, focal_length)).Sub(viewport_u.Div(2)).Sub(viewport_v.Div(2))
cam.pixel00_loc = viewport_upper_left.Add((cam.pixel_delta_u.Add(cam.pixel_delta_v)).Div(2))
}
func (cam *Camera) Render(world *Hittable) {
cam.Initialize()
// Rendering
fmt.Println("P3")
fmt.Println(cam.image_width, " ", cam.image_height, "\n255")
for j := 0; j < cam.image_height; j++ {
fmt.Fprintf(os.Stderr, "\rScanlines remaining: %d ", cam.image_height-j)
for i := 0; i < cam.image_width; i++ {
pixel_center := cam.pixel00_loc.Add(cam.pixel_delta_u.Mult(float32(i))).Add(cam.pixel_delta_v.Mult(float32(j)))
ray_direction := pixel_center.Sub(cam.center)
r := NewRay(cam.center, ray_direction)
pixel_color := Ray_color(*r, world)
Write_color(pixel_color)
}
}
}
// =============== MAIN =====================
func main() {
// World
// Image
aspect_ratio := 16.0 / 9.0;
var image_width int = 400;
world := NewHittable()
world.Add(Sphere{
center: NewVec3(0, 0, -1),
radius: 0.5,
})
world.Add(Sphere{
center: NewVec3(0, -100.5, -1),
radius: 100,
})
// Image
// Calculate the image height
var image_height int = int(float64(image_width) / aspect_ratio)
if image_height < 1 {
image_height = 1
}
// World
world := NewHittable()
world.Add(Sphere{
center: NewVec3(0, 0, -1),
radius: 0.5,
})
world.Add(Sphere{
center: NewVec3(0, -100.5, -1),
radius: 100,
})
cam := NewCamera()
cam.aspect_ratio = 16.0 / 9.0
cam.image_width = 400
// Camera
var focal_length float32 = 1.0
var viewport_height float32 = 2.0
var viewport_width float32 = viewport_height * float32(image_width)/float32(image_height)
camera_center := NewVec3(0,0,0)
// Calculate the vectors across the horizontal and down the vertical viewport edges
viewport_u := NewVec3(viewport_width, 0, 0)
viewport_v := NewVec3(0, -viewport_height, 0)
//Calculate the horizontal and vertical delta vectors from pixel to pixel
pixel_delta_u := viewport_u.Div(float32(image_width))
pixel_delta_v := viewport_v.Div(float32(image_height))
// Calculate the location of the upper left pixel
viewport_upper_left := camera_center.Sub(camera_center).Sub(NewVec3(0, 0, focal_length)).Sub(viewport_u.Div(2)).Sub(viewport_v.Div(2))
pixel00_loc := viewport_upper_left.Add((pixel_delta_u.Add(pixel_delta_v)).Div(2))
// Rendering
fmt.Println("P3")
fmt.Println(image_width, " ", image_height, "\n255")
for j := 0; j < image_height; j++ {
fmt.Fprintf(os.Stderr, "\rScanlines remaining: %d ", image_height-j)
for i := 0; i < image_width; i++ {
pixel_center := pixel00_loc.Add(pixel_delta_u.Mult(float32(i))).Add(pixel_delta_v.Mult(float32(j)))
ray_direction := pixel_center.Sub(camera_center)
r := NewRay(camera_center, ray_direction)
pixel_color := Ray_color(*r, world)
Write_color(pixel_color)
}
}
// INFO: The pixels are written out in rows.
// Image file can be created with
// go run main.go > image.ppm
cam.Render(world)
// INFO: The pixels are written out in rows.
// Image file can be created with
// go run main.go > image.ppm
}