コード例 #1
0
    def test_bbox_intersect(self):
        b = geo.BBox(geo.Point(1., 1., 1.), geo.Point(2., 2., 2.))
        ray = geo.Ray(geo.Point(0., 0., 0.), geo.Vector(1., 1., 1.))
        hit, t1, t2 = b.intersect_p(ray)
        assert hit
        assert_almost_eq(t1, 1.)
        assert_almost_eq(t2, 2.)

        # ambiguity in this case

        ray = geo.Ray(geo.Point(1. - EPS, 1. - EPS, 0.),
                      geo.Vector(-EPS, -EPS, 1.))
        hit, t1, t2 = b.intersect_p(ray)
        assert not hit
        assert_almost_eq(t1, 0.)
        assert_almost_eq(t2, 0.)

        ray = geo.Ray(geo.Point(1. - EPS, 1. - EPS, 1. - EPS),
                      geo.Vector(-1., -1., -1.))
        hit, t1, t2 = b.intersect_p(ray)
        assert not hit
        assert_almost_eq(t1, 0.)
        assert_almost_eq(t2, 0.)

        ray = geo.Ray(geo.Point(0., 0., 0.), geo.Vector(-1., -1., -1.))
        hit, t1, t2 = b.intersect_p(ray)
        assert not hit
        assert_almost_eq(t1, 0.)
        assert_almost_eq(t2, 0.)
コード例 #2
0
 def test_call_ray(self, pnt, vec):
     ray = geo.Ray(pnt, vec)
     t = Transform()
     r = t(ray)
     assert isinstance(r, geo.Ray)
     assert r.o == ray.o
     assert r.d == ray.d
コード例 #3
0
 def test_ray_differential_from_ray(self, vec, pnt):
     r0 = geo.Ray(pnt, vec)
     r1 = geo.RayDifferential.from_ray(r0)
     assert r1.time == r0.time
     assert r1.depth == r0.depth
     assert not id(r1.o) == id(r0.o)
     assert not id(r1.d) == id(r0.d)
コード例 #4
0
	def sample_r(self, scene: 'Scene', ls: 'LightSample', u1: FLOAT, 
					u2: FLOAT, time: FLOAT) -> ['geo.Ray', 'geo.Normal', FLOAT, 'Spectrum']:
		ray = geo.Ray(self.pos, mc.uniform_sample_sphere(ls.u_pos[0], ls.u_pos[1]),
						0., np.inf, time)
		Ns = geo.Normal.fromVector(ray.d)
		pdf = mc.uniform_sphere_pdf()
		return [ray, Ns, pdf, self.intensity * self.__scale(ray.d)]
コード例 #5
0
	def sample_p(self, pnt: 'geo.Point', u1: FLOAT, u2: FLOAT) -> ['geo.Point', 'geo.Normal']:
		"""
		uniformly sample the sphere
		visible (of certain solid angle)
		to the point
		"""
		# compute coords for sampling
		ctr = self.o2w(geo.Point(0., 0., 0.))
		wc = geo.normalize(ctr - pnt)
		_, wc_x, wc_y = geo.coordinate_system(wc)

		# sample uniformly if p is inside
		if pnt.sq_dist(ctr) - self.radius * self.radius < EPS:
			return self.sample(u1, u2)

		# sample inside subtended cone
		st_max_sq = self.radius * self.radius / pnt.sq_dist(ctr)
		ct_max = np.sqrt(max(0., 1. - st_max_sq))

		from pytracer.montecarlo import uniform_sample_cone
		r = geo.Ray(pnt, uniform_sample_cone(u1, u2, ct_max, wc_x, wc_y, wc), EPS)

		hit, thit, _, _ = self.intersect(r)

		if not hit:
			thit = (ctr - pnt).dot(geo.normalize(r.d))

		ps = r(thit)
		ns = geo.Normal.from_arr(geo.normalize(ps - ctr))
		if self.ro:
			ns *= -1.

		return [ps, ns]
