Пример #1
0
def integrator_sample(scene, sampler, rays, medium, active=True):
    si = scene.ray_intersect(rays)
    active = si.is_valid() & active

    # Visible emitters
    emitter_vis = si.emitter(scene, active)
    result = ek.select(active, Emitter.eval_vec(emitter_vis, si, active), Vector3f(0.0))

    ctx = BSDFContext()
    bsdf = si.bsdf(rays)

    # Emitter sampling
    sample_emitter = active & has_flag(BSDF.flags_vec(bsdf), BSDFFlags.Smooth)
    ds, emitter_val = scene.sample_emitter_direction(si, sampler.next_2d(sample_emitter), True, sample_emitter)
    active_e = sample_emitter & ek.neq(ds.pdf, 0.0)
    wo = si.to_local(ds.d)
    bsdf_val = BSDF.eval_vec(bsdf, ctx, si, wo, active_e)
    bsdf_pdf = BSDF.pdf_vec(bsdf, ctx, si, wo, active_e)
    mis = ek.select(ds.delta, Float(1), mis_weight(ds.pdf, bsdf_pdf))
    result += ek.select(active_e, emitter_val * bsdf_val * mis, Vector3f(0))

    # BSDF sampling
    active_b = active
    bs, bsdf_val = BSDF.sample_vec(bsdf, ctx, si, sampler.next_1d(active), sampler.next_2d(active), active_b)
    si_bsdf = scene.ray_intersect(si.spawn_ray(si.to_world(bs.wo)), active_b)
    emitter = si_bsdf.emitter(scene, active_b)
    active_b &= ek.neq(emitter, 0)
    emitter_val = Emitter.eval_vec(emitter, si_bsdf, active_b)
    delta = has_flag(bs.sampled_type, BSDFFlags.Delta)
    ds = DirectionSample3f(si_bsdf, si)
    ds.object = emitter
    emitter_pdf = ek.select(delta, Float(0), scene.pdf_emitter_direction(si, ds, active_b))
    result += ek.select(active_b, bsdf_val * emitter_val * mis_weight(bs.pdf, emitter_pdf), Vector3f(0))
    return result, si.is_valid(), ek.select(si.is_valid(), si.t, Float(0.0))
Пример #2
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)
Пример #3
0
 def collatz(value: p.Int):
     counter = p.Int(0)
     loop = p.Loop(value, counter)
     while (loop.cond(ek.neq(value, 1))):
         is_even = ek.eq(value & 1, 0)
         value.assign(ek.select(is_even, value // 2, 3 * value + 1))
         counter += 1
     return counter
Пример #4
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))))
Пример #5
0
def neq_(a0, a1):
    ar, sr = _check2_mask(a0, a1)
    for i in range(sr):
        ar[i] = _ek.neq(a0[i], a1[i])
    return ar
