git.haldean.org monte / ee98ab3
Add monte carlo antialiasing and configurable sky color Will Brown 9 years ago
4 changed file(s) with 55 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
2424 Look: monte.NewRay(monte.Vect(0, 0, 0), monte.Vect(0, 0, 1)),
2525 U1: monte.Vect(1, 0, 0),
2626 U2: monte.Vect(0, 1, 0),
27 FDist: 1}
27 FDist: 1,
28 Sky: monte.NewColor(0, 200, 255, 255),
29 Oversample: 8,
30 }
2831
2932 img := image.NewNRGBA(image.Rect(0, 0, *Width, *Height))
30 w, h := float64(*Width), float64(*Height)
31 for i := 0; i < *Width; i++ {
32 u := (float64(i) - w / 2.0) / (w / 2.0)
33 for j := 0; j < *Height; j++ {
34 v := (float64(j) - h / 2.0) / (h / 2.0)
35 go scene.SetColor(i, j, u, v, img)
36 }
37 }
33 scene.Render(img)
3834
3935 out, err := os.Create(*Output)
4036 if err != nil {
33 "image"
44 "image/color"
55 "math"
6 "math/rand"
67 )
78
8 func NewColor(r, g, b, a uint8) color.Color {
9 func NewColor(r, g, b, a uint8) color.NRGBA {
910 return color.NRGBA{R: r, G: g, B: b, A: a}
1011 }
1112
1617 // scan to fill in the picture
1718 U1, U2 *Vector
1819 FDist float64
20 Sky color.NRGBA
21 Oversample int
1922 }
2023
2124 func (s *Scene) DirectionAt(u, v float64) *Vector {
2427 }
2528
2629 func (s *Scene) ColorAt(u, v float64) color.Color {
27 ray := NewRay(s.Look.Origin, s.DirectionAt(u, v))
30 var r, g, b, n int32 = 0, 0, 0, 0
31 sr, sg, sb := s.Sky.R, s.Sky.G, s.Sky.B
2832
29 minDist := math.Inf(1)
30 var minGeom *Primitive = nil
33 for i := 0; i < s.Oversample; i++ {
34 du := (rand.Float64() - 0.5) / 200
35 dv := (rand.Float64() - 0.5) / 200
36 ray := NewRay(s.Look.Origin, s.DirectionAt(u+du, v+dv))
3137
32 for _, geom := range s.Geom {
33 i, d := geom.Intersect(ray)
34 if i != nil && d < minDist {
35 minDist = d
36 minGeom = &geom
38 minDist := math.Inf(1)
39 var minGeom *Primitive = nil
40
41 for _, geom := range s.Geom {
42 i, d := geom.Intersect(ray)
43 if i != nil && d < minDist {
44 minDist = d
45 minGeom = &geom
46 }
3747 }
48
49 if minGeom != nil {
50 r += 255
51 g += 255
52 b += 255
53 } else {
54 r += int32(sr)
55 g += int32(sg)
56 b += int32(sb)
57 }
58 n++
3859 }
39
40 if minGeom != nil {
41 return NewColor(255, 255, 255, 255)
42 }
43 return NewColor(0, 0, 0, 255)
60 return NewColor(uint8(r / n), uint8(g / n), uint8(b / n), 255)
4461 }
4562
4663 func (s *Scene) SetColor(i, j int, u, v float64, img *image.NRGBA) {
4764 img.Set(i, j, s.ColorAt(u, v))
4865 }
66
67 func (s *Scene) Render(img *image.NRGBA) {
68 rect := img.Bounds()
69 w, h := float64(rect.Dx()), float64(rect.Dy())
70 i_max, j_max := rect.Dx(), rect.Dy()
71 for i := 0; i < i_max; i++ {
72 u := (float64(i) - w / 2.0) / (w / 2.0)
73 for j := 0; j < j_max; j++ {
74 // (h / w) term is needed to correct for nonunity aspect ratios
75 v := (float64(j) - h / 2.0) / (h / 2.0) * (h / w)
76 go s.SetColor(i, j, u, v, img)
77 }
78 }
79 }
4141 }
4242
4343 func (s Sphere) Normal(loc *Vector) *Vector {
44 return Vect(0, 0, 0)
44 return loc.Sub(s.Center).NormalizeInPlace()
4545 }
1313
1414 func (v *Vector) Add(w *Vector) *Vector {
1515 return &Vector{X: v.X + w.X, Y: v.Y + w.Y, Z: v.Z + w.Z}
16 }
17
18 func (v *Vector) Sub(w *Vector) *Vector {
19 return &Vector{X: v.X - w.X, Y: v.Y - w.Y, Z: v.Z - w.Z}
1620 }
1721
1822 func (v *Vector) Copy() *Vector {