def test30_acos(m): x = ek.linspace(m.Float, -.8, .8, 10) ek.enable_grad(x) y = ek.acos(x * x) ek.backward(y) acos_x = ek.acos(ek.sqr(ek.detach(x))) assert ek.allclose(y, acos_x) assert ek.allclose( ek.grad(x), m.Float(2.08232, 1.3497, 0.906755, 0.534687, 0.177783, -0.177783, -0.534687, -0.906755, -1.3497, -2.08232))
def test04_normal_weighting_scheme(variant_scalar_rgb): from mitsuba.core import Vector3f from mitsuba.render import Mesh import numpy as np """Tests the weighting scheme that is used to compute surface normals.""" m = Mesh("MyMesh", 5, 2, has_vertex_normals=True) vertices = m.vertex_positions_buffer() normals = m.vertex_normals_buffer() a, b = 1.0, 0.5 vertices[:] = [0, 0, 0, -a, 1, 0, a, 1, 0, -b, 0, 1, b, 0, 1] n0 = Vector3f(0.0, 0.0, -1.0) n1 = Vector3f(0.0, 1.0, 0.0) angle_0 = ek.pi / 2.0 angle_1 = ek.acos(3.0 / 5.0) n2 = n0 * angle_0 + n1 * angle_1 n2 /= ek.norm(n2) n = np.vstack([n2, n0, n0, n1, n1]).transpose() m.faces_buffer()[:] = [0, 1, 2, 0, 3, 4] m.recompute_vertex_normals() for i in range(5): assert ek.allclose(normals[i * 3:(i + 1) * 3], n[:, i], 5e-4)
def test09_trig(): for i in range(-5, 5): for j in range(-5, 5): a = ek.sin(C(i, j)) b = C(cmath.sin(complex(i, j))) assert ek.allclose(a, b) a = ek.cos(C(i, j)) b = C(cmath.cos(complex(i, j))) assert ek.allclose(a, b) sa, ca = ek.sincos(C(i, j)) sb = C(cmath.sin(complex(i, j))) cb = C(cmath.cos(complex(i, j))) assert ek.allclose(sa, sb) assert ek.allclose(ca, cb) # Python appears to handle the branch cuts # differently from Enoki, C, and Mathematica.. a = ek.asin(C(i, j + 0.1)) b = C(cmath.asin(complex(i, j + 0.1))) assert ek.allclose(a, b) a = ek.acos(C(i, j + 0.1)) b = C(cmath.acos(complex(i, j + 0.1))) assert ek.allclose(a, b) if abs(j) != 1 or i != 0: a = ek.atan(C(i, j)) b = C(cmath.atan(complex(i, j))) assert ek.allclose(a, b, atol=1e-7)
def fallof(self, cosTheta): # delta = (cosTheta - self.cosTotalWidth)/(self.cosFallOffStart - self.cosTotalWidth) delta = (self.cutOffAngle - ek.acos(cosTheta)) * self.m_invTransitionWidth delta = ek.select(cosTheta > self.cosFallOffStart, ek.full(type(delta), 1), delta) delta = ek.select(cosTheta < self.cosTotalWidth, ek.zero(type(delta)), delta) return delta
def test04_snell(variant_packet_rgb): from mitsuba.render import fresnel # Snell's law theta_i = ek.linspace(Float, 0, ek.pi / 2, 20) F, cos_theta_t, _, _ = fresnel(ek.cos(theta_i), 1.5) theta_t = ek.acos(cos_theta_t) assert ek.allclose(ek.sin(theta_i) - 1.5 * ek.sin(theta_t), Float.zero(20), atol=1e-5)
def test_sample_direction(variant_scalar_spectral, spectrum_key, it_pos, wavelength_sample, cutoff_angle, lookat): # Check the correctness of the sample_direction() method import math from mitsuba.core import sample_shifted, Transform4f from mitsuba.render import SurfaceInteraction3f cutoff_angle_rad = math.radians(cutoff_angle) beam_width_rad = cutoff_angle_rad * 0.75 inv_transition_width = 1 / (cutoff_angle_rad - beam_width_rad) emitter, spectrum = create_emitter_and_spectrum(lookat, cutoff_angle, spectrum_key) eval_t = 0.3 trafo = Transform4f(emitter.world_transform().eval(eval_t)) # Create a surface iteration it = SurfaceInteraction3f.zero() it.p = it_pos it.time = eval_t # Sample a wavelength from spectrum wav, spec = spectrum.sample(it, sample_shifted(wavelength_sample)) it.wavelengths = wav # Direction from the position to the point emitter d = -it.p + lookat["pos"] dist = ek.norm(d) d /= dist # Calculate angle between lookat direction and ray direction angle = ek.acos((trafo.inverse().transform_vector(-d))[2]) angle = ek.select( ek.abs(angle - beam_width_rad) < 1e-3, beam_width_rad, angle) angle = ek.select( ek.abs(angle - cutoff_angle_rad) < 1e-3, cutoff_angle_rad, angle) # Sample a direction from the emitter ds, res = emitter.sample_direction(it, [0, 0]) # Evalutate the spectrum spec = spectrum.eval(it) spec = ek.select( angle <= beam_width_rad, spec, spec * ((cutoff_angle_rad - angle) * inv_transition_width)) spec = ek.select(angle <= cutoff_angle_rad, spec, 0) assert ds.time == it.time assert ds.pdf == 1.0 assert ds.delta assert ek.allclose(ds.d, d) assert ek.allclose(res, spec / (dist**2))
def acos_(a0): if not a0.IsFloat: raise Exception("acos(): requires floating point operands!") ar, sr = _check1(a0) if not a0.IsSpecial: for i in range(sr): ar[i] = _ek.acos(a0[i]) elif a0.IsSpecial: tmp = _ek.sqrt(1 - _ek.sqr(a0)) tmp = _ek.log(a0 + type(a0)(-tmp.imag, tmp.real)) ar.real = tmp.imag ar.imag = -tmp.real else: raise Exception("acos(): unsupported array type!") return ar
def test_sample_ray(variant_packet_spectral, spectrum_key, wavelength_sample, pos_sample, cutoff_angle, lookat): # Check the correctness of the sample_ray() method import math from mitsuba.core import warp, sample_shifted, Transform4f from mitsuba.render import SurfaceInteraction3f cutoff_angle_rad = math.radians(cutoff_angle) cos_cutoff_angle_rad = math.cos(cutoff_angle_rad) beam_width_rad = cutoff_angle_rad * 0.75 inv_transition_width = 1 / (cutoff_angle_rad - beam_width_rad) emitter, spectrum = create_emitter_and_spectrum(lookat, cutoff_angle, spectrum_key) eval_t = 0.3 trafo = Transform4f(emitter.world_transform().eval(eval_t)) # Sample a local direction and calculate local angle dir_sample = pos_sample # not being used anyway local_dir = warp.square_to_uniform_cone(pos_sample, cos_cutoff_angle_rad) angle = ek.acos(local_dir[2]) angle = ek.select( ek.abs(angle - beam_width_rad) < 1e-3, beam_width_rad, angle) angle = ek.select( ek.abs(angle - cutoff_angle_rad) < 1e-3, cutoff_angle_rad, angle) # Sample a ray (position, direction, wavelengths) from the emitter ray, res = emitter.sample_ray(eval_t, wavelength_sample, pos_sample, dir_sample) # Sample wavelengths on the spectrum it = SurfaceInteraction3f.zero() wav, spec = spectrum.sample(it, sample_shifted(wavelength_sample)) it.wavelengths = wav spec = spectrum.eval(it) spec = ek.select( angle <= beam_width_rad, spec, spec * ((cutoff_angle_rad - angle) * inv_transition_width)) spec = ek.select(angle <= cutoff_angle_rad, spec, 0) assert ek.allclose( res, spec / warp.square_to_uniform_cone_pdf( trafo.inverse().transform_vector(ray.d), cos_cutoff_angle_rad)) assert ek.allclose(ray.time, eval_t) assert ek.all(local_dir.z >= cos_cutoff_angle_rad) assert ek.allclose(ray.wavelengths, wav) assert ek.allclose(ray.d, trafo.transform_vector(local_dir)) assert ek.allclose(ray.o, lookat["pos"])
def log_(a0): if not a0.IsFloat: raise Exception("log(): requires floating point operands!") ar, sr = _check1(a0) if not a0.IsSpecial: for i in range(sr): ar[i] = _ek.log(a0[i]) elif a0.IsComplex: ar.real = .5 * _ek.log(_ek.squared_norm(a0)) ar.imag = _ek.arg(a0) elif a0.IsQuaternion: qi_n = _ek.normalize(a0.imag) rq = _ek.norm(a0) acos_rq = _ek.acos(a0.real / rq) log_rq = _ek.log(rq) ar.imag = qi_n * acos_rq ar.real = log_rq else: raise Exception("log(): unsupported array type!") return ar
def test04_normal_weighting_scheme(variant_scalar_rgb): from mitsuba.core import Struct, float_dtype, Vector3f from mitsuba.render import Mesh import numpy as np """Tests the weighting scheme that is used to compute surface normals.""" vertex_struct = Struct() \ .append("x", Struct.Type.Float32) \ .append("y", Struct.Type.Float32) \ .append("z", Struct.Type.Float32) \ .append("nx", Struct.Type.Float32) \ .append("ny", Struct.Type.Float32) \ .append("nz", Struct.Type.Float32) index_struct = Struct() \ .append("i0", Struct.Type.UInt32) \ .append("i1", Struct.Type.UInt32) \ .append("i2", Struct.Type.UInt32) m = Mesh("MyMesh", vertex_struct, 5, index_struct, 2) v = m.vertices() a, b = 1.0, 0.5 v['x'] = Float([0, -a, a, -b, b]) v['y'] = Float([0, 1, 1, 0, 0]) v['z'] = Float([0, 0, 0, 1, 1]) n0 = Vector3f(0.0, 0.0, -1.0) n1 = Vector3f(0.0, 1.0, 0.0) angle_0 = ek.pi / 2.0 angle_1 = ek.acos(3.0 / 5.0) n2 = n0 * angle_0 + n1 * angle_1 n2 /= ek.norm(n2) n = np.vstack([n2, n0, n0, n1, n1]) f = m.faces() f[0] = (0, 1, 2) f[1] = (0, 3, 4) m.recompute_vertex_normals() assert ek.allclose(v['nx'], n[:, 0], 5e-4) assert ek.allclose(v['ny'], n[:, 1], 5e-4) assert ek.allclose(v['nz'], n[:, 2], 5e-4)
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)
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)