예제 #1
0
def test02_point_sample_direction(variant_scalar_spectral, spectrum_key):
    # Check the correctness of the sample_direction() method

    from mitsuba.render import SurfaceInteraction3f

    emitter_pos = [10, -1, 2]
    emitter, spectrum = create_emitter_and_spectrum(emitter_pos, spectrum_key)

    # Direction sampling
    it = SurfaceInteraction3f.zero()
    it.p = [0.0, -2.0, 4.5]  # Some position
    it.time = 0.3

    # Direction from the position to the point emitter
    d = -it.p + emitter_pos
    dist = ek.norm(d)
    d /= dist

    # Sample a direction on the emitter
    sample = [0.1, 0.5]
    ds, res = emitter.sample_direction(it, sample)

    assert ds.time == it.time
    assert ds.pdf == 1.0
    assert ds.delta
    assert ek.allclose(ds.d, d)

    # Evalutate the spectrum
    spec = spectrum.eval(it) / (dist**2)
    assert ek.allclose(res, spec)
예제 #2
0
def test03_point_sample_direction_vec(variant_packet_spectral, spectrum_key):
    from mitsuba.render import SurfaceInteraction3f

    emitter_pos = [10, -1, 2]
    emitter, spectrum = create_emitter_and_spectrum(emitter_pos, spectrum_key)

    # Direction sampling
    it = SurfaceInteraction3f.zero(3)
    it.p = [[0.0, 0.0, 0.0], [-2.0, 0.0, -2.0], [4.5, 4.5,
                                                 0.0]]  # Some positions
    it.time = [0.3, 0.3, 0.3]

    # Direction from the position to the point emitter
    d = -it.p + emitter_pos
    dist = ek.norm(d)
    d /= dist

    # Sample direction on the emitter
    sample = [0.1, 0.5]
    ds, res = emitter.sample_direction(it, sample)

    assert ek.all(ds.time == it.time)
    assert ek.all(ds.pdf == 1.0)
    assert ek.all(ds.delta)
    assert ek.allclose(ds.d, d / ek.norm(d))

    # Evalutate the spectrum
    spec = spectrum.eval(it) / (dist**2)
    assert ek.allclose(res, spec)
def test04_direction_sample_construction_single(variant_scalar_rgb):
    from mitsuba.render import Interaction3f, DirectionSample3f, SurfaceInteraction3f

    # Default constructor
    record = DirectionSample3f()
    record.p = [1, 2, 3]
    record.n = [4, 5, 6]
    record.uv = [7, 8]
    record.d = [0, 42, -1]
    record.pdf = 0.002
    record.dist = 0.13

    assert ek.allclose(record.d, [0, 42, -1])
    assert str(record) == """DirectionSample3f[
  p = [1, 2, 3],
  n = [4, 5, 6],
  uv = [7, 8],
  time = 0,
  pdf = 0.002,
  delta = 0,
  object = nullptr,
  d = [0, 42, -1],
  dist = 0.13
]"""

    # Construct from two interactions: ds.d should start from the reference its.
    its = SurfaceInteraction3f.zero()
    its.p = [20, 3, 40.02]
    its.t = 1
    ref = Interaction3f.zero()
    ref.p = [1.6, -2, 35]
    record = DirectionSample3f(its, ref)
    d = (its.p - ref.p) / ek.norm(its.p - ref.p)
    assert ek.allclose(record.d, d)
예제 #4
0
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))
예제 #5
0
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, direction):
    # Check correctness of sample_direction() and pdf_direction() methods

    from mitsuba.render import SurfaceInteraction3f
    from mitsuba.core import Vector3f

    direction = Vector3f(direction)
    emitter = make_emitter(direction, spectrum_key)
    spectrum = make_spectrum(spectrum_key)

    it = SurfaceInteraction3f.zero()
    # Some position inside the unit sphere (i.e. within the emitter's default bounding sphere)
    it.p = [-0.5, 0.3, -0.1]
    it.time = 1.0

    # Sample direction
    samples = [0.85, 0.13]
    ds, res = emitter.sample_direction(it, samples)

    # Direction should point *towards* the illuminated direction
    assert ek.allclose(ds.d, -direction / ek.norm(direction))
    assert ek.allclose(ds.pdf, 1.)
    assert ek.allclose(emitter.pdf_direction(it, ds), 0.)
    assert ek.allclose(ds.time, it.time)

    # Check spectrum (no attenuation vs distance)
    spec = spectrum.eval(it)
    assert ek.allclose(res, spec)
예제 #7
0
def test04_sample_direction(variant_packet_spectral, spectrum_key):
    # Check the correctness of the sample_direction() and pdf_direction() methods

    from mitsuba.render import SurfaceInteraction3f

    shape, spectrum = create_emitter_and_spectrum(spectrum_key)
    emitter = shape.emitter()

    # Direction sampling is conditioned on a sampled position
    it = SurfaceInteraction3f.zero(3)
    it.p = [[0.2, 0.1, 0.2], [0.6, -0.9, 0.2], [0.4, 0.9,
                                                -0.2]]  # Some positions
    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)

    # Sample direction on the shape
    shape_ds = shape.sample_direction(it, samples)

    assert ek.allclose(ds.pdf, shape_ds.pdf)
    assert ek.allclose(ds.pdf, emitter.pdf_direction(it, ds))
    assert ek.allclose(ds.d, shape_ds.d)
    assert ek.allclose(ds.time, it.time)

    # Evalutate the spectrum (divide by the pdf)
    spec = spectrum.eval(it) / ds.pdf
    assert ek.allclose(res, spec)
