コード例 #1
0
ファイル: photonmapping.go プロジェクト: Nightgunner5/goray
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)
		}
	}
}