コード例 #6
0
	def generate_ray(self, sample: 'CameraSample') -> [FLOAT, 'geo.Ray']:
		"""
		Generate ray based on image sample.
		Returned ray direction is normalized
		"""
		# generate raster and camera samples
		Pras = geo.Point(sample.imageX, sample.imageY, 0.)
		Pcam = self.r2c(Pras)

		ray = geo.Ray(Pcam, geo.Vector(0., 0., 1.), 0., np.inf)

		# modify ray for dof
		if self.lens_rad > 0.:
			# sample point on lens

			from pytracer.montecarlo import concentric_sample_disk
			lens_u, lens_v = \
				concentric_sample_disk(sample.lens_u, sample.lens_v)
			lens_u *= self.lens_rad
			lens_v *= self.lens_rad

			# compute point on focal plane
			ft = self.focal_dist / ray.d.z
			Pfoc = ray(ft)

			# update ray
			ray.o = geo.Point(lens_u, lens_v, 0.)
			ray.d = geo.normalize(Pfoc - ray.o)

		ray.time = util.lerp(sample.time, self.s_open, self.s_close)
		ray = self.c2w(ray)
		return [1., ray]
コード例 #7
0
    def set_ray(self, p: 'geo.Point', eps: FLOAT, w: 'geo.Vector',
                time: FLOAT):
        """
		set_ray()

		The test is to indicate whether there
		is any object along a given direction.
		"""
        self.ray = geo.Ray(p, w, eps, np.inf, time=time)
コード例 #8
0
	def sample_r(self, scene: 'Scene', ls: 'LightSample', u1: FLOAT, 
					u2: FLOAT, time: FLOAT) -> ['geo.Ray', 'geo.Normal', FLOAT, 'Spectrum']:
		
		v = mc.uniform_sample_cone(ls.u_pos[0], ls.u_pos[1], self.cos_width)

		ray = geo.Ray(self.pos, self.l2w(v), 0., np.inf, time)
		Ns = geo.Normal.fromVector(ray.d)
		pdf = mc.uniform_cone_pdf(self.cos_width)
		return [ray, Ns, pdf, self.intensity * self.__projection(ray.d)]
コード例 #9
0
    def set_segment(self, p1: 'geo.Point', eps1: FLOAT, p2: 'geo.Point',
                    eps2: FLOAT, time: FLOAT):
        """
		set_segment()

		The test is to be done within the
		given segment.
		"""
        dist = (p1 - p2).length()
        self.ray = geo.Ray(p1, (p2 - p1) / dist,
                           eps1,
                           dist * (1. - eps2),
                           time=time)
コード例 #10
0
	def sample_r(self, scene: 'Scene', ls: 'LightSample', u1: FLOAT, 
					u2: FLOAT, time: FLOAT) -> ['geo.Ray', 'geo.Normal', FLOAT, 'Spectrum']:
		"""
		Create a bounding disk
		and uniformly sample
		on it.
		"""
		org, Ns = self.shape_set.sample(ls)
		di = mc.uniform_sample_sphere(u1, u2)
		if di.dot(Ns) < 0.:
			di *= -1.
		ray = geo.Ray(org, di, EPS, np.inf, time)
		pdf = self.shape_set.pdf(org) * INV_2PI
		return [ray, Ns, pdf, self.l(org, Ns, di)]
コード例 #11
0
    def tau(self, r: 'geo.Ray', step_size: FLOAT, u: FLOAT) -> 'Spectrum':
        tau = Spectrum(0.)
        length = r.d.length()
        if length == 0.:
            return tau

        rn = geo.Ray(r.o, r.d / length, r.mint * length, r.maxt * length,
                     r.time)
        hit, t0, t1 = self.intersect_p(rn)
        if not hit:
            return tau

        t0 += u * step_size
        while t0 < t1:
            tau += self.sigma_t(rn(t0), -rn.d, r.time)
            t0 += step_size

        return tau * step_size
