def test_square_to_uniform_sphere_vec(variant_scalar_rgb): from mitsuba.core import warp assert(ek.allclose(warp.square_to_uniform_sphere([0, 0]), [0, 0, 1])) assert(ek.allclose(warp.square_to_uniform_sphere([0, 1]), [0, 0, -1])) assert(ek.allclose(warp.square_to_uniform_sphere([0.5, 0.5]), [-1, 0, 0], atol=1e-7)) check_inverse(warp.square_to_uniform_sphere, warp.uniform_sphere_to_square) check_vectorization("square_to_uniform_sphere")
def test01_coordinate_system(variant_scalar_rgb): from mitsuba.core import coordinate_system, warp def branchless_onb(n): """ Building an Orthonormal Basis, Revisited Tom Duff, James Burgess, Per Christensen, Christophe Hery, Andrew Kensler, Max Liani, and Ryusuke Villemin """ sign = ek.copysign(1.0, n[2]) a = -1.0 / (sign + n[2]) b = n[0] * n[1] * a return ( [1.0 + sign * n[0] * n[0] * a, sign * b, -sign * n[0]], [b, sign + n[1] * n[1] * a, -n[1]] ) a = [0.70710678, -0. , -0.70710678] b = [-0., 1., 0.] assert ek.allclose( branchless_onb([ek.sqrt(0.5), 0, ek.sqrt(0.5)]), (a, b), atol=1e-6) assert ek.allclose( coordinate_system([ek.sqrt(0.5), 0, ek.sqrt(0.5)]), (a, b), atol=1e-6) for u in ek.linspace(Float, 0, 1, 10): for v in ek.linspace(Float, 0, 1, 10): n = warp.square_to_uniform_sphere([u, v]) s1, t1 = branchless_onb(n) s2, t2 = coordinate_system(n) assert ek.allclose(s1, s2, atol=1e-6) assert ek.allclose(t1, t2, atol=1e-6)
def test01_point_sample_ray(variant_packet_spectral, spectrum_key): # Check the correctness of the sample_ray() method from mitsuba.core import Vector3f, warp, sample_shifted from mitsuba.render import SurfaceInteraction3f emitter_pos = [10, -1, 2] emitter, spectrum = create_emitter_and_spectrum(emitter_pos, spectrum_key) time = 0.5 wavelength_sample = [0.5, 0.33, 0.1] dir_sample = [[0.4, 0.5, 0.3], [0.1, 0.4, 0.9]] pos_sample = dir_sample # not being used anyway # Sample a ray (position, direction, wavelengths) on the emitter ray, res = emitter.sample_ray(time, wavelength_sample, pos_sample, dir_sample) # Sample wavelengths on the spectrum it = SurfaceInteraction3f.zero(3) wav, spec = spectrum.sample_spectrum(it, sample_shifted(wavelength_sample)) assert ek.allclose(res, spec * 4 * ek.pi) assert ek.allclose(ray.time, time) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(ray.d, warp.square_to_uniform_sphere(dir_sample)) assert ek.allclose(ray.o, Vector3f(emitter_pos))
def test03_sample_direction(variant_packet_spectral): # Check the correctness of the sample_direction() and pdf_direction() methods from mitsuba.core import warp from mitsuba.core.math import InvFourPi from mitsuba.render import SurfaceInteraction3f emitter, spectrum = create_emitter_and_spectrum() it = SurfaceInteraction3f.zero(3) # Some positions inside the unit sphere it.p = [[-0.5, 0.3, -0.1], [0.8, -0.3, -0.2], [-0.2, 0.6, -0.6]] it.time = 1.0 # Sample direction on the emitter samples = [[0.4, 0.5, 0.3], [0.1, 0.4, 0.9]] ds, res = emitter.sample_direction(it, samples) assert ek.allclose(ds.pdf, InvFourPi) assert ek.allclose(ds.d, warp.square_to_uniform_sphere(samples)) assert ek.allclose(emitter.pdf_direction(it, ds), InvFourPi) assert ek.allclose(ds.time, it.time) # Evaluate the spectrum (divide by the pdf) spec = spectrum.eval(it) / warp.square_to_uniform_sphere_pdf(ds.d) assert ek.allclose(res, spec)
def test02_sample_ray(variant_packet_spectral, spectrum_key): # Check the correctness of the sample_ray() method from mitsuba.core import Frame3f, warp, sample_shifted from mitsuba.render import SurfaceInteraction3f emitter, spectrum = create_emitter_and_spectrum(spectrum_key) time = 0.5 wavelength_sample = [0.5, 0.33, 0.1] pos_sample = [[0.2, 0.1, 0.2], [0.6, 0.9, 0.2]] dir_sample = [[0.4, 0.5, 0.3], [0.1, 0.4, 0.9]] # Sample a ray (position, direction, wavelengths) on the emitter ray, res = emitter.sample_ray(time, wavelength_sample, pos_sample, dir_sample) # Sample wavelengths on the spectrum it = SurfaceInteraction3f.zero(3) wav, spec = spectrum.sample(it, sample_shifted(wavelength_sample)) assert ek.allclose(res, spec * 4 * ek.pi * ek.pi) assert ek.allclose(ray.time, time) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(ray.o, warp.square_to_uniform_sphere(pos_sample)) assert ek.allclose( ray.d, Frame3f(-ray.o).to_world(warp.square_to_cosine_hemisphere(dir_sample)))
def sample_ray( self, time, sample1, # wavelength sample2, # pos sample3, # dir active): wavelengths, spec_weight = self.m_intensity.sample( SurfaceInteraction3f(), ek.arange(sample1), active) trafo = self.m_world_transform.eval(ref.time) ray = Ray3f(trafo * Point3f(0), warp.square_to_uniform_sphere(sample3), time, wavelengths) # print(spec_weight.class_().name()) return (ray, spec_weight * 4.0 * Pi)
def test03_sample_eval_pdf(variant_scalar_rgb, interaction): from mitsuba.core.math import InvPi from mitsuba.core.warp import square_to_uniform_sphere from mitsuba.render import BSDFContext from mitsuba.core.xml import load_string bsdf = load_string("""<bsdf version="2.0.0" type="twosided"> <bsdf type="diffuse"> <rgb name="reflectance" value="0.1, 0.1, 0.1"/> </bsdf> <bsdf type="diffuse"> <rgb name="reflectance" value="0.9, 0.9, 0.9"/> </bsdf> </bsdf>""") n = 5 ctx = BSDFContext() for u in ek.arange(UInt32, n): for v in ek.arange(UInt32, n): interaction.wi = square_to_uniform_sphere([u / float(n-1), v / float(n-1)]) up = ek.dot(interaction.wi, [0, 0, 1]) > 0 for x in ek.arange(UInt32, n): for y in ek.arange(UInt32, n): sample = [x / float(n-1), y / float(n-1)] (bs, s_value) = bsdf.sample(ctx, interaction, 0.5, sample) if ek.any(s_value > 0): # Multiply by square_to_cosine_hemisphere_theta s_value *= bs.wo[2] * InvPi if not up: s_value *= -1 e_value = bsdf.eval(ctx, interaction, bs.wo) p_pdf = bsdf.pdf(ctx, interaction, bs.wo) assert ek.allclose(s_value, e_value, atol=1e-2) assert ek.allclose(bs.pdf, p_pdf) assert not ek.any(ek.isnan(e_value) | ek.isnan(s_value))
def sample(self, ctx, mi, sample1, active=True): wo = warp.square_to_uniform_sphere(sample1) pdf = warp.square_to_uniform_sphere_pdf(wo) return (wo, pdf)