def createRay(self, vertex): '''Create a ray from light position to the vertex. Return the ray if the vertex is reachable only''' ray = Ray(self.position, vertex) ray.intersect(self.segments) if ray.vertex_reached: #if ray.vertex_point is not None: #if ray.reachable: return ray return None
def hard_shadow(ph, objects, l, dist_l): """ Determines if this point should have a shadow for the light in pl. Args: ph: 3D Point of hit objects([Object]): list of objects that can be between the point and the light l(numpy.array): unit vector pointing to the light dist_l(float): distance to the light Returns: numpy.array: The calculated color for this hard shadow (RGB) """ # Case outside of cone in SpotLight if np.array_equal(l, np.zeros(3)): return np.zeros(3) shadow_coef = 0 r = Ray(ph, l) for obj in objects: # Cast ray from ph to the object with n = l and shadow if t < dist_l t = r.intersect(obj) if 0 < t < dist_l: shadow_coef = 1 break shadow_color = np.zeros(3) # Use SHADOW_STRENGTH = 0 for no shadows and 1 for hard shadows shadow_coef *= max(0.0, min(SHADOW_STRENGTH, 1.0)) color = COLOR_FOR_LIGHT * (1 - shadow_coef) + shadow_color * shadow_coef return color
def in_scattering(self, r, view_samples=IN_SCATTER_SAMPLES): dist_to_atmosphere = r.intersect(self.atmosphere_obj) transmittance = 0 for i in range(view_samples): distance = (dist_to_atmosphere / view_samples) * i sample_point = r.at(distance) sun_ray = Ray(sample_point, self.sun_direction) t_to_atmosphere = sun_ray.intersect(self.atmosphere_obj) t_to_planet = sun_ray.intersect(self.planet_obj) if 0 < t_to_planet < t_to_atmosphere: continue out_sun = self.out_scattering(sun_ray.pr, sun_ray.nr, t_to_atmosphere) out_view = self.out_scattering(sample_point, -r.nr, distance) current_density = self.density_at_point(sample_point) segment_distance = dist_to_atmosphere / view_samples transmittance += (current_density * np.exp(-(out_sun + out_view)) * segment_distance) light = (SUNLIGHT * SCATTERING_COEFFICIENTS * transmittance) return light
class RayTestCase(unittest.TestCase): def setUp(self): pr = np.array([0, 0, 1]) nr = np.array([0, 0, 1]) self.ray = Ray(pr, nr) def test_intersect_sphere(self): # case there is intersection sphere_position = np.array([0, 0, 4]) material = None radius = 1 sphere = Sphere(sphere_position, material, SHADER_TYPE, radius) t = self.ray.intersect(sphere) self.assertEqual(t, 2) # cases object is behind sphere_position = np.array([0, 0, -4]) material = None radius = 2 sphere = Sphere(sphere_position, material, SHADER_TYPE, radius) t = self.ray.intersect(sphere) self.assertEqual(t, -1) sphere_position = np.array([3, 24, -1]) material = None radius = 0.4 sphere = Sphere(sphere_position, material, SHADER_TYPE, radius) t = self.ray.intersect(sphere) self.assertEqual(t, -1) # case is not in the ray line sphere_position = np.array([-3.3, 12.6, 5.2]) material = None radius = 0.4 sphere = Sphere(sphere_position, material, SHADER_TYPE, radius) t = self.ray.intersect(sphere) self.assertEqual(t, -1) def test_intersect_hollow_sphere(self): # case there is intersection position = np.array([0, 0, 0]) material = None radius = 3 sphere = HollowSphere(position, material, SHADER_TYPE, radius) t = self.ray.intersect(sphere) self.assertEqual(t, 2) # cases object is behind position = np.array([0, 0, -4]) radius = 4 sphere = HollowSphere(position, material, SHADER_TYPE, radius) t = self.ray.intersect(sphere) self.assertEqual(t, -1) position = np.array([3, 24, -1]) radius = 0.4 sphere = HollowSphere(position, material, SHADER_TYPE, radius) t = self.ray.intersect(sphere) self.assertEqual(t, -1) # case is not in the ray line position = np.array([-3.3, 12.6, 5.2]) radius = 0.4 sphere = HollowSphere(position, material, SHADER_TYPE, radius) t = self.ray.intersect(sphere) self.assertEqual(t, -1) def test_intersect_plane(self): # Case there is intersection p0 = np.array([0, 0, 3]) n = np.array([0, 0, -1]) n0 = np.array([1, 0, 0]) material = None plane = Plane(p0, material, SHADER_TYPE, n, n0) t = self.ray.intersect(plane) self.assertEqual(t, 2) # Case there is not because it's parallel to the ray p0 = np.array([0, -1, 0]) n = np.array([0, 1, 0]) plane = Plane(p0, material, SHADER_TYPE, n, n0) t = self.ray.intersect(plane) self.assertEqual(t, -1) # Case there is not because it is behind p0 = np.array([0, 0, -1]) n = np.array([0, 0, 1]) plane = Plane(p0, material, SHADER_TYPE, n, n0) t = self.ray.intersect(plane) self.assertEqual(t, -1) def test_at(self): self.assertTrue(np.array_equal(self.ray.at(2), np.array([0, 0, 3])))