func BloomFilter(img [][]geometry.Vec3, depth int) [][]geometry.Vec3 { data := make([][]geometry.Vec3, len(img)) for i, _ := range data { data[i] = make([]geometry.Vec3, len(img[0])) } const box_width = 2 factor := geometry.Float(1.0 / math.Pow(2*box_width+1, 2)) source := img for iteration := 0; iteration < depth; iteration++ { for y := box_width; y < len(img)-box_width; y++ { for x := box_width; x < len(img[0])-box_width; x++ { var colour geometry.Vec3 for dy := -box_width; dy <= box_width; dy++ { for dx := -box_width; dx <= box_width; dx++ { colour.AddInPlace(source[y+dy][x+dx]) } } data[y][x] = colour.Mult(factor) } } fmt.Printf("\rPost Processing %3.0f%% \r", 100*float64(iteration)/float64(depth)) source, data = data, source } return source }
func MonteCarloPixel(results chan Result, scene *geometry.Scene, diffuseMap /*, causticsMap*/ *kd.KDNode, start, rows int, rand *rand.Rand) { samples := Config.NumRays var px, py, dy, dx geometry.Float var direction, contribution geometry.Vec3 for y := start; y < start+rows; y++ { py = scene.Height - scene.Height*2*geometry.Float(y)/geometry.Float(scene.Rows) for x := 0; x < scene.Cols; x++ { px = -scene.Width + scene.Width*2*geometry.Float(x)/geometry.Float(scene.Cols) var colourSamples geometry.Vec3 if x >= Config.Skip.Left && x < scene.Cols-Config.Skip.Right && y >= Config.Skip.Top && y < scene.Rows-Config.Skip.Bottom { for sample := 0; sample < samples; sample++ { dy, dx = geometry.Float(rand.Float32())*scene.PixH, geometry.Float(rand.Float32())*scene.PixW direction = geometry.Vec3{ px + dx - scene.Camera.Origin.X, py + dy - scene.Camera.Origin.Y, -scene.Camera.Origin.Z, }.Normalize() contribution = Radiance(geometry.Ray{scene.Camera.Origin, direction}, scene, diffuseMap /*causticsMap,*/, 0, 1.0, rand) colourSamples.AddInPlace(contribution) } } results <- Result{x, y, colourSamples.Mult(1.0 / geometry.Float(samples))} } } }
func EmitterSampling(point, normal geometry.Vec3, shapes []*geometry.Shape, rand *rand.Rand) geometry.Vec3 { incomingLight := geometry.Vec3{0, 0, 0} for _, shape := range shapes { if !shape.Emission.IsZero() { // It's a light source direction := shape.NormalDir(point).Mult(-1) u := direction.Cross(normal).Normalize().Mult(geometry.Float(rand.NormFloat64() * 0.3)) v := direction.Cross(u).Normalize().Mult(geometry.Float(rand.NormFloat64() * 0.3)) direction.X += u.X + v.X direction.Y += u.Y + v.Y direction.Z += u.Z + v.Z ray := geometry.Ray{point, direction.Normalize()} if object, distance := ClosestIntersection(shapes, ray); object == shape { incomingLight.AddInPlace(object.Emission.Mult(direction.Dot(normal) / (1 + distance))) } } } return incomingLight }