Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
fogleman committed Sep 3, 2016
1 parent cc4c8cf commit a5bc73a
Showing 2 changed files with 38 additions and 32 deletions.
47 changes: 29 additions & 18 deletions pt/buffer.go
Original file line number Diff line number Diff line change
@@ -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
23 changes: 9 additions & 14 deletions pt/render.go
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit a5bc73a

Please sign in to comment.