Chapter 4 done :D

This commit is contained in:
Luxdragon 2024-02-03 22:48:01 +01:00
parent 0ae8ad9c8a
commit 5fc728efd6
2 changed files with 90069 additions and 65578 deletions

155538
image.ppm

File diff suppressed because it is too large Load diff

109
main.go
View file

@ -42,26 +42,22 @@ func (v *Vec3) Set(i int, val float32) {
v.E[i] = val
}
func (v *Vec3) Add(v2 Vec3) {
v.E[0] += v2.E[0]
v.E[1] += v2.E[1]
v.E[2] += v2.E[2]
func (v Vec3) Add(v2 Vec3) Vec3 {
return NewVec3(v.E[0]+v2.E[0], v.E[1]+v2.E[1], v.E[2]+v2.E[2])
}
func (v *Vec3) Mult(t float32) {
v.E[0] *= t
v.E[1] *= t
v.E[2] *= t
func (v Vec3) Mult(t float32) Vec3 {
return NewVec3(v.E[0]*t, v.E[1]*t, v.E[2]*t)
}
func (v *Vec3) Div(t float32) {
func (v Vec3) Div(t float32) Vec3 {
if t != 0 {
v.E[0] /= t
v.E[1] /= t
v.E[2] /= t
return NewVec3(v.E[0] / t, v.E[1] / t, v.E[2] / t)
}
return v
}
func (v Vec3) Length() float32 {
return float32(math.Sqrt(float64(v.E[0]*v.E[0] + v.E[1]*v.E[1] + v.E[2]*v.E[2])))
}
@ -72,22 +68,19 @@ func (v Vec3) String() string {
return fmt.Sprintf("%v %v %v", v.E[0], v.E[1], v.E[2])
}
func (v *Vec3) Sub(v2 Vec3) {
v.E[0] -= v2.E[0]
v.E[1] -= v2.E[1]
v.E[2] -= v2.E[2]
func (v Vec3) Sub(v2 Vec3) Vec3 {
return NewVec3(v.E[0]-v2.E[0], v.E[1]-v2.E[1], v.E[2]-v2.E[2])
}
func (v *Vec3) MultVec(v2 Vec3) {
v.E[0] *= v2.E[0]
v.E[1] *= v2.E[1]
v.E[2] *= v2.E[2]
func (v Vec3) MultVec(v2 Vec3) Vec3 {
return NewVec3(v.E[0]*v2.E[0], v.E[1]*v2.E[1], v.E[2]*v2.E[2])
}
func (v *Vec3) DivVec(v2 Vec3) {
v.E[0] /= v2.E[0]
v.E[1] /= v2.E[1]
v.E[2] /= v2.E[2]
func (v Vec3) DivVec(v2 Vec3) Vec3 {
if v2.E[0] != 0 && v2.E[1] != 0 && v2.E[2] != 0 {
return NewVec3(v.E[0]/v2.E[0], v.E[1]/v2.E[1], v.E[2]/v2.E[2])
}
return v
}
func Dot(v1 Vec3, v2 Vec3) float32 {
@ -111,19 +104,25 @@ func Write_color(v Vec3) {
fmt.Println(int(255.999*v.E[0]), int(255.999*v.E[1]), int(255.999*v.E[2]))
}
func NewColor(e0, e1, e2 float32) Vec3 {
return Vec3{E: [3]float32{e0, e1, e2}}
}
// ============== RAY CLASS =================
type Point3 Vec3
func NewPoint3(e0, e1, e2 float32) Vec3 {
return Vec3{E: [3]float32{e0, e1, e2}}
}
type Ray struct {
Orig Point3
Orig Vec3
Dir Vec3
}
func NewRay(orig Point3, dir Vec3) *Ray {
func NewRay(orig Vec3, dir Vec3) *Ray {
return &Ray{Orig: orig, Dir: dir}
}
func (r *Ray) Origin() Point3 {
func (r *Ray) Origin() Vec3 {
return r.Orig
}
@ -131,30 +130,52 @@ func (r *Ray) Direction() Vec3 {
return r.Dir
}
func (r *Ray) At(t float32) Point3 {
return Point3{
X: r.Orig.X + t*r.Dir.X,
Y: r.Orig.Y + t*r.Dir.Y,
Z: r.Orig.Z + t*r.Dir.Z
func (r *Ray) At(t float32) Vec3 {
return Vec3{
E: [3]float32{
r.Orig.X() + t*r.Dir.X(),
r.Orig.Y() + t*r.Dir.Y(),
r.Orig.Z() + t*r.Dir.Z(),
},
}
}
func Ray_color(r *Ray) Vec3 {
unit_direction := Unit_vector(r.Direction())
var a float32 = 0.5*unit_direction.Y() + 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))
}
// =============== MAIN =====================
func main() {
// Image
var aspect_ratio := 16.0 / 9.0;
aspect_ratio := 16.0 / 9.0;
var image_width int = 400;
var image_height int = int(image_width / aspect_ratio)
// Calculate the image height
var image_height int = int(float64(image_width) / aspect_ratio)
if image_height < 1 {
image_height = 1
}
// Camera
var focal_length float32 = 1.0
var viewport_height float32 = 2.0
var viewport_width float32 = viewport_height * float32(image_width/image_height)
camera_center := NewVec3(0,0,0)
// Viewport
var viewport_height := 2.0
var viewport_width := viewport_height * float32(image_width/image_height)
// 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)
// Rendering
//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++ {
@ -169,8 +190,14 @@ func main() {
// ib := int(b * 256)
// fmt.Println(ir, " ", ig, " ", ib)
pixel_colour := NewVec3(float32(i) / float32(image_width - 1), float32(j) / float32(image_height-1), 0)
Write_color(pixel_colour)
//pixel_colour := NewVec3(float32(i) / float32(image_width - 1), float32(j) / float32(image_height-1), 0)
//Write_color(pixel_colour)
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)
Write_color(pixel_color)
}
}
// INFO: The pixels are written out in rows.