コード例 #12
0
	def sample_r(self, scene: 'Scene', ls: 'LightSample', u1: FLOAT, 
					u2: FLOAT, time: FLOAT) -> ['geo.Ray', 'geo.Normal', FLOAT, 'Spectrum']:
		"""
		Create a bounding disk
		and uniformly sample
		on it.
		"""
		# choose point on disk oriented towards light
		ctr, rad = scene.world_bound().bounding_sphere()
		_, v1, v2 = geo.coordinate_system(self.di)
		d1, d2 = mc.concentric_sample_disk(ls.u_pos[0], ls.u_pos[1])
		pnt = ctr + rad * (d1 * v1 + d2 * v2)

		# set ray
		ray = geo.Ray(pnt + rad * self.di, -self.di, 0., np.inf, time)
		Ns = geo.Normal.fromVector(ray.d)
		pdf = 1. / (PI * rad * rad)
		return [ray, Ns, pdf, self.l]
コード例 #13
0
    def generate_ray(self, sample: 'CameraSample') -> [FLOAT, 'geo.Ray']:
        """
		Generate ray based on image sample.
		Returned ray direction is normalized
		"""
        time = util.lerp(sample.time, self.s_open, self.s_close)

        # compute ray direction
        theta = np.pi * sample.imageY / self.film.yResolution
        phi = 2 * np.pi * sample.imageX / self.film.xResolution
        stheta = np.sin(theta)

        ray = self.c2w(
            geo.Ray(
                geo.Point(0., 0., 0.),
                geo.Vector(stheta * np.cos(phi), np.cos(theta),
                           stheta * np.sin(phi)), 0., np.inf, time))
        return [1., ray]
コード例 #14
0
	def sample_r(self, scene: 'Scene', ls: 'LightSample', u1: FLOAT, 
					u2: FLOAT, time: FLOAT) -> ['geo.Ray', 'geo.Normal', FLOAT, 'Spectrum']:
		"""
		Create a bounding disk
		and uniformly sample
		on it.
		"""
		# find (u, v) sample coords in inf. light texture
		uv, pdf = self.dist.sample_cont(ls.u_pos[0], ls.u_pos[1])
		if pdf == 0.:
			return [None, None, 0., Spectrum(0.)]

		theta = uv[1] * PI
		phi = uv[0] * 2. * PI
		ct = np.cos(theta)
		st = np.sin(theta)
		sp = np.sin(phi)
		cp = np.cos(phi)
		d = -self.l2w(geo.Vector(st * cp, st * sp, ct))
		Ns = geo.Normal.fromVector(d)

		# choose point on disk oriented towards light
		ctr, rad = scene.world_bound().bounding_sphere()
		_, v1, v2 = geo.coordinate_system(self.di)
		d1, d2 = mc.concentric_sample_disk(ls.u_pos[0], ls.u_pos[1])
		pnt = ctr + rad * (d1 * v1 + d2 * v2)

		# set ray
		ray = geo.Ray(pnt + rad * (-d), d, 0., np.inf, time)

		# compute pdf
		dir_pdf = pdf / (2. * PI * PI * st)
		area_pdf = 1. / (PI * rad * rad)
		pdf = dir_pdf * area_pdf
		if st == 0.:
			pdf == 0.

		return [ray, Ns, pdf, Spectrum.from_rgb(self.radMap.look_up([uv[0], uv[1]]), SpectrumType.ILLUMINANT)]
コード例 #15
0
 def test_ray_call(self, vec, pnt):
     ray = geo.Ray(pnt, vec)
     t = rng()
     p = ray(t)
     assert isinstance(pnt, geo.Point)
     assert p == pnt + vec * t
コード例 #16
0
 def test_ray_from_parent(self, vec, pnt):
     r0 = geo.Ray(pnt, vec)
     r1 = geo.Ray.from_parent(pnt, vec, r0)
     assert r1.time == r0.time
     assert r1.depth == r0.depth + 1
コード例 #17
0
	def generate_ray(self, sample: 'CameraSample') -> [FLOAT, 'geo.Ray']:
		p = geo.Point(sample.imageX, sample.imageY, 0.)
		pp = geo.Point(0., 0., self.focal)
		d = self.c2w.startTransform(pp - p)
		p = self.c2w.startTransform(p)
		return 1., geo.Ray(p, d)