示例#1
0
def matmul_(a0, a1):
    if not (a0.Size == a1.Size and (a0.IsMatrix or a0.IsVector) \
                               and (a1.IsMatrix or a1.IsVector)):
        raise Exception("matmul(): unsupported operand shape!")

    if a0.IsVector and a1.IsVector:
        return _ek.dot(a0, a1)
    elif a0.IsMatrix and a1.IsVector:
        ar = a0[0] * a1[0]
        for i in range(1, a1.Size):
            ar = _ek.fmadd(a0[i], a1[i], ar)
        return ar
    elif a0.IsVector and a1.IsMatrix:
        ar = a1.Value()
        for i in range(a1.Size):
            ar[i] = _ek.dot(a0, a1[i])
        return ar
    else:  # matrix @ matrix
        ar, sr = _check2(a0, a1)
        for j in range(a0.Size):
            accum = a0[0] * _ek.full(a0.Value, a1[0, j])
            for i in range(1, a0.Size):
                accum = _ek.fmadd(a0[i], _ek.full(a0.Value, a1[i, j]), accum)
            ar[j] = accum
        return ar
示例#2
0
    def eval(self, si, active):
        cosTheta = ek.dot(si.wi, si.n)

        tmp2 = ek.select(Frame3f.cos_theta(si.wi) > 0, \
                self.m_radiance.eval(si, active)*self.fallof(cosTheta), \
                float(0))
        return tmp2
示例#3
0
def test05_scalar(t):
    if not ek.is_array_v(t) or ek.array_size_v(t) == 0:
        return
    get_class(t.__module__)

    if ek.is_mask_v(t):
        assert ek.all_nested(t(True))
        assert ek.any_nested(t(True))
        assert ek.none_nested(t(False))
        assert ek.all_nested(t(False) ^ t(True))
        assert ek.all_nested(ek.eq(t(False), t(False)))
        assert ek.none_nested(ek.eq(t(True), t(False)))

    if ek.is_arithmetic_v(t):
        assert t(1) + t(1) == t(2)
        assert t(3) - t(1) == t(2)
        assert t(2) * t(2) == t(4)
        assert ek.min(t(2), t(3)) == t(2)
        assert ek.max(t(2), t(3)) == t(3)

        if ek.is_signed_v(t):
            assert t(2) * t(-2) == t(-4)
            assert ek.abs(t(-2)) == t(2)

        if ek.is_integral_v(t):
            assert t(6) // t(2) == t(3)
            assert t(7) % t(2) == t(1)
            assert t(7) >> 1 == t(3)
            assert t(7) << 1 == t(14)
            assert t(1) | t(2) == t(3)
            assert t(1) ^ t(3) == t(2)
            assert t(1) & t(3) == t(1)
        else:
            assert t(6) / t(2) == t(3)
            assert ek.sqrt(t(4)) == t(2)
            assert ek.fmadd(t(1), t(2), t(3)) == t(5)
            assert ek.fmsub(t(1), t(2), t(3)) == t(-1)
            assert ek.fnmadd(t(1), t(2), t(3)) == t(1)
            assert ek.fnmsub(t(1), t(2), t(3)) == t(-5)
            assert (t(1) & True) == t(1)
            assert (t(1) & False) == t(0)
            assert (t(1) | False) == t(1)

        assert ek.all_nested(t(3) > t(2))
        assert ek.all_nested(ek.eq(t(2), t(2)))
        assert ek.all_nested(ek.neq(t(3), t(2)))
        assert ek.all_nested(t(1) >= t(1))
        assert ek.all_nested(t(2) < t(3))
        assert ek.all_nested(t(1) <= t(1))
        assert ek.select(ek.eq(t(2), t(2)), t(4), t(5)) == t(4)
        assert ek.select(ek.eq(t(3), t(2)), t(4), t(5)) == t(5)
        t2 = t(2)
        assert ek.hsum(t2) == t.Value(2 * len(t2))
        assert ek.dot(t2, t2) == t.Value(4 * len(t2))
        assert ek.dot_async(t2, t2) == t(4 * len(t2))

        value = t(1)
        value[ek.eq(value, t(1))] = t(2)
        value[ek.eq(value, t(3))] = t(5)
        assert value == t(2)
示例#4
0
 def pdf_direction(self, ref, ds, active):
     # as the shape init happens after the emitter init
     if (not (hasattr(self, "m_shape"))):
         self.set_shape_area()
     tmp3 = ek.select(
         ek.dot(ds.d, ds.n) < 0,
         self.m_shape.pdf_direction(ref, ds, active), float(0))
     return tmp3
