def intersect(self, ray, intersection): """Compute an intersection.""" w2p = self.world_to_primitive.interpolate(ray.time) ray_primitive = w2p(ray) intersection = Intersection() if not self.primitive.intersect(ray_primitive, intersection): return False ray.maxt = ray_primitive.maxt intersection.primitive_id = self.primitive_id if not w2p.is_identity(): # Compute world-to-object transformation for instance intersection.world_to_object = intersection.world_to_object * w2p intersection.object_to_world = inverse( intersection.world_to_object) p2w = inverse(w2p) # Transform instance's differential geometry to world space intersection.dg.p = p2w(intersection.dg.p) intersection.dg.nn = normalize(p2w(intersection.dg.nn)) intersection.dg.dpdu = p2w(intersection.dg.dp_du) intersection.dg.dpdv = p2w(intersection.dg.dp_dv) intersection.dg.dndu = p2w(intersection.dg.dn_du) intersection.dg.dndv = p2w(intersection.dg.dn_dv) return True
def test_intersect(self): # test an intersection ray = Ray(Point(0, 0, 10), Vector(0, 0, -1)) intersection = Intersection() intersected = self.grid_accel.intersect(ray, intersection) self.assertFalse(intersected) ray.maxt = float('inf') intersected = self.grid_accel.intersect_p(ray) self.assertFalse(intersected) # test an intersection ray2 = Ray(Point(10, 0, 10), Vector(0, 0, -1)) intersection = Intersection() intersected = self.grid_accel.intersect(ray2, intersection) self.assertTrue(intersected) self.assertEqual(intersection.primitive_id, self.primitive_sphere1.primitive_id) self.assertEqual(intersection.shape_id, self.sphere1.shape_id) ray2.maxt = float('inf') intersected = self.grid_accel.intersect_p(ray2) self.assertTrue(intersected) # test an intersection ray3 = Ray(Point(-10, 0, 10), Vector(0, 0, -1)) intersection = Intersection() intersected = self.grid_accel.intersect(ray3, intersection) self.assertTrue(intersected) self.assertEqual(intersection.primitive_id, self.primitive_sphere2.primitive_id) self.assertEqual(intersection.shape_id, self.sphere2.shape_id) ray3.maxt = float('inf') intersected = self.grid_accel.intersect_p(ray3) self.assertTrue(intersected)
def get_intersection(self, ray: Ray, intersection: Intersection) -> bool: hit, thit = self.shape.get_intersection(ray, intersection.differentialGeometry) if not hit: return False intersection.primitive = self intersection.WorldToObject = self.shape.objectToWorld intersection.ObjectToWorld = self.shape.objectToWorld ray.max_t = thit return True
def get_intersection(self, ray: Ray, intersection: Intersection) -> bool: # Refine primitives in voxel if needed if not self.allCanIntersect: for i in range(len(self.primitives)): prim = self.primitives[i] # Refine primitive _prim_ if it's not intersectable if not prim.get_can_intersect(): prims = [] prim.get_fully_refine(prims) assert len(prims) > 0 if len(prims) == 1: self.primitives[i] = prims[0] else: self.primitives[i] = UniformGrid(prims, False) self.allCanIntersect = True # Loop over primitives in voxel and find intersections hitSomething = False intersection_tmp = Intersection() for prim in self.primitives: if prim.get_intersection(ray, intersection_tmp): intersection.differentialGeometry.point = intersection_tmp.differentialGeometry.point intersection.differentialGeometry.normal = intersection_tmp.differentialGeometry.normal intersection.differentialGeometry.shape = intersection_tmp.differentialGeometry.shape intersection.primitive=intersection_tmp.primitive hitSomething = True return hitSomething
def Li(self, scene: Scene, renderer: Renderer, ray: Ray, intersection: Intersection, sample: Sample)->Spectrum: occlusion = 0 intersection.ray_epsilon = infinity_max_f bsdf = intersection.get_bsdf(ray) p = bsdf.dgShading.point n = maths.tools.get_face_forward(intersection.differentialGeometry.normal, -ray.direction) for i in range(self.samples_count): w = maths.tools.get_uniform_sample_sphere(random(), random()) if Vector3d.dot(w, n) < 0.0: w = -w r = Ray(p, w, 0.01, self.max_distance) if scene.get_is_intersected(r): occlusion += 1 return Spectrum(1.0-(float(occlusion) / float(self.samples_count)))
def intersect(self, ray, intersection): """Compute an intersection.""" w2p = self.world_to_primitive.interpolate(ray.time) ray_primitive = w2p(ray) intersection = Intersection() if not self.primitive.intersect(ray_primitive, intersection): return False ray.maxt = ray_primitive.maxt intersection.primitive_id = self.primitive_id if not w2p.is_identity(): # Compute world-to-object transformation for instance intersection.world_to_object = intersection.world_to_object * w2p intersection.object_to_world = inverse(intersection.world_to_object) p2w = inverse(w2p) # Transform instance's differential geometry to world space intersection.dg.p = p2w(intersection.dg.p) intersection.dg.nn = normalize(p2w(intersection.dg.nn)) intersection.dg.dpdu = p2w(intersection.dg.dp_du) intersection.dg.dpdv = p2w(intersection.dg.dp_dv) intersection.dg.dndu = p2w(intersection.dg.dn_du) intersection.dg.dndv = p2w(intersection.dg.dn_dv) return True
def Li(self, scene: Scene, renderer: Renderer, ray: Ray, intersection: Intersection, sample: Sample) -> Spectrum: L = Spectrum(0.0) wo = -ray.direction bsdf = intersection.get_bsdf(ray) # Compute emitted light if ray hit an area light source L += intersection.Le(wo) if len(scene.lights) > 0: if self.strategy == LightStrategy.SAMPLE_ALL_UNIFORM: L += UniformSampleAllLights(scene, renderer, intersection.differentialGeometry.point, intersection.differentialGeometry.normal, wo, ray.time, bsdf, sample, self.lightSampleOffsets, self.bsdfSampleOffsets) elif self.strategy == LightStrategy.SAMPLE_ONE_UNIFORM: L += UniformSampleOneLight(scene, renderer, intersection.differentialGeometry.point, intersection.differentialGeometry.normal, wo, ray.time, bsdf, sample, self.lightSampleOffsets, self.bsdfSampleOffsets, self.lightNumOffset) return L
def Li(self, scene, ray, sample, rng, intersection=None, T=None): """Compute the incident radiance along a given ray.""" # allocate local variables for isect and T if needed if not T: T = Spectrum(0.0) if not intersection: intersection = Intersection() Li = Spectrum(0.0) hit = scene.intersect(ray, intersection) if hit: Li = self.surface_integrator.Li(scene, self, ray, intersection, sample, rng) else: # handle ray that doesn't intersect any geometry for light in scene.lights: Li += light.Le(ray) # Lvi = self.volume_integrator.Li(scene, self, ray, sample, rng, T) # return T * Li + Lvi, intersection return Li, intersection, T
def run(self): """Execute the task.""" print "executing task %d/%d" % (self.task_num, self.task_count) # get sub-sampler for SamplerRendererTask sampler = self.main_sampler.get_sub_sampler(self.task_num, self.task_count) if not sampler: return # Declare local variables used for rendering loop rng = RNG(self.task_num) # allocate space for samples and intersections max_samples = sampler.maximum_sample_count() samples = self.orig_sample.duplicate(max_samples) rays = [None] * max_samples Ls = [None] * max_samples Ts = [None] * max_samples isects = [] # Intersection[max_samples] for i in range(max_samples): isects.append(Intersection()) # get samples from Sampler and update image while True: sample_count = sampler.get_more_samples(samples, rng) # if no more samples to compute, exit if sample_count <= 0: break # generate camera rays and compute radiance along rays for i in range(sample_count): # find camera ray for samples[i] ray_weight, ray_diff = self.camera.generate_ray_differential( samples[i]) rays[i] = ray_diff coeff = 1.0 / math.sqrt(sampler.samples_per_pixel) ray_diff.scale_differentials(coeff) # evaluate radiance along camera ray if ray_weight > 0.0: radiance, intersection, Ts_i = \ self.renderer.Li(self.scene, ray_diff, samples[i], rng, isects[i]) Ls_i = ray_weight * radiance else: Ls_i = Spectrum(0.0) Ts_i = Spectrum(1.0) Ls[i] = Ls_i Ts[i] = Ts_i # check for unexpected radiance values if Ls_i.has_nan(): logger.error( "Not-a-number radiance value returned for image sample. Setting to black." ) Ls_i = Spectrum(0.0) elif Ls_i.y() < -1e-5: logger.error( "Negative luminance value, %f, returned for image sample. Setting to black." % Ls_i.y()) Ls_i = Spectrum(0.0) elif Ls_i.y() == float('inf'): logger.error( "Infinite luminance value returned for image sample. Setting to black." ) Ls_i = Spectrum(0.0) # report sample results to Sampler, add contributions to image if sampler.report_results(samples, rays, Ls, isects, sample_count): for i in range(sample_count): self.camera.film.add_sample(samples[i], Ls[i]) # clean up after SamplerRendererTask is done with its image region pass