Пример #6
0
def render_sample(scene, sampler, rays, bdata, heightmap_pybind, bssrdf=None):
    """
    Sample RTE
    TODO: Support multi channel sampling

    Args:
        scene: Target scene object
        sampler: Sampler object for random number
        rays: Given rays for sampling
        bdata: BSSRDF Data object
        heightmap_pybind: Object for getting height map around incident position.
                          Refer src/librender/python/heightmap.cpp

    Returns:
        result: Sampling RTE result
        valid_rays: Mask data whether rays are valid or not
        scatter: Scatter components of Sampling RTE result
        non_scatter: Non scatter components of Sampling RTE result
        invalid_sample: Sampling RTE result with invalid sampled data by VAEBSSRDF
    """

    eta = Float(1.0)
    emission_weight = Float(1.0)
    throughput = Spectrum(1.0)
    result = Spectrum(0.0)
    scatter = Spectrum(0.0)
    non_scatter = Spectrum(0.0)
    invalid_sample = Spectrum(0.0)
    active = True
    is_bssrdf = False

    ##### First interaction #####
    si = scene.ray_intersect(rays, active)
    active = si.is_valid() & active
    valid_rays = si.is_valid()

    emitter = si.emitter(scene, active)

    depth = 0

    # Set channel
    # At and after evaluating BSSRDF, a ray consider only this one channel
    n_channels = 3
    channel = UInt32(
        ek.min(sampler.next_1d(active) * n_channels, n_channels - 1))

    d_out_local = Vector3f().zero()
    d_out_pdf = Float(0)

    sss = Mask(False)

    while (True):
        depth += 1
        if config.aovs and depth == 2:
            sss = is_bssrdf

        ##### Interaction with emitters #####
        emission_val = emission_weight * throughput * Emitter.eval_vec(
            emitter, si, active)

        result += ek.select(active, emission_val, Spectrum(0.0))
        invalid_sample += ek.select(active, emission_val, Spectrum(0.0))
        scatter += ek.select(active & sss, emission_val, Spectrum(0.0))
        non_scatter += ek.select(active & ~sss, emission_val, Spectrum(0.0))

        active = active & si.is_valid()

        # Process russian roulette
        if depth > config.rr_depth:
            q = ek.min(ek.hmax(throughput) * ek.sqr(eta), 0.95)
            active = active & (sampler.next_1d(active) < q)
            throughput *= ek.rcp(q)

        # Stop if the number of bouces exceeds the given limit bounce, or
        # all rays are invalid. latter check is done only when the limit
        # bounce is infinite
        if depth >= config.max_depth:
            break

        ##### Emitter sampling #####
        bsdf = si.bsdf(rays)
        ctx = BSDFContext()

        active_e = active & has_flag(BSDF.flags_vec(bsdf), BSDFFlags.Smooth)
        ds, emitter_val = scene.sample_emitter_direction(
            si, sampler.next_2d(active_e), True, active_e)
        active_e &= ek.neq(ds.pdf, 0.0)

        # Query the BSDF for that emitter-sampled direction
        wo = si.to_local(ds.d)
        bsdf_val = BSDF.eval_vec(bsdf, ctx, si, wo, active_e)
        # Determine density of sampling that same direction using BSDF sampling
        bsdf_pdf = BSDF.pdf_vec(bsdf, ctx, si, wo, active_e)

        mis = ek.select(ds.delta, Float(1), mis_weight(ds.pdf, bsdf_pdf))

        emission_val = mis * throughput * bsdf_val * emitter_val

        result += ek.select(active, emission_val, Spectrum(0.0))
        invalid_sample += ek.select(active, emission_val, Spectrum(0.0))
        scatter += ek.select(active & sss, emission_val, Spectrum(0.0))
        non_scatter += ek.select(active & ~sss, emission_val, Spectrum(0.0))

        ##### BSDF sampling #####
        bs, bsdf_val = BSDF.sample_vec(bsdf, ctx, si, sampler.next_1d(active),
                                       sampler.next_2d(active), active)

        ##### BSSRDF replacing #####
        if (config.enable_bssrdf):
            # Replace bsdf samples by ones of BSSRDF
            bs.wo = ek.select(is_bssrdf, d_out_local, bs.wo)
            bs.pdf = ek.select(is_bssrdf, d_out_pdf, bs.pdf)
            bs.sampled_component = ek.select(is_bssrdf, UInt32(1),
                                             bs.sampled_component)
            bs.sampled_type = ek.select(is_bssrdf,
                                        UInt32(+BSDFFlags.DeltaTransmission),
                                        bs.sampled_type)
        ############################

        throughput *= ek.select(is_bssrdf, Float(1.0), bsdf_val)
        active &= ek.any(ek.neq(throughput, 0))

        eta *= bs.eta

        # Intersect the BSDF ray against the scene geometry
        rays = RayDifferential3f(si.spawn_ray(si.to_world(bs.wo)))
        si_bsdf = scene.ray_intersect(rays, active)

        ##### Checking BSSRDF #####
        if (config.enable_bssrdf):
            # Whether the BSDF is BSS   RDF or not?
            is_bssrdf = (active
                         & has_flag(BSDF.flags_vec(bsdf), BSDFFlags.BSSRDF)
                         & (Frame3f.cos_theta(bs.wo) < Float(0.0))
                         & (Frame3f.cos_theta(si.wi) > Float(0.0)))

            # Decide whether we should use 0-scattering or multiple scattering
            is_zero_scatter = utils_render.check_zero_scatter(
                sampler, si_bsdf, bs, channel, is_bssrdf)
            is_bssrdf = is_bssrdf & ~is_zero_scatter

            throughput *= ek.select(is_bssrdf, ek.sqr(bs.eta), Float(1.0))
        ###########################

        ###### Process for BSSRDF ######
        if (config.enable_bssrdf and not ek.none(is_bssrdf)):
            # Get projected samples from BSSRDF
            projected_si, project_suc, abs_prob = bssrdf.sample_bssrdf(
                scene, bsdf, bs, si, bdata, heightmap_pybind, channel,
                is_bssrdf)

            if config.visualize_invalid_sample and (depth <= 1):
                active = active & (~is_bssrdf | project_suc)
                invalid_sample += ek.select((is_bssrdf & (~project_suc)),
                                            Spectrum([100, 0, 0]),
                                            Spectrum(0.0))

            # Sample outgoing direction from projected position
            d_out_local, d_out_pdf = utils_render.resample_wo(
                sampler, is_bssrdf)
            # Apply absorption probability
            throughput *= ek.select(is_bssrdf,
                                    Spectrum(1) - abs_prob, Spectrum(1))
            # Replace interactions by sampled ones from BSSRDF
            si_bsdf = SurfaceInteraction3f().masked_si(si_bsdf, projected_si,
                                                       is_bssrdf)
        ################################

        # Determine probability of having sampled that same
        # direction using emitter sampling
        emitter = si_bsdf.emitter(scene, active)
        ds = DirectionSample3f(si_bsdf, si)
        ds.object = emitter

        delta = has_flag(bs.sampled_type, BSDFFlags.Delta)
        emitter_pdf = ek.select(delta, Float(0.0),
                                scene.pdf_emitter_direction(si, ds))
        emission_weight = mis_weight(bs.pdf, emitter_pdf)

        si = si_bsdf

    return result, valid_rays, scatter, non_scatter, invalid_sample