示例#5
0
    def sample_direction(self, ref, sample, active):
        # as the shape init happens after the emitter init
        if (not (hasattr(self, "m_shape"))):
            self.set_shape_area()

        ds = self.m_shape.sample_direction(ref, sample, active)

        active &= (ek.dot(ds.d, ds.n) < 0) & (ek.neq(ds.pdf, 0))

        si = SurfaceInteraction3f(ds, ref.wavelengths)
        # spatially varying
        cosTheta = -ek.dot(ds.d, ds.n)
        fall = self.fallof(cosTheta)

        spec = self.m_radiance.eval(si, active) * fall / ds.pdf

        ds.object = 0  # HACK

        return (ds, ek.select(active, spec, ek.zero(type(spec))))
示例#6
0
def det(m):
    if not _ek.is_matrix_v(m):
        raise Exception("Unsupported target type!")

    if m.Size == 1:
        return m[0, 0]
    elif m.Size == 2:
        return _ek.fmsub(m[0, 0], m[1, 1], m[0, 1] * m[1, 0])
    elif m.Size == 3:
        return _ek.dot(m[0], _ek.cross(m[1], m[2]))
    elif m.Size == 4:
        col0, col1, col2, col3 = m

        col1 = _ek.shuffle((2, 3, 0, 1), col1)
        col3 = _ek.shuffle((2, 3, 0, 1), col3)

        temp = _ek.shuffle((1, 0, 3, 2), col2 * col3)
        row0 = col1 * temp
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fmsub(col1, temp, row0)

        temp = _ek.shuffle((1, 0, 3, 2), col1 * col2)
        row0 = _ek.fmadd(col3, temp, row0)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fnmadd(col3, temp, row0)

        col1 = _ek.shuffle((2, 3, 0, 1), col1)
        col2 = _ek.shuffle((2, 3, 0, 1), col2)
        temp = _ek.shuffle((1, 0, 3, 2), col1 * col3)
        row0 = _ek.fmadd(col2, temp, row0)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fnmadd(col2, temp, row0)

        return _ek.dot(col0, row0)
    else:
        raise Exception('Unsupported array size!')
def test02_intersection_partials(variant_scalar_rgb):
    from mitsuba.core import Frame3f, Ray3f, RayDifferential3f
    from mitsuba.render import SurfaceInteraction3f

    # Test the texture partial computation with some random data

    o = [0.44650541, 0.16336525, 0.74225088]
    d = [0.2956123, 0.67325977, 0.67774232]
    time = 0.5
    w = []
    r = RayDifferential3f(o, d, time, w)
    r.o_x = r.o + [0.1, 0, 0]
    r.o_y = r.o + [0, 0.1, 0]
    r.d_x = r.d
    r.d_y = r.d
    r.has_differentials = True

    si = SurfaceInteraction3f()
    si.p = r(10)
    si.dp_du = [0.5514372, 0.84608955, 0.41559092]
    si.dp_dv = [0.14551054, 0.54917541, 0.39286475]
    si.n = ek.cross(si.dp_du, si.dp_dv)
    si.n /= ek.norm(si.n)
    si.t = 0

    si.compute_partials(r)

    # Positions reached via computed partials
    px1 = si.dp_du * si.duv_dx[0] + si.dp_dv * si.duv_dx[1]
    py1 = si.dp_du * si.duv_dy[0] + si.dp_dv * si.duv_dy[1]

    # Manually
    px2 = r.o_x + r.d_x * \
        ((ek.dot(si.n, si.p) - ek.dot(si.n, r.o_x)) / ek.dot(si.n, r.d_x))
    py2 = r.o_y + r.d_y * \
        ((ek.dot(si.n, si.p) - ek.dot(si.n, r.o_y)) / ek.dot(si.n, r.d_y))
    px2 -= si.p
    py2 -= si.p

    assert (ek.allclose(px1, px2))
    assert (ek.allclose(py1, py2))

    si.dp_du = [0, 0, 0]
    si.compute_partials(r)

    assert (ek.allclose(px1, px2))
    assert (ek.allclose(py1, py2))

    si.compute_partials(r)

    assert (ek.allclose(si.duv_dx, [0, 0]))
    assert (ek.allclose(si.duv_dy, [0, 0]))
