Пример #1
0
def test04_div():
    a = C(1, 3)
    b = C(5, 7)
    c = a / b
    d = C(13 / 37, 4 / 37)
    assert ek.allclose(c, d)
    assert a / 2 == C(1 / 2, 3 / 2)
def test04_transform_point(variant_scalar_rgb):
    from mitsuba.core import Transform4f

    A = np.eye(4)
    A[3, 3] = 2
    assert ek.allclose(Transform4f(A).transform_point([2, 4, 6]), [1, 2, 3])

    try:
        mitsuba.set_variant("packet_rgb")
        from mitsuba.core import Transform4f as Transform4fX
    except:
        return

    assert ek.allclose(
        Transform4fX(A).transform_point([[2, 4], [4, 6], [6, 8]]),
        [[1, 2], [2, 3], [3, 4]])
def test01_create(variant_scalar_rgb):
    from mitsuba.core import xml, ScalarTransform4f

    s = xml.load_dict({"type" : "cylinder"})
    assert s is not None
    assert s.primitive_count() == 1
    assert ek.allclose(s.surface_area(), 2*ek.pi)

    # Test transforms order in constructor

    rot = ScalarTransform4f.rotate([1.0, 0.0, 0.0], 35)

    s1 = xml.load_dict({
        "type" : "cylinder",
        "radius" : 2.0,
        "p0" : [1, 0, 0],
        "p1" : [1, 0, 2],
        "to_world" : rot
    })

    s2 = xml.load_dict({
        "type" : "cylinder",
        "to_world" : rot * ScalarTransform4f.translate([1, 0, 0]) * ScalarTransform4f.scale(2)
    })

    assert str(s1) == str(s2)
Пример #4
0
def test_sample_ray(variant_scalar_rgb, direction):
    import enoki as ek
    from mitsuba.core import Vector2f, Vector3f

    emitter = make_emitter(direction=direction)
    direction = Vector3f(direction)

    time = 1.0
    wavelength_sample = 0.3
    directional_sample = [0.3, 0.2]

    for spatial_sample in [
        [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],
    ]:
        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.
Пример #5
0
def test04_normal_weighting_scheme(variant_scalar_rgb):
    from mitsuba.core import Struct, float_dtype, Vector3f
    from mitsuba.render import Mesh
    import numpy as np

    """Tests the weighting scheme that is used to compute surface normals."""
    m = Mesh("MyMesh", 5, 2, has_vertex_normals=True)

    vertices = m.vertex_positions_buffer()
    normals = m.vertex_normals_buffer()

    a, b = 1.0, 0.5
    vertices[:] = [0, 0, 0, -a, 1, 0, a, 1, 0, -b, 0, 1, b, 0, 1]

    n0 = Vector3f(0.0, 0.0, -1.0)
    n1 = Vector3f(0.0, 1.0, 0.0)
    angle_0 = ek.pi / 2.0
    angle_1 = ek.acos(3.0 / 5.0)
    n2 = n0 * angle_0 + n1 * angle_1
    n2 /= ek.norm(n2)
    n = np.vstack([n2, n0, n0, n1, n1]).transpose()

    m.faces_buffer()[:] = [0, 1, 2, 0, 3, 4]

    m.recompute_vertex_normals()
    for i in range(5):
        assert ek.allclose(normals[i*3:(i+1)*3], n[:, i], 5e-4)
Пример #6
0
def test01_create(variant_scalar_rgb):
    from mitsuba.core import xml

    s = xml.load_dict({"type": "sphere"})
    assert s is not None
    assert s.primitive_count() == 1
    assert ek.allclose(s.surface_area(), 4 * ek.pi)