Пример #7
0
    def run(self, significance_level=0.01, test_count=1, quiet=False):
        """
        Run the Chi^2 test

        Parameter ``significance_level`` (float):
            Denotes the desired significance level (e.g. 0.01 for a test at the
            1% significance level)

        Parameter ``test_count`` (int):
            Specifies the total number of statistical tests run by the user.
            This value will be used to adjust the provided significance level
            so that the combination of the entire set of tests has the provided
            significance level.

        Returns → bool:
            ``True`` upon success, ``False`` if the null hypothesis was
            rejected.

        """

        from mitsuba.core import UInt32, Float64
        from mitsuba.core.math import chi2
        from mitsuba.python.math import rlgamma

        if self.histogram is None:
            self.tabulate_histogram()

        if self.pdf is None:
            self.tabulate_pdf()

        index = UInt32(
            [i[0] for i in sorted(enumerate(self.pdf), key=lambda x: x[1])])

        # Sort entries by expected frequency (increasing)
        pdf = Float64(ek.gather(self.pdf, index))
        histogram = Float64(ek.gather(self.histogram, index))

        # Compute chi^2 statistic and pool low-valued cells
        chi2val, dof, pooled_in, pooled_out = \
            chi2(histogram, pdf, 5)

        if dof < 1:
            self._log('Failure: The number of degrees of freedom is too low!')
            self.fail = True

        if ek.any(ek.eq(pdf, 0) & ek.neq(histogram, 0)):
            self._log('Failure: Found samples in a cell with expected '
                      'frequency 0. Rejecting the null hypothesis!')
            self.fail = True

        if pooled_in > 0:
            self._log('Pooled %i low-valued cells into %i cells to '
                      'ensure sufficiently high expected cell frequencies' %
                      (pooled_in, pooled_out))

        pdf_time = (self.pdf_end - self.pdf_start) * 1000
        histogram_time = (self.histogram_end - self.histogram_start) * 1000

        self._log('Histogram sum = %f (%.2f ms), PDF sum = %f (%.2f ms)' %
                  (self.histogram_sum, histogram_time, self.pdf_sum, pdf_time))

        self._log('Chi^2 statistic = %f (d.o.f = %i)' % (chi2val, dof))

        # Probability of observing a test statistic at least as
        # extreme as the one here assuming that the distributions match
        self.p_value = 1 - rlgamma(dof / 2, chi2val / 2)

        # Apply the Šidák correction term, since we'll be conducting multiple
        # independent hypothesis tests. This accounts for the fact that the
        # probability of a failure increases quickly when several hypothesis
        # tests are run in sequence.
        significance_level = 1.0 - \
            (1.0 - significance_level) ** (1.0 / test_count)

        if self.fail:
            self._log('Not running the test for reasons listed above. Target '
                      'density and histogram were written to "chi2_data.py')
            result = False
        elif self.p_value < significance_level \
                or not ek.isfinite(self.p_value):
            self._log('***** Rejected ***** the null hypothesis (p-value = %f,'
                      ' significance level = %f). Target density and histogram'
                      ' were written to "chi2_data.py".' %
                      (self.p_value, significance_level))
            result = False
        else:
            self._log('Accepted the null hypothesis (p-value = %f, '
                      'significance level = %f)' %
                      (self.p_value, significance_level))
            result = True
        if not quiet:
            print(self.messages)
            if not result:
                self._dump_tables()
        return result
