def rcp_(a0): if not a0.IsFloat: raise Exception("rcp(): requires floating point operands!") ar, sr = _check1(a0) if not a0.IsSpecial: for i in range(sr): ar[i] = _ek.rcp(a0[i]) elif a0.IsComplex or a0.IsQuaternion: return _ek.conj(a0) * _ek.rcp(_ek.squared_norm(a0)) else: raise Exception('rcp(): unsupported array type!') return ar
def test15_test_avx512_approx(): Float = get_class('enoki.llvm.Float') x = ek.linspace(Float, 0, 10, 1000) o = ek.full(Float, 1, 1000) assert ek.allclose(ek.rsqrt(x), o / ek.sqrt(x), rtol=2e-7, atol=0) assert ek.allclose(ek.rcp(x), o / x, rtol=2e-7, atol=0)
def polar_decomp(a, it=10): q = type(a)(a) for i in range(it): qi = _ek.inverse_transpose(q) gamma = _ek.sqrt(_ek.frob(qi) / _ek.frob(q)) s1, s2 = gamma * .5, (_ek.rcp(gamma) * .5) for i in range(a.Size): q[i] = _ek.fmadd(q[i], s1, qi[i] * s2) return q, transpose(q) @ a
def rsqrt_(a0): if not a0.IsFloat: raise Exception("rsqrt(): requires floating point operands!") if not a0.IsSpecial: ar, sr = _check1(a0) for i in range(sr): ar[i] = _ek.rsqrt(a0[i]) return ar else: return _ek.rcp(_ek.sqrt(a0))
def sample_direction(self, ref, sample, active): trafo = self.m_world_transform.eval(ref.time, active) ds = DirectionSample3f() ds.p = trafo.matrix[3][:3] ds.n = 0 ds.uv = 0 ds.time = ref.time ds.pdf = 1 ds.delta = True ds.d = ds.p - ref.p ds.dist = ek.norm(ds.d) inv_dist = ek.rcp(ds.dist) ds.d *= inv_dist si = SurfaceInteraction3f() si.wavelengths = ref.wavelengths spec = self.m_intensity.eval(si, active) * (inv_dist * inv_dist) return (ds, spec)
def sqrt_(a0): if not a0.IsFloat: raise Exception("sqrt(): requires floating point operands!") ar, sr = _check1(a0) if not a0.IsSpecial: for i in range(sr): ar[i] = _ek.sqrt(a0[i]) elif a0.IsComplex: n = abs(a0) m = a0.real >= 0 zero = _ek.eq(n, 0) t1 = _ek.sqrt(.5 * (n + abs(a0.real))) t2 = .5 * a0.imag / t1 im = _ek.select(m, t2, _ek.copysign(t1, a0.imag)) ar.real = _ek.select(m, t1, abs(t2)) ar.imag = _ek.select(zero, 0, im) elif a0.IsQuaternion: ri = _ek.norm(a0.imag) cs = _ek.sqrt(a0.Complex(a0.real, ri)) ar.imag = a0.imag * (_ek.rcp(ri) * cs.imag) ar.real = cs.real else: raise Exception("sqrt(): unsupported array type!") return ar
def eval(self, value): self.value = value self.inv_norm = ek.rcp(ek.norm(value)) return value * self.inv_norm
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
import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap plt.rcParams["font.family"] = "serif" plt.rcParams["mathtext.fontset"] = "dejavuserif" print("Load normal mapped ring scene ..") scene_path = "ring_notebook_normalmapped.xml" scene = mitsuba.core.xml.load_file(scene_path) camera = scene.sensors()[0] integrator = scene.integrator() res = camera.film().size() res //= 2 inv_res = ek.rcp(ek.scalar.Vector2f(res)) emitter = scene.shapes()[0] spec_shape = scene.shapes()[1] sampler = mitsuba.core.xml.load_string( "<sampler version='2.0.0' type='independent'/>") sms_config = SMSConfig() sms_config.max_iterations = 20 sms_config.solver_threshold = 1e-5 sms_config.halfvector_constraints = True mf = SpecularManifoldSingleScatter(scene, sms_config) seed = 1
def test05_rcp(): assert ek.allclose(ek.rcp(C(1, 3)), C(1 / 10, -3 / 10))
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!')