def check_scene(int_name, scene_name, is_empty=False):
    from mitsuba.core.xml import load_string
    from mitsuba.core import Bitmap, Struct

    variant_name = mitsuba.variant()

    print("variant_name:", variant_name)

    integrator = make_integrator(int_name, "")
    scene = SCENES[scene_name]['factory']()
    integrator_type = {
        'direct': 'direct',
        'depth': 'depth',
        # All other integrators: 'full'
    }.get(int_name, 'full')
    sensor = scene.sensors()[0]

    avg = SCENES[scene_name][integrator_type]
    film = sensor.film()

    status = integrator.render(scene, sensor)
    assert status, "Rendering ({}) failed".format(variant_name)

    if False:
        _save(film, int_name, suffix='_' + variant_name)

    converted = film.bitmap(raw=True).convert(Bitmap.PixelFormat.RGBA, Struct.Type.Float32, False)
    values = np.array(converted, copy=False)
    means = np.mean(values, axis=(0, 1))
    # Very noisy images, so we add a tolerance
    assert ek.allclose(means, avg, rtol=5e-2), \
        "Mismatch: {} integrator, {} scene, {}".format(
            int_name, scene_name, variant_name)

    return np.array(film.bitmap(raw=False), copy=True)
Пример #8
0
def check_inverse(func, inverse):
    for x in ek.linspace(Float, 1e-6, 1-1e-6, 10):
        for y in ek.linspace(Float, 1e-6, 1-1e-6, 10):
            p1 = np.array([x, y])
            p2 = func(p1)
            p3 = inverse(p2)
            assert(ek.allclose(p1, p3, atol=1e-5))
Пример #9
0
def test03_mueller_to_world_to_local(variant_scalar_mono_polarized):
    """
    At a few places, coordinate changes between local BSDF reference frame and
    world coordinates need to take place. This change also needs to be applied
    to Mueller matrices used in computations involving polarization state.

    In practice, this is always a simple rotation of reference Stokes vectors
    (for incident & outgoing directions) of the Mueller matrix.

    To test this behavior we take any Mueller matrix (e.g. linear polarizer)
    for some arbitrary incident/outgoing directions in world coordinates and
    compute the round trip going to local frame and back again.
    """
    from mitsuba.core import Frame3f, UnpolarizedSpectrum
    from mitsuba.render import SurfaceInteraction3f
    from mitsuba.render.mueller import linear_polarizer
    import numpy as np

    si = SurfaceInteraction3f()
    si.sh_frame = Frame3f(ek.normalize([1.0, 1.0, 1.0]))

    M = linear_polarizer(UnpolarizedSpectrum(1.0))

    # Random incident and outgoing directions
    wi_world = ek.normalize([0.2, 0.0, 1.0])
    wo_world = ek.normalize([0.0, -0.8, 1.0])

    wi_local = si.to_local(wi_world)
    wo_local = si.to_local(wo_world)

    M_local = si.to_local_mueller(M, wi_world, wo_world)
    M_world = si.to_world_mueller(M_local, wi_local, wo_local)

    assert ek.allclose(M, M_world, atol=1e-5)
Пример #10
0
def test19_gather_fwd(m):
    x = ek.linspace(m.Float, -1, 1, 10)
    ek.enable_grad(x)
    y = ek.gather(m.Float, x * x, m.UInt(1, 1, 2, 3))
    ek.forward(x)
    ref = [-1.55556, -1.55556, -1.11111, -0.666667]
    assert ek.allclose(ek.grad(y), ref)
Пример #11
0
def test_map_unit_cube(mode_mono):
    """
    Returns a transformation that maps old cube vertices to new cube vertices.
    """
    trafo = map_unit_cube(1, 2, 3, 4, 5, 6)

    vertices = [
        [0, 0, 0],
        [1, 0, 0],
        [0, 1, 0],
        [1, 1, 0],
        [0, 0, 1],
        [1, 0, 1],
        [0, 1, 1],
        [1, 1, 1],
    ]

    new_vertices = [
        [1, 3, 5],
        [2, 3, 5],
        [1, 4, 5],
        [2, 4, 5],
        [1, 3, 6],
        [2, 3, 6],
        [1, 4, 6],
        [2, 4, 6],
    ]

    for vertex, new_vertex in zip(vertices, new_vertices):
        assert ek.allclose(
            trafo.transform_point(vertex),
            new_vertex,
        )
