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 test02_sample_ray(variant_packet_spectral, origin, direction): # Check the correctness of the sample_ray() method from mitsuba.core import sample_shifted, sample_rgb_spectrum camera = create_camera(origin, direction) time = 0.5 wav_sample = [0.5, 0.33, 0.1] pos_sample = [[0.2, 0.1, 0.2], [0.6, 0.9, 0.2]] aperture_sample = 0 # Not being used ray, spec_weight = camera.sample_ray(time, wav_sample, pos_sample, aperture_sample) # Importance sample wavelength and weight wav, spec = sample_rgb_spectrum(sample_shifted(wav_sample)) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(spec_weight, spec) assert ek.allclose(ray.time, time) assert ek.allclose(ray.o, origin) # Check that a [0.5, 0.5] position_sample generates a ray # that points in the camera direction ray, _ = camera.sample_ray(0, 0, [0.5, 0.5], 0) assert ek.allclose(ray.d, direction, atol=1e-7)
def test03_sample_ray(variant_packet_spectral, spectrum_key): # Check the correctness of the sample_ray() method from mitsuba.core import warp, Frame3f, sample_shifted from mitsuba.render import SurfaceInteraction3f shape, spectrum = create_emitter_and_spectrum(spectrum_key) emitter = shape.emitter() 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_spectrum(it, sample_shifted(wavelength_sample)) # Sample a position on the shape ps = shape.sample_position(time, pos_sample) assert ek.allclose(res, spec * shape.surface_area() * ek.pi) assert ek.allclose(ray.time, time) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(ray.o, ps.p) assert ek.allclose( ray.d, Frame3f(ps.n).to_world(warp.square_to_cosine_hemisphere(dir_sample)))
def test_sample_direction(variant_scalar_spectral, spectrum_key, it_pos, wavelength_sample, cutoff_angle, lookat): # Check the correctness of the sample_direction() method import math from mitsuba.core import sample_shifted, Transform4f from mitsuba.render import SurfaceInteraction3f cutoff_angle_rad = math.radians(cutoff_angle) beam_width_rad = cutoff_angle_rad * 0.75 inv_transition_width = 1 / (cutoff_angle_rad - beam_width_rad) emitter, spectrum = create_emitter_and_spectrum(lookat, cutoff_angle, spectrum_key) eval_t = 0.3 trafo = Transform4f(emitter.world_transform().eval(eval_t)) # Create a surface iteration it = SurfaceInteraction3f.zero() it.p = it_pos it.time = eval_t # Sample a wavelength from spectrum wav, spec = spectrum.sample(it, sample_shifted(wavelength_sample)) it.wavelengths = wav # Direction from the position to the point emitter d = -it.p + lookat["pos"] dist = ek.norm(d) d /= dist # Calculate angle between lookat direction and ray direction angle = ek.acos((trafo.inverse().transform_vector(-d))[2]) angle = ek.select( ek.abs(angle - beam_width_rad) < 1e-3, beam_width_rad, angle) angle = ek.select( ek.abs(angle - cutoff_angle_rad) < 1e-3, cutoff_angle_rad, angle) # Sample a direction from the emitter ds, res = emitter.sample_direction(it, [0, 0]) # Evalutate the spectrum spec = spectrum.eval(it) spec = ek.select( angle <= beam_width_rad, spec, spec * ((cutoff_angle_rad - angle) * inv_transition_width)) spec = ek.select(angle <= cutoff_angle_rad, spec, 0) assert ds.time == it.time assert ds.pdf == 1.0 assert ds.delta assert ek.allclose(ds.d, d) assert ek.allclose(res, spec / (dist**2))
def test02_sample_ray(variant_packet_spectral, origin, direction, aperture_rad, focus_dist): # Check the correctness of the sample_ray() method from mitsuba.core import sample_shifted, sample_rgb_spectrum, warp, Vector3f, Transform4f cam = create_camera(origin, direction, aperture=aperture_rad, focus_dist=focus_dist) time = 0.5 wav_sample = [0.5, 0.33, 0.1] pos_sample = [[0.2, 0.1, 0.2], [0.6, 0.9, 0.2]] aperture_sample = [0.5, 0.5] ray, spec_weight = cam.sample_ray(time, wav_sample, pos_sample, aperture_sample) # Importance sample wavelength and weight wav, spec = sample_rgb_spectrum(sample_shifted(wav_sample)) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(spec_weight, spec) assert ek.allclose(ray.time, time) assert ek.allclose(ray.o, origin) # Check that a [0.5, 0.5] position_sample and [0.5, 0.5] aperture_sample # generates a ray that points in the camera direction ray, _ = cam.sample_ray(0, 0, [0.5, 0.5], [0.5, 0.5]) assert ek.allclose(ray.d, direction, atol=1e-7) # ---------------------------------------- # Check correctness of aperture sampling pos_sample = [0.5, 0.5] aperture_sample = [[0.9, 0.4, 0.2], [0.6, 0.9, 0.7]] ray, _ = cam.sample_ray(time, wav_sample, pos_sample, aperture_sample) ray_centered, _ = cam.sample_ray(time, wav_sample, pos_sample, [0.5, 0.5]) trafo = Transform4f(cam.world_transform().eval(time).matrix.numpy()) tmp = warp.square_to_uniform_disk_concentric(aperture_sample) aperture_v = trafo.transform_vector(aperture_rad * Vector3f(tmp.x, tmp.y, 0)) # NOTE: here we assume near_clip = 1.0 assert ek.allclose(ray.o, ray_centered.o + aperture_v) assert ek.allclose(ray.d, ek.normalize(ray_centered.d * focus_dist - aperture_v))
def test_sample_ray(variant_packet_spectral, spectrum_key, wavelength_sample, pos_sample, cutoff_angle, lookat): # Check the correctness of the sample_ray() method import math from mitsuba.core import warp, sample_shifted, Transform4f from mitsuba.render import SurfaceInteraction3f cutoff_angle_rad = math.radians(cutoff_angle) cos_cutoff_angle_rad = math.cos(cutoff_angle_rad) beam_width_rad = cutoff_angle_rad * 0.75 inv_transition_width = 1 / (cutoff_angle_rad - beam_width_rad) emitter, spectrum = create_emitter_and_spectrum(lookat, cutoff_angle, spectrum_key) eval_t = 0.3 trafo = Transform4f(emitter.world_transform().eval(eval_t)) # Sample a local direction and calculate local angle dir_sample = pos_sample # not being used anyway local_dir = warp.square_to_uniform_cone(pos_sample, cos_cutoff_angle_rad) angle = ek.acos(local_dir[2]) angle = ek.select( ek.abs(angle - beam_width_rad) < 1e-3, beam_width_rad, angle) angle = ek.select( ek.abs(angle - cutoff_angle_rad) < 1e-3, cutoff_angle_rad, angle) # Sample a ray (position, direction, wavelengths) from the emitter ray, res = emitter.sample_ray(eval_t, wavelength_sample, pos_sample, dir_sample) # Sample wavelengths on the spectrum it = SurfaceInteraction3f.zero() wav, spec = spectrum.sample(it, sample_shifted(wavelength_sample)) it.wavelengths = wav spec = spectrum.eval(it) spec = ek.select( angle <= beam_width_rad, spec, spec * ((cutoff_angle_rad - angle) * inv_transition_width)) spec = ek.select(angle <= cutoff_angle_rad, spec, 0) assert ek.allclose( res, spec / warp.square_to_uniform_cone_pdf( trafo.inverse().transform_vector(ray.d), cos_cutoff_angle_rad)) assert ek.allclose(ray.time, eval_t) assert ek.all(local_dir.z >= cos_cutoff_angle_rad) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(ray.d, trafo.transform_vector(local_dir)) assert ek.allclose(ray.o, lookat["pos"])
def test_sample_ray(variant_scalar_spectral, direction, spectrum_key): from mitsuba.core import Vector2f, Vector3f, sample_shifted from mitsuba.render import SurfaceInteraction3f emitter = make_emitter(direction=direction, spectrum_key=spectrum_key) spectrum = make_spectrum(spectrum_key) direction = Vector3f(direction) time = 1.0 for wavelength_sample, spatial_sample, directional_sample in zip( cycle([0.3, 0.7]), [ [0.85, 0.13], [0.16, 0.50], [0.00, 1.00], [0.32, 0.87], [0.16, 0.44], [0.17, 0.44], [0.22, 0.81], [0.12, 0.82], [0.99, 0.42], [0.72, 0.40], [0.01, 0.61], ], cycle([[0.3, 0.2]]) ): ray, _ = emitter.sample_ray( time, wavelength_sample, spatial_sample, directional_sample) # Check that ray direction is what is expected assert ek.allclose(ray.d, direction / ek.norm(direction)) # Check that ray origin is outside of bounding sphere # Bounding sphere is centered at world origin and has radius 1 without scene assert ek.norm(ray.o) >= 1. # Check that passed irradiance spectrum is used for wavelength sampling it = SurfaceInteraction3f.zero() wav, spec = spectrum.sample_spectrum( it, sample_shifted(wavelength_sample)) assert ek.allclose(ray.wavelengths, wav)
def test03_sample_ray_differential(variant_packet_spectral, origin, direction): # Check the correctness of the sample_ray_differential() method from mitsuba.core import sample_shifted, sample_rgb_spectrum camera = create_camera(origin, direction) time = 0.5 wav_sample = [0.5, 0.33, 0.1] pos_sample = [[0.2, 0.1, 0.2], [0.6, 0.9, 0.2]] ray, spec_weight = camera.sample_ray_differential(time, wav_sample, pos_sample, 0) # Importance sample wavelength and weight wav, spec = sample_rgb_spectrum(sample_shifted(wav_sample)) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(spec_weight, spec) assert ek.allclose(ray.time, time) assert ek.allclose(ray.o, origin) # Check that the derivatives are orthogonal assert ek.allclose(ek.dot(ray.d_x - ray.d, ray.d_y - ray.d), 0, atol=1e-7) # Check that a [0.5, 0.5] position_sample generates a ray # that points in the camera direction ray_center, _ = camera.sample_ray_differential(0, 0, [0.5, 0.5], 0) assert ek.allclose(ray_center.d, direction, atol=1e-7) # Check correctness of the ray derivatives # Deltas in screen space dx = 1.0 / camera.film().crop_size().x dy = 1.0 / camera.film().crop_size().y # Sample the rays by offsetting the position_sample with the deltas ray_dx, _ = camera.sample_ray_differential(0, 0, [0.5 + dx, 0.5], 0) ray_dy, _ = camera.sample_ray_differential(0, 0, [0.5, 0.5 + dy], 0) assert ek.allclose(ray_dx.d, ray_center.d_x) assert ek.allclose(ray_dy.d, ray_center.d_y)
def sample_functor(sample, *args): plugin = instantiate(args) si = SurfaceInteraction3f.zero(ek.slices(sample)) wavelength, weight = plugin.sample(si, sample_shifted(sample[0])) return Vector1f(wavelength[0])
def test03_sample_ray_diff(variant_packet_spectral, origin, direction, aperture_rad, focus_dist): # Check the correctness of the sample_ray_differential() method from mitsuba.core import sample_shifted, sample_rgb_spectrum, warp, Vector3f, Transform4f cam = create_camera(origin, direction, aperture=aperture_rad, focus_dist=focus_dist) time = 0.5 wav_sample = [0.5, 0.33, 0.1] pos_sample = [[0.2, 0.1, 0.2], [0.6, 0.9, 0.2]] aperture_sample = [0.5, 0.5] ray, spec_weight = cam.sample_ray_differential(time, wav_sample, pos_sample, aperture_sample) # Importance sample wavelength and weight wav, spec = sample_rgb_spectrum(sample_shifted(wav_sample)) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(spec_weight, spec) assert ek.allclose(ray.time, time) assert ek.allclose(ray.o, origin) # ----------------------------------------_ # Check that the derivatives are orthogonal assert ek.allclose(ek.dot(ray.d_x - ray.d, ray.d_y - ray.d), 0, atol=1e-7) # Check that a [0.5, 0.5] position_sample and [0.5, 0.5] aperture_sample # generates a ray that points in the camera direction ray_center, _ = cam.sample_ray_differential(0, 0, [0.5, 0.5], [0.5, 0.5]) assert ek.allclose(ray_center.d, direction, atol=1e-7) # ---------------------------------------- # Check correctness of the ray derivatives aperture_sample = [[0.9, 0.4, 0.2], [0.6, 0.9, 0.7]] ray_center, _ = cam.sample_ray_differential(0, 0, [0.5, 0.5], aperture_sample) # Deltas in screen space dx = 1.0 / cam.film().crop_size().x dy = 1.0 / cam.film().crop_size().y # Sample the rays by offsetting the position_sample with the deltas (aperture centered) ray_dx, _ = cam.sample_ray_differential(0, 0, [0.5 + dx, 0.5], aperture_sample) ray_dy, _ = cam.sample_ray_differential(0, 0, [0.5, 0.5 + dy], aperture_sample) assert ek.allclose(ray_dx.d, ray_center.d_x) assert ek.allclose(ray_dy.d, ray_center.d_y) # -------------------------------------- # Check correctness of aperture sampling pos_sample = [0.5, 0.5] aperture_sample = [[0.9, 0.4, 0.2], [0.6, 0.9, 0.7]] ray, _ = cam.sample_ray(time, wav_sample, pos_sample, aperture_sample) ray_centered, _ = cam.sample_ray(time, wav_sample, pos_sample, [0.5, 0.5]) trafo = Transform4f(cam.world_transform().eval(time).matrix.numpy()) tmp = warp.square_to_uniform_disk_concentric(aperture_sample) aperture_v = trafo.transform_vector(aperture_rad * Vector3f(tmp.x, tmp.y, 0)) # NOTE: here we assume near_clip = 1.0 assert ek.allclose(ray.o, ray_centered.o + aperture_v) assert ek.allclose(ray.d, ek.normalize(ray_centered.d * focus_dist - aperture_v))