示例#8
0
def visible_ndf(D, sigma, theta_i, phi_i, isotropic):
    from mitsuba.core import MarginalContinuous2D0, Vector2f

    # Construct projected surface area interpolant data structure
    m_sigma = MarginalContinuous2D0(sigma, normalize=False)

    # Create uniform samples and warp by G2 mapping
    if isotropic:
        n_theta = n_phi = D.shape[1]
    else:
        n_phi = D.shape[0]
        n_theta = D.shape[1]

    # Check dimensions of micro-facet model
    Dvis = np.zeros((phi_i.size, theta_i.size, n_phi, n_theta))

    theta = u2theta(np.linspace(0, 1, n_theta))
    phi = u2phi(np.linspace(0, 1, n_phi))

    # Calculate projected area of micro-facets
    for i in range(Dvis.shape[0]):  # incident elevation
        for j in range(Dvis.shape[1]):  # incident azimuth
            # Postion for sigma samples
            sample = Vector2f(theta2u(theta_i[j]), phi2u(phi_i[i]))
            sigma_i = m_sigma.eval(sample)

            # Incident direction
            omega_i = spherical2cartesian(theta_i[j], phi_i[i])
            #print(np.degrees(theta_i[j]), np.degrees(phi_i[i]))

            for k in range(Dvis.shape[2]):  # observation azimuth
                # Observation direction
                omega = spherical2cartesian(theta, phi[k])
                sample = Vector2f(theta2u(theta), phi2u(phi[k]))

                # NDF at observation directions
                if isotropic:
                    D_m = D[0]
                else:
                    D_m = D[k]
                # Bidirectional NDF
                Dvis[i, j,
                     k] = ek.max(0, ek.dot(omega, omega_i)) * D_m / sigma_i
    return Dvis
示例#9
0
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 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))
示例#11
0
def test_sampling(variant_scalar_rgb, center, radius):
    """
    We construct an irradiance meter attached to a sphere and assert that sampled
    rays originate at the sphere's surface
    """
    from mitsuba.core import Vector3f

    center_v = Vector3f(center)
    sphere = example_shape(radius, center_v)
    sensor = sphere.sensor()
    num_samples = 100

    wav_samples = np.random.rand(num_samples)
    pos_samples = np.random.rand(num_samples, 2)
    dir_samples = np.random.rand(num_samples, 2)

    for i in range(100):
        ray = sensor.sample_ray_differential(0.0, wav_samples[i],
                                             pos_samples[i], dir_samples[i])[0]

        # assert that the ray starts at the sphere surface
        assert ek.allclose(ek.norm(center_v - ray.o), radius)
        # assert that all rays point away from the sphere center
        assert ek.dot(ek.normalize(ray.o - center_v), ray.d) > 0.0
示例#12
0
 def check_fov(camera, sample):
     ray, _ = camera.sample_ray(0, 0, sample, 0)
     assert ek.allclose(
         ek.acos(ek.dot(ray.d, direction)) * 180 / ek.pi, fov / 2)
示例#13
0
 def forward(self):
     grad_in = self.grad_in('value')
     grad_out = grad_in * self.inv_norm
     grad_out -= self.value * (ek.dot(self.value, grad_out) *
                               ek.sqr(self.inv_norm))
     self.set_grad_out(grad_out)
示例#14
0
 def backward(self):
     grad_out = self.grad_out()
     grad_in = grad_out * self.inv_norm
     grad_in -= self.value * (ek.dot(self.value, grad_in) *
                              ek.sqr(self.inv_norm))
     self.set_grad_in('value', grad_in)