Пример #12
0
def test02_eval_grad(variant_scalar_rgb):
    # Tests evaluating the texture gradient under different rotation
    from mitsuba.render import SurfaceInteraction3f
    from mitsuba.core.xml import load_string
    from mitsuba.core import Vector2f
    import numpy as np
    import enoki as ek
    delta = 1e-4
    si = SurfaceInteraction3f()
    for u01 in np.random.rand(10, 1):
        angle = 360.0*u01[0]
        bitmap = load_string("""
        <texture type="bitmap" version="2.0.0">
            <string name="filename" value="resources/data/common/textures/noise_8x8.png"/>
            <transform name="to_uv">
                <rotate angle="%f"/>
            </transform>
        </texture>""" % angle).expand()[0]
        for uv in np.random.rand(10, 2):
            si.uv = Vector2f(uv)
            f = bitmap.eval_1(si)
            si.uv = uv + Vector2f(delta, 0)
            fu = bitmap.eval_1(si)
            si.uv = uv + Vector2f(0, delta)
            fv = bitmap.eval_1(si)
            gradient_finite_difference = Vector2f((fu - f)/delta, (fv - f)/delta)
            gradient_analytic = bitmap.eval_1_grad(si)
            assert ek.allclose(0, ek.abs(gradient_finite_difference/gradient_analytic - 1.0), atol = 1e04)
Пример #13
0
def test03_ply_computed_normals(variant_scalar_rgb):
    from mitsuba.core import Vector3f
    from mitsuba.core.xml import load_string
    """Checks(automatic) vertex normal computation for a PLY file that
    doesn't have them."""
    shape = load_string("""
        <shape type="ply" version="0.5.0">
            <string name="filename" value="data/triangle.ply"/>
        </shape>
    """)
    vertices = shape.vertices()
    assert shape.has_vertex_normals()
    # Normals are stored in half precision
    assert ek.allclose(vertices['nx'], [-1, -1, -1])
    assert ek.allclose(vertices['ny'], [0, 0, 0])
    assert ek.allclose(vertices['nz'], [0, 0, 0])
def test03_ray_intersect_transform(variant_scalar_rgb):
    from mitsuba.core import xml, Ray3f, Transform4f

    for r in [1, 3]:
        s = xml.load_dict({
            "type":
            "sphere",
            "radius":
            r,
            "to_world":
            Transform4f.translate([0, 1, 0]) *
            Transform4f.rotate([0, 1, 0], 30.0)
        })

        # grid size
        n = 21
        inv_n = 1.0 / n

        for x in range(n):
            for y in range(n):
                x_coord = r * (2 * (x * inv_n) - 1)
                y_coord = r * (2 * (y * inv_n) - 1)

                ray = Ray3f(o=[x_coord, y_coord + 1, -8],
                            d=[0.0, 0.0, 1.0],
                            time=0.0,
                            wavelengths=[])
                si_found = s.ray_test(ray)

                assert si_found == (x_coord ** 2 + y_coord ** 2 <= r * r) \
                    or ek.abs(x_coord ** 2 + y_coord ** 2 - r * r) < 1e-8

                if si_found:
                    si = s.ray_intersect(ray)
                    ray_u = Ray3f(ray)
                    ray_v = Ray3f(ray)
                    eps = 1e-4
                    ray_u.o += si.dp_du * eps
                    ray_v.o += si.dp_dv * eps
                    si_u = s.ray_intersect(ray_u)
                    si_v = s.ray_intersect(ray_v)
                    if si_u.is_valid():
                        du = (si_u.uv - si.uv) / eps
                        assert ek.allclose(du, [1, 0], atol=2e-2)
                    if si_v.is_valid():
                        dv = (si_v.uv - si.uv) / eps
                        assert ek.allclose(dv, [0, 1], atol=2e-2)
