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))
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)
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
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))))
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
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
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
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]) ]