From a5bc73a1f76a904d63c05219727397f9726fc2a8 Mon Sep 17 00:00:00 2001 From: Michael Fogleman Date: Fri, 2 Sep 2016 20:41:47 -0400 Subject: [PATCH] refactor --- pt/buffer.go | 47 +++++++++++++++++++++++++++++------------------ pt/render.go | 23 +++++++++-------------- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/pt/buffer.go b/pt/buffer.go index fd8216e..97fa2ab 100644 --- a/pt/buffer.go +++ b/pt/buffer.go @@ -2,14 +2,21 @@ package pt import "image" +type Channel int + +const ( + ColorChannel = iota + VarianceChannel + StandardDeviationChannel +) + type Pixel struct { Samples int - C, M, V Color + M, V Color } func (p *Pixel) AddSample(sample Color) { p.Samples++ - p.C = p.C.Add(sample) if p.Samples == 1 { p.M = sample return @@ -20,19 +27,22 @@ func (p *Pixel) AddSample(sample Color) { } func (p *Pixel) Color() Color { - return p.C.DivScalar(float64(p.Samples)) + return p.M } func (p *Pixel) Variance() Color { if p.Samples < 2 { return Black } - return p.V.DivScalar(float64(p.Samples - 1)).Pow(0.5) + return p.V.DivScalar(float64(p.Samples - 1)) +} + +func (p *Pixel) StandardDeviation() Color { + return p.Variance().Pow(0.5) } type Buffer struct { - W int - H int + W, H int Pixels []Pixel } @@ -63,23 +73,24 @@ func (b *Buffer) Variance(x, y int) Color { return b.Pixels[y*b.W+x].Variance() } -func (b *Buffer) Image() image.Image { - result := image.NewRGBA64(image.Rect(0, 0, b.W, b.H)) - for y := 0; y < b.H; y++ { - for x := 0; x < b.W; x++ { - c := b.Pixels[y*b.W+x].Color().Pow(1 / 2.2) - result.SetRGBA64(x, y, c.RGBA64()) - } - } - return result +func (b *Buffer) StandardDeviation(x, y int) Color { + return b.Pixels[y*b.W+x].StandardDeviation() } -func (b *Buffer) VarianceImage() image.Image { +func (b *Buffer) Image(channel Channel) image.Image { result := image.NewRGBA64(image.Rect(0, 0, b.W, b.H)) for y := 0; y < b.H; y++ { for x := 0; x < b.W; x++ { - c := b.Pixels[y*b.W+x].Variance().MaxComponent() - result.SetRGBA64(x, y, Color{c, c, c}.RGBA64()) + var c Color + switch channel { + case ColorChannel: + c = b.Pixels[y*b.W+x].Color().Pow(1 / 2.2) + case VarianceChannel: + c = b.Pixels[y*b.W+x].Variance() + case StandardDeviationChannel: + c = b.Pixels[y*b.W+x].StandardDeviation() + } + result.SetRGBA64(x, y, c.RGBA64()) } } return result diff --git a/pt/render.go b/pt/render.go index 896f802..9dc8062 100644 --- a/pt/render.go +++ b/pt/render.go @@ -63,7 +63,7 @@ func render(scene *Scene, camera *Camera, sampler Sampler, samplesPerPixel int, } } } - v := Clamp(buf.Variance(x, y).MaxComponent(), 0, 1) + v := Clamp(buf.StandardDeviation(x, y).MaxComponent(), 0, 1) v = math.Pow(v, 2) extraSamples := int(64 * v) for i := 0; i < extraSamples; i++ { @@ -86,14 +86,9 @@ func render(scene *Scene, camera *Camera, sampler Sampler, samplesPerPixel int, fmt.Println() } -func writeImage(path string, buf *Buffer, wg *sync.WaitGroup, variance bool) { +func writeImage(path string, buf *Buffer, channel Channel, wg *sync.WaitGroup) { defer wg.Done() - var im image.Image - if variance { - im = buf.VarianceImage() - } else { - im = buf.Image() - } + im := buf.Image(channel) if err := SavePNG(path, im); err != nil { panic(err) } @@ -102,7 +97,7 @@ func writeImage(path string, buf *Buffer, wg *sync.WaitGroup, variance bool) { func Render(scene *Scene, camera *Camera, sampler Sampler, w, h, samplesPerPixel int) image.Image { buf := NewBuffer(w, h) render(scene, camera, sampler, samplesPerPixel, buf) - return buf.Image() + return buf.Image(ColorChannel) } func IterativeRender(pathTemplate string, iterations int, scene *Scene, camera *Camera, sampler Sampler, w, h, samplesPerPixel int) image.Image { @@ -118,22 +113,22 @@ func IterativeRender(pathTemplate string, iterations int, scene *Scene, camera * } bufCopy := buf.Copy() wg.Add(1) - go writeImage(path, bufCopy, &wg, false) + go writeImage(path, bufCopy, ColorChannel, &wg) wg.Add(1) - go writeImage("variance.png", bufCopy, &wg, true) + go writeImage("deviation.png", bufCopy, StandardDeviationChannel, &wg) } wg.Wait() - return buf.Image() + return buf.Image(ColorChannel) } -func CallbackRender(scene *Scene, camera *Camera, sampler Sampler, w, h, samplesPerPixel int) <-chan image.Image { +func ChannelRender(scene *Scene, camera *Camera, sampler Sampler, w, h, samplesPerPixel int) <-chan image.Image { ch := make(chan image.Image) go func() { scene.Compile() buf := NewBuffer(w, h) for i := 1; ; i++ { render(scene, camera, sampler, samplesPerPixel, buf) - ch <- buf.Image() + ch <- buf.Image(ColorChannel) } }() return ch