示例#15
0
def inverse_transpose(m):
    if not _ek.is_matrix_v(m):
        raise Exception("Unsupported target type!")

    t = type(m)
    if m.Size == 1:
        return t(_ek.rcp(m[0, 0]))
    elif m.Size == 2:
        inv_det = _ek.rcp(_ek.fmsub(m[0, 0], m[1, 1], m[0, 1] * m[1, 0]))
        return t(m[1, 1] * inv_det, -m[1, 0] * inv_det, -m[0, 1] * inv_det,
                 m[0, 0] * inv_det)
    elif m.Size == 3:
        col0, col1, col2 = m
        row0 = _ek.cross(col1, col2)
        row1 = _ek.cross(col2, col0)
        row2 = _ek.cross(col0, col1)
        inv_det = _ek.rcp(_ek.dot(col0, row0))

        return t(row0 * inv_det, row1 * inv_det, row2 * inv_det)

    elif m.Size == 4:
        col0, col1, col2, col3 = m

        col1 = _ek.shuffle((2, 3, 0, 1), col1)
        col3 = _ek.shuffle((2, 3, 0, 1), col3)

        temp = _ek.shuffle((1, 0, 3, 2), col2 * col3)
        row0 = col1 * temp
        row1 = col0 * temp
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fmsub(col1, temp, row0)
        row1 = _ek.shuffle((2, 3, 0, 1), _ek.fmsub(col0, temp, row1))

        temp = _ek.shuffle((1, 0, 3, 2), col1 * col2)
        row0 = _ek.fmadd(col3, temp, row0)
        row3 = col0 * temp
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fnmadd(col3, temp, row0)
        row3 = _ek.shuffle((2, 3, 0, 1), _ek.fmsub(col0, temp, row3))

        temp = _ek.shuffle((1, 0, 3, 2),
                           _ek.shuffle((2, 3, 0, 1), col1) * col3)
        col2 = _ek.shuffle((2, 3, 0, 1), col2)
        row0 = _ek.fmadd(col2, temp, row0)
        row2 = col0 * temp
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fnmadd(col2, temp, row0)
        row2 = _ek.shuffle((2, 3, 0, 1), _ek.fmsub(col0, temp, row2))

        temp = _ek.shuffle((1, 0, 3, 2), col0 * col1)
        row2 = _ek.fmadd(col3, temp, row2)
        row3 = _ek.fmsub(col2, temp, row3)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row2 = _ek.fmsub(col3, temp, row2)
        row3 = _ek.fnmadd(col2, temp, row3)

        temp = _ek.shuffle((1, 0, 3, 2), col0 * col3)
        row1 = _ek.fnmadd(col2, temp, row1)
        row2 = _ek.fmadd(col1, temp, row2)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row1 = _ek.fmadd(col2, temp, row1)
        row2 = _ek.fnmadd(col1, temp, row2)

        temp = _ek.shuffle((1, 0, 3, 2), col0 * col2)
        row1 = _ek.fmadd(col3, temp, row1)
        row3 = _ek.fnmadd(col1, temp, row3)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row1 = _ek.fnmadd(col3, temp, row1)
        row3 = _ek.fmadd(col1, temp, row3)

        inv_det = _ek.rcp(_ek.dot(col0, row0))

        return t(row0 * inv_det, row1 * inv_det, row2 * inv_det,
                 row3 * inv_det)
    else:
        raise Exception('Unsupported array size!')
示例#16
0
def projected_area(D, isotropic, projected=True):
    from mitsuba.core import MarginalContinuous2D0, Vector2f, Vector3f

    # Check dimensions of micro-facet model
    sigma = np.zeros(D.shape)

    # Construct projected surface area interpolant data structure
    m_D = MarginalContinuous2D0(D, normalize=False)

    # Create uniform samples and warp by G2 mapping
    if isotropic:
        n_theta = n_phi = D.shape[1]
    else:
        n_phi = D.shape[0]
        n_theta = D.shape[1]
    theta = u2theta(np.linspace(0, 1, n_theta))
    phi = u2phi(np.linspace(0, 1, n_phi))

    # Temporary values for surface area calculation
    theta_mean = np.zeros(n_theta + 1)
    for i in range(n_theta - 1):
        theta_mean[i + 1] = (theta[i + 1] - theta[i]) / 2. + theta[i]
    theta_mean[-1] = theta[-1]
    theta_mean[0] = theta[0]
    """
    Surface area portion of unit sphere.
    Conditioning better for non vectorized approach.
    a  = sphere_surface_patch(1, theta_next, Vector2f(phi[0], phi[1]))
    """
    a = np.zeros(n_theta)
    for i in range(n_theta):
        a[i] = sphere_surface_patch(1, theta_mean[i:i + 2], phi[-3:-1])

    # Calculate constants for integration
    for j in range(n_phi):
        # Interpolation points
        o = spherical2cartesian(theta, phi[j])
        # Postion for NDF samples
        u0 = theta2u(theta)
        u1 = np.ones(n_theta) * phi2u(phi[j])
        if j == 0:
            omega = o
            u_0 = u0
            u_1 = u1
            area = a / 2
        else:
            omega = np.concatenate((omega, o))
            u_0 = np.concatenate((u_0, u0))
            u_1 = np.concatenate((u_1, u1))
            if j == n_phi - 1:
                area = np.concatenate((area, a / 2))
            else:
                area = np.concatenate((area, a))
    sample = Vector2f(u_0, u_1)
    D_s = m_D.eval(sample)
    omega = Vector3f(omega)

    P = 1.
    # Calculate projected area of micro-facets
    for i in range(sigma.shape[0] - 1):
        for j in range(sigma.shape[1]):
            # Get projection factor from incident and outgoind direction
            if projected:
                # Incident direction
                omega_i = spherical2cartesian(theta[j], phi[i])
                P = ek.max(0, ek.dot(omega, omega_i))

            # Integrate over sphere
            F = P * D_s
            sigma[i, j] = np.dot(F, area)

        if projected:
            # Normalise
            sigma[i] = sigma[i] / sigma[i, 0]

    # TODO: Check for anisotropic case
    if isotropic:
        sigma[1] = sigma[0]

    return sigma
