Camera struct
This commit is contained in:
parent
93ff66ada9
commit
218a0340bc
1 changed files with 81 additions and 57 deletions
138
main.go
138
main.go
|
@ -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
|
||||
}
|
Loading…
Reference in a new issue