def generate_ray_differential(self, sample: 'CameraSample') -> [FLOAT, 'geo.RayDifferential']: """ Generate ray differential. """ p_ras = geo.Point(sample.imageX, sample.imageY, 0.) p_cam = self.r2c(p_ras) ray = geo.RayDifferential(geo.Point(0., 0., 0.), geo.Vector.from_arr(geo.normalize(p_cam)), 0., np.inf) # ray.d is a geo.Vector init from a geo.Point from pytracer.montecarlo import concentric_sample_disk if self.lens_rad > 0.: # depth of field 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) if self.lens_rad > 0.: # with defocus blue 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 dx = geo.normalize(self.dxCam + p_cam) ft = self.focal_dist / dx.z Pfoc = geo.Point(0., 0., 0.) + ft * dx ray.rxOrigin = geo.Point(lens_u, lens_v, 0.) ray.rxDirection = geo.normalize(Pfoc - ray.rxOrigin) dy = geo.normalize(geo.Vector.from_arr(p_cam + self.dyCam)) ft = self.focal_dist / dy.z Pfoc = geo.Point(0., 0., 0.) + ft * dy ray.ryOrigin = geo.Point(lens_u, lens_v, 0.) ray.ryDirection = geo.normalize(Pfoc - ray.ryOrigin) else: ray.rxOrigin = ray.ryOrigin = ray.o ray.rxDirection = geo.normalize(self.dxCam + p_cam) # geo.Vector + geo.Point => geo.Vector ray.ryDirection = geo.normalize(self.dyCam + p_cam) ray.time = sample.time ray = self.c2w(ray) ray.has_differentials = True return [1., ray]
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]
def sample(self, u1: FLOAT, u2: FLOAT) -> ['geo.Point', 'geo.Normal']: # account for partial disk from pytracer.montecarlo import concentric_sample_disk x, y = concentric_sample_disk(u1, u2) phi = np.arctan2(y, x) * self.phiMax * INV_2PI r = self.inner_radius + np.sqrt(x * x + y * y) * (self.radius - self.inner_radius) p = geo.Point(r * np.cos(phi), r * np.sin(phi), self.height) Ns = geo.normalize(self.o2w(p)) if self.ro: Ns *= -1. return [self.o2w(p), Ns]
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]
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)]