Пример #15
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

    from mitsuba.core import warp, sample_shifted, Transform4f
    from mitsuba.render import SurfaceInteraction3f

    cutoff_angle_rad = cutoff_angle / 180 * ek.pi
    cos_cutoff_angle_rad = ek.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_spectrum(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.transform_point(0))
Пример #16
0
def test01_ray_intersect(variant_scalar_rgb, shape):
    from mitsuba.core import Ray3f
    from mitsuba.render import HitComputeFlags

    s, s_inst = example_scene(shape)

    # grid size
    n = 21
    inv_n = 1.0 / n

    for x in range(n):
        for y in range(n):
            x_coord = (2 * (x * inv_n) - 1)
            y_coord = (2 * (y * inv_n) - 1)
            ray = Ray3f(o=[x_coord, y_coord + 1, -8],
                        d=[0.0, 0.0, 1.0],
                        time=0.0,
                        wavelengths=[])

            si_found = s.ray_test(ray)
            si_found_inst = s_inst.ray_test(ray)

            assert si_found == si_found_inst

            if si_found:
                si = s.ray_intersect(
                    ray, HitComputeFlags.All | HitComputeFlags.dNSdUV)
                si_inst = s_inst.ray_intersect(
                    ray, HitComputeFlags.All | HitComputeFlags.dNSdUV)

                assert si.prim_index == si_inst.prim_index
                assert si.instance is None
                assert si_inst.instance is not None
                assert ek.allclose(si.t, si_inst.t, atol=2e-2)
                assert ek.allclose(si.time, si_inst.time, atol=2e-2)
                assert ek.allclose(si.p, si_inst.p, atol=2e-2)
                assert ek.allclose(si.sh_frame.n,
                                   si_inst.sh_frame.n,
                                   atol=2e-2)
                assert ek.allclose(si.dp_du, si_inst.dp_du, atol=2e-2)
                assert ek.allclose(si.dp_dv, si_inst.dp_dv, atol=2e-2)
                assert ek.allclose(si.uv, si_inst.uv, atol=2e-2)
                assert ek.allclose(si.wi, si_inst.wi, atol=2e-2)

                if ek.norm(si.dn_du) > 0.0 and ek.norm(si.dn_dv) > 0.0:
                    assert ek.allclose(si.dn_du, si_inst.dn_du, atol=2e-2)
                    assert ek.allclose(si.dn_dv, si_inst.dn_dv, atol=2e-2)
Пример #17
0
def test22_scatter_rev(m):
    for i in range(3):
        idx1 = ek.arange(m.UInt, 5)
        idx2 = ek.arange(m.UInt, 4) + 3

        x = ek.linspace(m.Float, 0, 1, 5)
        y = ek.linspace(m.Float, 1, 2, 4)
        buf = ek.zero(m.Float, 10)

        if i % 2 == 0:
            ek.enable_grad(buf)
        if i // 2 == 0:
            ek.enable_grad(x, y)

        x.label = "x"
        y.label = "y"
        buf.label = "buf"

        buf2 = m.Float(buf)
        ek.scatter(buf2, x, idx1)
        ek.eval(buf2)
        ek.scatter(buf2, y, idx2)

        ref_buf = m.Float(0.0000, 0.2500, 0.5000, 1.0000, 1.3333, 1.6667,
                          2.0000, 0.0000, 0.0000, 0.0000)

        assert ek.allclose(ref_buf, buf2, atol=1e-4)
        assert ek.allclose(ref_buf, buf, atol=1e-4)

        s = ek.dot_async(buf2, buf2)

        ek.backward(s)

        ref_x = m.Float(0.0000, 0.5000, 1.0000, 0.0000, 0.0000)
        ref_y = m.Float(2.0000, 2.6667, 3.3333, 4.0000)

        if i // 2 == 0:
            assert ek.allclose(ek.grad(y), ek.detach(ref_y), atol=1e-4)
            assert ek.allclose(ek.grad(x), ek.detach(ref_x), atol=1e-4)
        else:
            assert ek.grad(x) == 0
            assert ek.grad(y) == 0

        if i % 2 == 0:
            assert ek.allclose(ek.grad(buf), 0, atol=1e-4)
        else:
            assert ek.grad(buf) == 0
