Пример #1
0
def max_(a0, a1):
    ar, sr = _check2(a0, a1)
    if not a0.IsArithmetic:
        raise Exception("max(): requires arithmetic operands!")
    for i in range(sr):
        ar[i] = _ek.max(a0[i], a1[i])
    return ar
Пример #2
0
    def __init__(self,
                 domain,
                 sample_func,
                 pdf_func,
                 sample_dim=2,
                 sample_count=1000000,
                 res=101,
                 ires=4):
        from mitsuba.core import ScalarVector2u

        if ires < 2:
            raise Exception("The 'ires' parameter must be >= 2!")

        self.domain = domain
        self.sample_func = sample_func
        self.pdf_func = pdf_func
        self.sample_dim = sample_dim
        self.sample_count = sample_count
        self.res = ek.max(ScalarVector2u(res, int(res * domain.aspect())), 1)
        self.ires = ires
        self.bounds = domain.bounds()
        self.pdf = None
        self.histogram = None
        self.p_value = None
        self.messages = ''
        self.fail = False
Пример #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 __init__(self,
                 domain,
                 sample_func,
                 pdf_func,
                 sample_dim=2,
                 sample_count=1000000,
                 res=101,
                 ires=4):
        from mitsuba.core import ScalarVector2u

        assert res > 0
        assert ires >= 2, "The 'ires' parameter must be >= 2!"

        self.domain = domain
        self.sample_func = sample_func
        self.pdf_func = pdf_func
        self.sample_dim = sample_dim
        self.sample_count = sample_count
        if domain.aspect() is None:
            self.res = ScalarVector2u(res, 1)
        else:
            self.res = ek.max(ScalarVector2u(int(res / domain.aspect()), res),
                              1)
        self.ires = ires
        self.bounds = domain.bounds()
        self.pdf = None
        self.histogram = None
        self.p_value = None
        self.messages = ''
        self.fail = False
Пример #5
0
def hmax_(a0):
    size = len(a0)
    if size == 0:
        raise Exception("hmax(): zero-sized array!")

    value = a0[0]
    for i in range(1, size):
        value = _ek.max(value, a0[i])
    return value
Пример #6
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
Пример #7
0
def test05_path_tracer_malus_law(variant_scalar_mono_polarized):
    from mitsuba.core import Spectrum
    from mitsuba.core.xml import load_string
    from mitsuba.render import BSDFContext, TransportMode
    from mitsuba.render.mueller import stokes_basis, rotate_stokes_basis_m

    def spectrum_from_stokes(v):
        res = Spectrum(0.0)
        for i in range(4):
            res[i,0] = v[i]
        return res

    # Test polarizer implementation inside of an actual polarized path tracer.
    # (Serves also as test case for the polarized path tracer itself.)
    #
    # This test involves a setup using two polarizers placed along an optical
    # axis between light source and camera.
    # - The first polarizer is fixed, and transforms the emitted radiance into
    #   linearly polarized light.
    # - The second polarizer rotates to different angles, thus attenuating the
    #   final observed intensity at the camera. We verify that this intensity
    #   follows Malus' law as expected.

    angles = [0, 15, 30, 45, 60, 75, 90]
    radiance = []

    for angle in angles:
        # Build scene with given polarizer rotation angle
        scene_str = """<scene version='2.0.0'>
                           <integrator type="path"/>

                           <sensor type="perspective">
                               <float name="fov" value="0.00001"/>
                               <transform name="to_world">
                                   <lookat origin="0, 10, 0"
                                           target="0, 0, 0"
                                           up    ="0, 0, 1"/>
                               </transform>
                               <film type="hdrfilm">
                                   <integer name="width" value="1"/>
                                   <integer name="height" value="1"/>
                                   <rfilter type="gaussian"/>
                                   <string name="pixel_format" value="rgb"/>
                               </film>
                           </sensor>

                           <!-- Light source -->
                           <shape type="rectangle">
                               <transform name="to_world">
                                   <rotate x="1" y="0" z="0" angle="-90"/>
                                   <translate y="-10"/>
                               </transform>

                               <emitter type="area">
                                   <spectrum name="radiance" value="1"/>
                               </emitter>
                           </shape>

                           <!-- First polarizer. Stays fixed. -->
                           <shape type="rectangle">
                               <bsdf type="polarizer"/>

                               <transform name="to_world">
                                   <rotate x="1" y="0" z="0" angle="-90"/>
                                   <translate y="-5"/>
                               </transform>
                           </shape>

                           <!-- Second polarizer. Rotates. -->
                           <shape type="rectangle">
                               <bsdf type="polarizer"/>

                               <transform name="to_world">
                                   <rotate x="1" y="0" z="0" angle="-90"/>
                                   <rotate x="0" y="1" z="0" angle="{}"/>  <!-- Rotate around optical axis -->
                                   <translate y="0"/>
                               </transform>
                           </shape>

                       </scene>""".format(angle)

        scene = load_string(scene_str)
        integrator = scene.integrator()
        sensor     = scene.sensors()[0]
        sampler    = sensor.sampler()

        # Sample ray from sensor
        ray, _ = sensor.sample_ray_differential(0.0, 0.5, [0.5, 0.5], [0.5, 0.5])

        # Call integrator
        value, _, _ = integrator.sample(scene, sampler, ray)

        # Extract intensity from returned Stokes vector
        v = value[0,0]

        # Avoid occasional rounding problems
        v = ek.max(0.0, v)

        # Keep track of observed radiance
        radiance.append(v)

    # Check that Malus' law holds
    for i in range(len(angles)):
        theta = angles[i] * ek.pi/180
        malus = ek.cos(theta)**2
        malus *= radiance[0]
        assert ek.allclose(malus, radiance[i], atol=1e-2)
Пример #8
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