Пример #8
0
    def sample(self, scene, sampler, ray, medium=None, active=True):
        result = Vector3f(0.0)
        si = scene.ray_intersect(ray, active)
        active = si.is_valid() & active

        # emitter = si.emitter(scene)
        # result = ek.select(active, Emitter.eval_vec(emitter, si, active), Vector3f(0.0))

        # z_axis = np.array([0, 0, 1])

        # vertex = si.p.numpy()
        # v_count = vertex.shape[0]
        # vertex = np.expand_dims(vertex, axis=1)
        # vertex = np.repeat(vertex, self.light.vertex_count(), axis=1)

        # light_vertices = self.light.vertex_positions_buffer().numpy().reshape(self.light.vertex_count(), 3)
        # light_vertices = np.expand_dims(light_vertices, axis=0)
        # light_vertices = np.repeat(light_vertices, v_count, axis=0)

        # sph_polygons = light_vertices - vertex
        # sph_polygons = sph_polygons / np.linalg.norm(sph_polygons, axis=2, keepdims=True)

        # z_axis = np.repeat( np.expand_dims(z_axis, axis=0), v_count, axis=0 )
        # result_np = np.zeros(v_count, dtype=np.double)

        # for idx in range( self.light.vertex_count() ):
        #     idx1 = (idx+1) % self.light.vertex_count()
        #     idx2 = (idx) % self.light.vertex_count()

        #     dp = np.sum( sph_polygons[:, idx1, :] * sph_polygons[:, idx2, :], axis=1 )
        #     acos = np.arccos(dp)

        #     cp = np.cross( sph_polygons[:, idx1, :], sph_polygons[:, idx2, :] )
        #     cp = cp / np.linalg.norm(cp, axis=1, keepdims=True)

        #     dp = np.sum( cp * z_axis, axis=1 )

        #     result_np += acos * dp

        # result_np *= 0.5 * 1.0/math.pi
        # result_np = np.repeat( result_np.reshape((v_count, 1)), 3, axis=1 )

        # fin = self.light_radiance * Vector3f(result_np)
        # fin[fin < 0] = 0
        # result += ek.select(active, fin, Vector3f(0.0))

        ctx = BSDFContext()
        bsdf = si.bsdf(ray)

        # bs, bsdf_val = BSDF.sample_vec(bsdf, ctx, si, sampler.next_1d(active), sampler.next_2d(active), active)
        # pdf = bs.pdf
        # wo = si.to_world(bs.wo)

        ds, emitter_val = scene.sample_emitter_direction(
            si, sampler.next_2d(active), True, active)
        pdf = ds.pdf
        active_e = active & ek.neq(ds.pdf, 0.0)
        wo = ds.d
        bsdf_val = BSDF.eval_vec(bsdf, ctx, si, wo, active_e)
        emitter_val[emitter_val > 1.0] = 1.0
        bsdf_val *= emitter_val

        # _, wi_theta, wi_phi = sph_convert(si.to_world(si.wi))
        _, wo_theta, wo_phi = sph_convert(wo)

        y_0_0_ = y_0_0(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))

        y_1_n1_ = y_1_n1(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))
        y_1_0_ = y_1_0(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))
        y_1_p1_ = y_1_p1(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))

        y_2_n2_ = y_2_n2(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))
        y_2_n1_ = y_2_n1(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))
        y_2_0_ = y_2_0(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))
        y_2_p1_ = y_2_p1(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))
        y_2_p2_ = y_2_p2(bsdf_val, wo_theta, wo_phi) / ek.select(
            pdf > 0, pdf, Float(0.01))

        return result, si.is_valid(), [ Float(y_0_0_[0]), Float(y_0_0_[1]), Float(y_0_0_[2]),\
                                        Float(y_1_n1_[0]), Float(y_1_n1_[1]), Float(y_1_n1_[2]),\
                                        Float(y_1_0_[0]), Float(y_1_0_[1]), Float(y_1_0_[2]),\
                                        Float(y_1_p1_[0]), Float(y_1_p1_[1]), Float(y_1_p1_[2]),\
                                        Float(y_2_n2_[0]), Float(y_2_n2_[1]), Float(y_2_n2_[2]),\
                                        Float(y_2_n1_[0]), Float(y_2_n1_[1]), Float(y_2_n1_[2]),\
                                        Float(y_2_0_[0]), Float(y_2_0_[1]), Float(y_2_0_[2]),\
                                        Float(y_2_p1_[0]), Float(y_2_p1_[1]), Float(y_2_p1_[2]),\
                                        Float(y_2_p2_[0]), Float(y_2_p2_[1]), Float(y_2_p2_[2]) ]