示例#17
0
def outgoing_direction(n_phi,
                       n_theta,
                       Dvis_sampler,
                       theta_i,
                       phi_i,
                       isotropic,
                       theta_max=np.pi / 2,
                       all=False):
    from mitsuba.core import Vector2f, Frame3f
    from mitsuba.core import MarginalContinuous2D2

    print("Max theta angle is %f deg." % np.degrees(theta_max))

    phi_o = np.zeros((phi_i.size, theta_i.size, n_phi, n_theta))
    theta_o = np.zeros((phi_i.size, theta_i.size, n_phi, n_theta))
    invalid = np.ones((phi_i.size, theta_i.size, n_phi, n_theta), dtype='bool')
    active = np.ones((phi_i.size, theta_i.size, n_phi, n_theta), dtype='bool')

    # Create uniform samples
    u_0 = np.linspace(0, 1, n_theta)
    u_1 = np.linspace(0, 1, n_phi)
    samples = Vector2f(np.tile(u_0, n_phi), np.repeat(u_1, n_theta))

    # Construct projected surface area interpolant data structure
    params = [phi_i.tolist(), theta_i.tolist()]
    m_vndf = MarginalContinuous2D2(Dvis_sampler, params, normalize=True)

    for i in range(phi_i.size):
        for j in range(theta_i.size):
            # Warp uniform samples by VNDF distribution (G1 mapping)
            u_m, ndf_pdf = m_vndf.sample(samples, [phi_i[i], theta_i[j]])
            # Convert samples to radians (G2 mapping)
            theta_m = u2theta(u_m.x)  # [0, 1] -> [0, pi]
            phi_m = u2phi(u_m.y)  # [0, 1] -> [0, 2pi]
            if isotropic:
                phi_m += phi_i[i]
            # Phase vector
            m = spherical2cartesian(theta_m, phi_m)
            # Incident direction
            wi = spherical2cartesian(theta_i[j], phi_i[i])
            # Outgoing direction (reflection over phase vector)
            wo = ek.fmsub(m, 2.0 * ek.dot(m, wi), wi)
            tmp1, tmp2 = cartesian2spherical(wo)
            # Remove invalid directions
            act = u_m.y > 0  # covered twice [-pi = pi]
            inv = Frame3f.cos_theta(wo) < 0  # below surface plane
            act &= np.invert(inv)  # above surface plane
            act &= tmp1 <= (theta_max + EPSILON)  # further angular restriction
            if isotropic:
                act &= tmp2 >= 0
            if not all:
                tmp1[~act] = 0
                tmp2[~act] = 0
            else:
                tmp1[inv] = 0
                tmp2[inv] = 0

            # Fit to datashape
            act = np.reshape(act, (n_phi, n_theta))
            inv = np.reshape(inv, (n_phi, n_theta))
            tmp1 = np.reshape(tmp1, (n_phi, n_theta))
            tmp2 = np.reshape(tmp2, (n_phi, n_theta))

            # Append
            active[i, j] = act
            invalid[i, j] = inv
            theta_o[i, j] = tmp1
            phi_o[i, j] = tmp2
    return [theta_o, phi_o, active, invalid]
示例#18
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))
示例#19
0
 def check_fov(camera, sample):
     # aperture position at the center
     ray, _ = camera.sample_ray(0, 0, sample, [0.5, 0.5])
     assert ek.allclose(
         ek.acos(ek.dot(ray.d, direction)) * 180 / ek.pi, fov / 2)