Beispiel #1
0
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
}
Beispiel #2
0
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))}
		}
	}
}
Beispiel #3
0
func DiffusePhoton(scene []*geometry.Shape, emitter *geometry.Shape, ray geometry.Ray, colour geometry.Vec3, result chan<- PhotonHit, alpha geometry.Float, depth int, rand *rand.Rand) {
	if geometry.Float(rand.Float32()) > alpha {
		return
	}
	if shape, distance := ClosestIntersection(scene, ray); shape != nil {
		impact := ray.Origin.Add(ray.Direction.Mult(distance))

		if depth == 0 && emitter == shape {
			// Leave the emitter first
			nextRay := geometry.Ray{impact, ray.Direction}
			DiffusePhoton(scene, emitter, nextRay, colour, result, alpha, depth, rand)
		} else {
			normal := shape.NormalDir(impact).Normalize()
			reverse := ray.Direction.Mult(-1)
			outgoing := normal
			if normal.Dot(reverse) < 0 {
				outgoing = normal.Mult(-1)
			}
			strength := colour.Mult(alpha / (1 + distance))
			result <- PhotonHit{impact, strength, ray.Direction, uint8(depth)}

			if shape.Material == geometry.DIFFUSE {
				// Random bounce for color bleeding
				u := normal.Cross(reverse).Normalize().Mult(geometry.Float(rand.NormFloat64() * 0.5))
				v := u.Cross(normal).Normalize().Mult(geometry.Float(rand.NormFloat64() * 0.5))
				bounce := geometry.Vec3{
					u.X + outgoing.X + v.X,
					u.Y + outgoing.Y + v.Y,
					u.Z + outgoing.Z + v.Z,
				}
				bounceRay := geometry.Ray{impact, bounce.Normalize()}
				bleedColour := colour.MultVec(shape.Colour).Mult(alpha / (1 + distance))
				DiffusePhoton(scene, shape, bounceRay, bleedColour, result, alpha*0.66, depth+1, rand)
			}
			// Store Shadow Photons
			shadowRay := geometry.Ray{impact, ray.Direction}
			DiffusePhoton(scene, shape, shadowRay, geometry.Vec3{0, 0, 0}, result, alpha*0.66, depth+1, rand)
		}
	}
}