예제 #8
0
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)
예제 #9
0
def test01_eval(variant_packet_spectral, spectrum_key):
    # Check the correctness of the eval() method

    from mitsuba.core import warp
    from mitsuba.core.math import InvFourPi
    from mitsuba.render import SurfaceInteraction3f

    emitter, spectrum = create_emitter_and_spectrum(spectrum_key)

    it = SurfaceInteraction3f.zero()
    assert ek.allclose(emitter.eval(it), spectrum.eval(it))
예제 #10
0
def test_eval(variant_packet_spectral, spectrum_key, lookat, cutoff_angle):
    # Check the correctness of the eval() method

    from mitsuba.render import SurfaceInteraction3f
    emitter, spectrum = create_emitter_and_spectrum(lookat, cutoff_angle,
                                                    spectrum_key)

    # Check that incident direction in the illuminated direction is zero (because hitting a delta light is impossible)
    it = SurfaceInteraction3f.zero(3)
    it.wi = [0, 1, 0]
    assert ek.allclose(emitter.eval(it), 0.)
예제 #11
0
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))
예제 #12
0
def test02_eval(variant_packet_spectral, spectrum_key):
    # Check that eval() return the same values as the 'radiance' spectrum

    from mitsuba.render import SurfaceInteraction3f

    shape, spectrum = create_emitter_and_spectrum(spectrum_key)
    emitter = shape.emitter()

    it = SurfaceInteraction3f.zero(3)
    assert ek.allclose(emitter.eval(it), spectrum.eval(it))

    # Check that eval return 0.0 when direction points inside the shape

    it.wi = ek.normalize([0.2, 0.2, -0.5])
    assert ek.allclose(emitter.eval(it), 0.0)
예제 #13
0
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 test02_position_sample_construction_dynamic(variant_packet_rgb):
    from mitsuba.render import PositionSample3f, SurfaceInteraction3f

    n_records = 5

    records = PositionSample3f.zero(n_records)
    # Set properties for all records at once (SoA style)
    # records.n = np.zeros(shape=(n_records, 3))
    # records.pdf = np.zeros(shape=(n_records,))
    # records.uv = np.zeros(shape=(n_records, 2))
    # records.delta = np.zeros(shape=(n_records,), dtype=np.bool)
    records.p = np.array([[1.0, 1.0, 1.0], [0.9, 0.9, 0.9], [0.7, 0.7, 0.7],
                          [1.2, 1.5, 1.1], [1.5, 1.5, 1.5]])
    records.time = [0.0, 0.5, 0.7, 1.0, 1.5]
    assert str(records) == """PositionSample3fX[
  p = [[1, 1, 1],
       [0.9, 0.9, 0.9],
       [0.7, 0.7, 0.7],
       [1.2, 1.5, 1.1],
       [1.5, 1.5, 1.5]],
  n = [[0, 0, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 0]],
  uv = [[0, 0],
        [0, 0],
        [0, 0],
        [0, 0],
        [0, 0]],
  time = [0, 0.5, 0.7, 1, 1.5],
  pdf = [0, 0, 0, 0, 0],
  delta = [0, 0, 0, 0, 0],
  object = [nullptr, nullptr, nullptr, nullptr, nullptr]
]"""

    # SurfaceInteraction constructor
    si = SurfaceInteraction3f.zero(n_records)
    si.time = [0.0, 0.5, 0.7, 1.0, 1.5]
    records = PositionSample3f(si)
    assert ek.all(records.time == si.time)
예제 #16
0
# Create a texture with the reference displacement map
disp_tex_1 = xml.load_dict({
	"type" : "bitmap",
	"filename": "diffuser_surface_1.jpg",
	"to_uv" : ScalarTransform4f.scale([1, -1, 1]) # texture is upside-down
}).expand()[0]

# Create a texture with another displacement map
disp_tex_2 = xml.load_dict({
        "type" : "bitmap",
        "filename": "diffuser_surface_2.jpg",
        "to_uv" : ScalarTransform4f.scale([1, -1, 1]) # texture is upside-down
}).expand()[0]

# Create a fake surface interaction with an entry per vertex on the mesh
mesh_si = SurfaceInteraction3f.zero(vertex_count)
mesh_si.uv = ravel(params['grid_mesh.vertex_texcoords_buf'], dim=2)

# Evaluate the displacement map for the entire mesh
disp_tex_diffuser_1 = disp_tex_1.eval_1(mesh_si)
disp_tex_diffuser_2 = disp_tex_2.eval_1(mesh_si)

# Apply displacement to mesh vertex positions and update scene (e.g. OptiX BVH)
def apply_displacement(disp, amplitude = 0.05):
	new_positions = disp.eval_1(mesh_si) * normals_initial * amplitude + positions_initial
	unravel(new_positions, params['grid_mesh.vertex_positions_buf'])
	params.set_dirty('grid_mesh.vertex_positions_buf')
	params.update()

# Change amp to adjust the magnitude of displacement
amp = 0.1
예제 #17
0
 def pdf_functor(w, *args):
     plugin = instantiate(args)
     si = SurfaceInteraction3f.zero(ek.slices(w))
     si.wavelengths = w
     return plugin.pdf(si)[0]
예제 #18
0
 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])
예제 #19
0
 def make_context(n):
     si = SurfaceInteraction3f.zero(n)
     si.wi = wi
     ek.set_slices(si.wi, n)
     si.wavelengths = []
     return (si, ctx)