Пример #18
0
def test09_hsum_2_rev(m):
    x = ek.linspace(m.Float, 0, 1, 11)
    ek.enable_grad(x)
    z = ek.hsum_async(ek.hsum_async(x * x) * x * x)
    ek.backward(z)
    assert ek.allclose(
        ek.grad(x),
        [0., 1.54, 3.08, 4.62, 6.16, 7.7, 9.24, 10.78, 12.32, 13.86, 15.4])
Пример #19
0
def test50_gather_fwd_eager(m):
    with EagerMode():
        x = ek.linspace(m.Float, -1, 1, 10)
        ek.enable_grad(x)
        ek.set_grad(x, 1)
        y = ek.gather(m.Float, x * x, m.UInt(1, 1, 2, 3))
        ref = [-1.55556, -1.55556, -1.11111, -0.666667]
        assert ek.allclose(ek.grad(y), ref)
def test02_pdf(variant_scalar_rgb, interaction):
    from mitsuba.core.math import InvPi
    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"/>
    </bsdf>""")

    interaction.wi = [0, 0, 1]
    ctx = BSDFContext()
    p_pdf = bsdf.pdf(ctx, interaction, [0, 0, 1])
    assert ek.allclose(p_pdf, InvPi)

    p_pdf = bsdf.pdf(ctx, interaction, [0, 0, -1])
    assert ek.allclose(p_pdf, 0.0)
Пример #21
0
def test18_gather(m):
    x = ek.linspace(m.Float, -1, 1, 10)
    ek.enable_grad(x)
    y = ek.gather(m.Float, x * x, m.UInt(1, 1, 2, 3))
    z = ek.hsum_async(y)
    ek.backward(z)
    ref = [0, -1.55556 * 2, -1.11111, -0.666667, 0, 0, 0, 0, 0, 0]
    assert ek.allclose(ek.grad(x), ref)
Пример #22
0
def test_invert_1d(variant_scalar_rgb):
    from mitsuba.core import spline

    values = Float([0.0, 0.25, 0.5, 0.75, 1.0])
    assert (ek.allclose(
        spline.invert_1d(0, 1, values, spline.eval_1d(0, 1, values, 0.6)),
        0.6))
    values = Float([0.1, 0.2, 0.3, 0.35, 1])
    assert (ek.allclose(
        spline.invert_1d(0, 1, values, spline.eval_1d(0, 1, values, 0.26)),
        0.26))
    assert (ek.allclose(
        spline.invert_1d(0, 1, values, spline.eval_1d(0, 1, values, 0.46)),
        0.46))
    assert (ek.allclose(
        spline.invert_1d(0, 1, values, spline.eval_1d(0, 1, values, 0.86)),
        0.86))
Пример #23
0
def test_sample_1d_non_uniform(variant_scalar_rgb):
    from mitsuba.core import spline

    nodes = Float([0.0, 0.25, 0.5, 0.75, 1.0])
    values = Float([0.0, 0.25, 0.5, 0.75, 1.0])

    for i in range(10):
        res = spline.sample_1d(2 * nodes, values,
                               spline.integrate_1d(2 * nodes, values), i / 10)
        assert (ek.allclose(res[1], res[2]))

    values = Float([1.0, 1.0, 1.0, 1.0, 1.0])
    res = spline.sample_1d(nodes, values, spline.integrate_1d(nodes, values),
                           0.5)
    assert (ek.allclose(res[0], 0.5))
    assert (ek.allclose(res[1], 1))
    assert (ek.allclose(res[2], 1))
Пример #24
0
def test01_create(variant_scalar_rgb):
    if mitsuba.core.MTS_ENABLE_EMBREE:
        pytest.skip("EMBREE enabled")

    s = example_sphere()
    assert s is not None
    assert s.primitive_count() == 1
    assert ek.allclose(s.surface_area(), 4 * ek.pi)
Пример #25
0
def test02_gauss_legendre(variant_scalar_rgb):
    from mitsuba.core.quad import gauss_legendre

    assert ek.allclose(gauss_legendre(1), [[0], [2]])
    assert ek.allclose(
        gauss_legendre(2),
        [[-ek.sqrt(1.0 / 3.0), ek.sqrt(1.0 / 3.0)], [1, 1]])
    assert ek.allclose(
        gauss_legendre(3),
        [[-ek.sqrt(3.0 / 5.0), 0, ek.sqrt(3.0 / 5.0)],
         [5.0 / 9.0, 8.0 / 9.0, 5.0 / 9.0]])
    assert ek.allclose(gauss_legendre(4), [[
        -0.861136,
        -0.339981,
        0.339981,
        0.861136,
    ], [0.347855, 0.652145, 0.652145, 0.347855]])
Пример #26
0
def test43_custom_reverse(m):
    d = m.Array3f(1, 2, 3)
    ek.enable_grad(d)
    d2 = ek.custom(Normalize, d)
    ek.set_grad(d2, m.Array3f(5, 6, 7))
    ek.enqueue(d2)
    ek.traverse(m.Float, reverse=True)
    assert ek.allclose(ek.grad(d), m.Array3f(0.610883, 0.152721, -0.305441))
Пример #27
0
def test05_differentiable_surface_interaction_ray_forward(
        variant_gpu_autodiff_rgb):
    from mitsuba.core import xml, Ray3f, Vector3f, UInt32

    shape = xml.load_dict({'type': 'sphere'})

    ray = Ray3f(Vector3f(0.0, -10.0, 0.0), Vector3f(0.0, 1.0, 0.0), 0, [])
    pi = shape.ray_intersect_preliminary(ray)

    ek.set_requires_gradient(ray.o)
    ek.set_requires_gradient(ray.d)

    # If the ray origin is shifted along the x-axis, so does si.p
    si = pi.compute_surface_interaction(ray)
    ek.forward(ray.o.x)
    assert ek.allclose(ek.gradient(si.p), [1, 0, 0])

    # If the ray origin is shifted along the z-axis, so does si.p
    si = pi.compute_surface_interaction(ray)
    ek.forward(ray.o.z)
    assert ek.allclose(ek.gradient(si.p), [0, 0, 1])

    # If the ray origin is shifted along the y-axis, so does si.t
    si = pi.compute_surface_interaction(ray)
    ek.forward(ray.o.y)
    assert ek.allclose(ek.gradient(si.t), -1)

    # If the ray direction is shifted along the x-axis, so does si.p
    si = pi.compute_surface_interaction(ray)
    ek.forward(ray.d.x)
    assert ek.allclose(ek.gradient(si.p), [9, 0, 0])

    # If the ray origin is shifted tangent to the sphere (azimuth), so si.uv.x move by 1 / 2pi
    ek.set_requires_gradient(ray.o)
    si = shape.ray_intersect(ray)
    ek.forward(ray.o.x)
    assert ek.allclose(ek.gradient(si.uv), [1 / (2.0 * ek.pi), 0])

    # If the ray origin is shifted tangent to the sphere (inclination), so si.uv.y move by 2 / 2pi
    ek.set_requires_gradient(ray.o)
    si = shape.ray_intersect(ray)
    ek.forward(ray.o.z)
    assert ek.allclose(ek.gradient(si.uv), [0, -2 / (2.0 * ek.pi)])

    # # If the ray origin is shifted along the x-axis, so does si.n
    ek.set_requires_gradient(ray.o)
    si = shape.ray_intersect(ray)
    ek.forward(ray.o.x)
    assert ek.allclose(ek.gradient(si.n), [1, 0, 0])

    # # If the ray origin is shifted along the z-axis, so does si.n
    ek.set_requires_gradient(ray.o)
    si = shape.ray_intersect(ray)
    ek.forward(ray.o.z)
    assert ek.allclose(ek.gradient(si.n), [0, 0, 1])
Пример #28
0
def test_construct(variant_scalar_rgb):
    from mitsuba.core.xml import load_string

    # Test construct from to_world
    only_to_world = xml_sensor(
        params=xml_lookat(origin="0,0,0", target="0,1,0"))
    sensor = load_string(only_to_world)
    assert not sensor.bbox().valid()  # Degenerate bounding box
    assert ek.allclose(
        sensor.world_transform().eval(0.).matrix,
        [[-1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])

    # Test construct from origin and direction
    origin_direction = xml_sensor(params=xml_origin("0,0,0") +
                                  xml_direction("0,1,0"))
    sensor = load_string(origin_direction)
    assert not sensor.bbox().valid()  # Degenerate bounding box
    assert ek.allclose(
        sensor.world_transform().eval(0.).matrix,
        [[0, 0, 1, 0], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1]])

    # Test to_world overriding direction + origin
    to_world_origin_direction = xml_sensor(
        params=xml_lookat(origin="0,0,0", target="0,1,0") +
        xml_origin("1,0,0") + xml_direction("4,1,0"))
    sensor = load_string(to_world_origin_direction)
    assert not sensor.bbox().valid()  # Degenerate bounding box
    assert ek.allclose(
        sensor.world_transform().eval(0.).matrix,
        [[-1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])

    # Test raise on missing direction or origin
    only_direction = xml_sensor(params=xml_direction("0,1,0"))
    with pytest.raises(RuntimeError):
        sensor = load_string(only_direction)

    only_origin = xml_sensor(params=xml_origin("0,1,0"))
    with pytest.raises(RuntimeError):
        sensor = load_string(only_origin)

    # Test raise on wrong film size
    with pytest.raises(RuntimeError):
        sensor = example_sensor(params=xml_lookat(origin="0,0,-2",
                                                  target="0,0,0"),
                                pixels=2)
Пример #29
0
def test09_trig():
    for i in range(-5, 5):
        for j in range(-5, 5):
            a = ek.sin(C(i, j))
            b = C(cmath.sin(complex(i, j)))
            assert ek.allclose(a, b)

            a = ek.cos(C(i, j))
            b = C(cmath.cos(complex(i, j)))
            assert ek.allclose(a, b)

            sa, ca = ek.sincos(C(i, j))
            sb = C(cmath.sin(complex(i, j)))
            cb = C(cmath.cos(complex(i, j)))
            assert ek.allclose(sa, sb)
            assert ek.allclose(ca, cb)

            # Python appears to handle the branch cuts
            # differently from Enoki, C, and Mathematica..
            a = ek.asin(C(i, j + 0.1))
            b = C(cmath.asin(complex(i, j + 0.1)))
            assert ek.allclose(a, b)

            a = ek.acos(C(i, j + 0.1))
            b = C(cmath.acos(complex(i, j + 0.1)))
            assert ek.allclose(a, b)

            if abs(j) != 1 or i != 0:
                a = ek.atan(C(i, j))
                b = C(cmath.atan(complex(i, j)))
                assert ek.allclose(a, b, atol=1e-7)
Пример #30
0
def test_sample_ray(variant_scalar_rgb, direction, origin):
    sample1 = [0.32, 0.87]
    sample2 = [0.16, 0.44]
    direction_str = ",".join([str(x) for x in direction])
    origin_str = ",".join([str(x) for x in origin])
    sensor = example_sensor(params=xml_direction(direction_str) +
                            xml_origin(origin_str))

    # Test regular ray sampling
    ray = sensor.sample_ray(1., 1., sample1, sample2, True)
    assert ek.allclose(ray[0].o, origin)
    assert ek.allclose(ray[0].d, ek.normalize(direction))

    # Test ray differential sampling
    ray = sensor.sample_ray_differential(1., 1., sample2, sample1, True)
    assert ek.allclose(ray[0].o, origin)
    assert ek.allclose(ray[0].d, ek.normalize(direction))
    assert not ray[0].has_differentials