示例#1
0
	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]
示例#2
0
 def test_ray_differential_from_ray_differential(self, vec, pnt):
     r0 = geo.RayDifferential(pnt, vec)
     r1 = geo.RayDifferential.from_rd(r0)
     assert r1.time == r0.time
     assert r1.depth == r0.depth
     assert r1.has_differentials == r0.has_differentials
     assert not id(r1.o) == id(r0.o)
     assert not id(r1.d) == id(r0.d)
     assert not id(r1.rxDirection) == id(r0.rxDirection)
     assert not id(r1.ryDirection) == id(r0.ryDirection)
     assert not id(r1.rxOrigin) == id(r0.rxOrigin)
     assert not id(r1.ryOrigin) == id(r0.ryOrigin)
示例#3
0
 def test_ray_differential_scale(self, vec, pnt):
     ray = geo.RayDifferential(pnt, vec)
     ray.rxOrigin = ray.ryOrigin = pnt
     ray.rxDirection = vec + geo.Vector(rng(), rng(), rng())
     ray.ryDirection = vec + geo.Vector(rng(), rng(), rng())
     s = rng()
     r = geo.RayDifferential.from_rd(ray)
     ray.scale_differential(s)
     assert ray.rxOrigin == r.o + (r.rxOrigin - r.o) * s
     assert ray.ryOrigin == r.o + (r.ryOrigin - r.o) * s
     assert ray.rxDirection == r.d + (r.rxDirection - r.d) * s
     assert ray.ryDirection == r.d + (r.ryDirection - r.d) * s
     assert isinstance(ray.rxOrigin, geo.Point)
     assert isinstance(ray.ryOrigin, geo.Point)
     assert isinstance(ray.rxDirection, geo.Vector)
     assert isinstance(ray.ryDirection, geo.Vector)
示例#4
0
def estimate_direct(scene: 'Scene',
                    renderer: 'Renderer',
                    light: 'Light',
                    p: 'geo.Point',
                    n: 'geo.Normal',
                    wo: 'geo.Vector',
                    r_eps: FLOAT,
                    time: FLOAT,
                    bsdf: 'BSDF',
                    light_smp: 'LightSample',
                    bsdf_smp: 'BSDFSample',
                    flags: 'BDFType',
                    rng=np.random.rand) -> 'Spectrum':
    """
	estimate_direct()

	Estimate direct lighting
	using MC Multiple Importance Sampling.
	"""
    from pytracer.reflection import BDFType
    Ld = Spectrum(0.)
    # sample light source
    Li, wi, light_pdf, vis = light.sample_l(p, r_eps, light_smp, time)
    if light_pdf > 0. and not Li.is_black():
        f = bsdf.f(wo, wi, flags)
        if not f.is_black() and vis.unoccluded(scene):
            # add contribution to reflected radiance
            ## account for attenuation due to participating media,
            ## left for `VolumeIntegrator` to do
            Li *= vis.transmittance(scene, renderer, None, rng)
            if light.is_delta_light():
                Ld += f * Li * (wi.abs_dot(n) / light_pdf)
            else:
                from pytracer.montecarlo import power_heuristic
                bsdf_pdf = bsdf.pdf(wo, wi, flags)
                weight = power_heuristic(
                    1, light_pdf, 1,
                    bsdf_pdf)  # Power heuristic for HG phase function
                Ld += f * Li * (wi.abs_dot(n) * weight / light_pdf)

    # sample BSDF
    ## no need if delta light
    if not light.is_delta_light():
        bsdf_pdf, wi, smp_type, f = bsdf.sample_f(wo, bsdf_smp, flags)
        if not f.is_black() and bsdf_pdf > 0.:
            wt = 1.
            if not (smp_type & BDFType.SPECULAR
                    ).v == 0:  # MIS not apply to specular direction
                light_pdf = light.pdf(p, wi)
                if light_pdf == 0.:
                    return Ld
                from pytracer.montecarlo import power_heuristic
                wt = power_heuristic(1, bsdf_pdf, 1, light_pdf)
                # add contribution
                Li = Spectrum(0.)
                ray = geo.RayDifferential(p, wi, r_eps, np.inf, time)
                hit, light_isect = scene.intersect(ray)
                if hit:
                    if light_isect.primitive.get_area_light() == light:
                        Li = light_isect.le(-wi)
                else:
                    Li = light.le(ray)  # light illum.

                if not Li.is_black():
                    Li *= renderer.transmittance(scene, ray, None,
                                                 rng)  # attenuation
                    Ld += f * Li * wi.abs_dot(n) * wt / bsdf_pdf

    return Ld
示例#5
0
 def test_ray_differential_call(self, vec, pnt):
     ray = geo.RayDifferential(pnt, vec)
     t = rng()
     p = ray(t)
     assert isinstance(pnt, geo.Point)
     assert p == pnt + vec * t
示例#6
0
 def test_ray_differential_from_parent(self, vec, pnt):
     r0 = geo.RayDifferential(pnt, vec)
     r1 = geo.RayDifferential.from_parent(pnt, vec, r0)
     assert r1.time == r0.time
     assert r1.depth == r0.depth + 1