Пример #1
0
func trace(root []scene.Primitive, ambient glm.Vec3, ray, origin *glm.Vec3, lights []scene.Light, depth int) (*glm.Vec3, bool) {
	if hit, node, raylen, normal := intersectNodes(root, ray, origin); hit {
		// ambient silhouette
		mat := root[node].GetMaterial()
		colour := glm.NewVec3(ambient.Elem[0]*mat.Ambient.Elem[0], ambient.Elem[1]*mat.Ambient.Elem[1], ambient.Elem[2]*mat.Ambient.Elem[2])
		// setup for casting secondary (shadow) rays.
		intersection := origin.Add(ray.Scale(raylen))
		diffuse := glm.Vec3{}
		specular := glm.Vec3{}
		ray.Normalize()
		normal.Normalize()

		// cast shadow ray.
		for _, light := range lights {
			shadow_ray := light.Pos.Subtract(intersection)
			if hit, _, _, _ = intersectNodes(root, shadow_ray, intersection); !hit {
				shadow_ray.Normalize()
				// add diffuse/specular components.
				diffuse_coef := normal.Dot(shadow_ray)
				if diffuse_coef > 0.00001 {
					fmt.Println(diffuse_coef)
					diffuse_tmp := mat.Diffuse.Scale(diffuse_coef)
					diffuse.Iadd(glm.NewVec3(diffuse_tmp.Elem[0]*light.Colour.Elem[0], diffuse_tmp.Elem[1]*light.Colour.Elem[1], diffuse_tmp.Elem[2]*light.Colour.Elem[2]))
				}
				reflected_shadow_ray := shadow_ray.Subtract(normal.Scale(2 * diffuse_coef))
				specular_coef := math.Abs(math.Pow(reflected_shadow_ray.Dot(ray), mat.Shininess))
				if specular_coef > 0.00001 {
					specular_tmp := mat.Specular.Scale(specular_coef)
					specular.Iadd(glm.NewVec3(specular_tmp.Elem[0]*light.Colour.Elem[0], specular_tmp.Elem[1]*light.Colour.Elem[1], specular_tmp.Elem[2]*light.Colour.Elem[2]))
				}
			}
		}
		colour.Iadd(&diffuse).Iadd(&specular)
		// cast reflectance ray.
		if REFLECTIONS {
			reflected := ray.Subtract(normal.Scale(2 * normal.Dot(ray)))
			if depth < MAX_DEPTH {
				if reflected_color, hit := trace(root, ambient, reflected, intersection, lights, depth+1); hit {
					colour.Iscale(1 - mat.Mirror).Iadd(reflected_color.Scale(mat.Mirror))
				}
			}
		}
		return colour, true
	}
	return &glm.Vec3{}, false
}
Пример #2
0
func same_side(a, b, c, test glm.Vec3) bool {
	t := b.Subtract(&a)
	return t.Cross(test.Subtract(&a)).Dot(t.Cross(c.Subtract(&a))) > Epsilon
}