def _parse_float(line): t = line.split('=', maxsplit=1) name = t.pop(0).strip() if len(t) == 0: return FloatArg(name, 0.0) v = float(t.pop(0).strip()) return FloatArg(name, v)
def light_sample(self, spectrum): area = (self.p1 - self.p0).cross(self.p2 - self.p0).length() * 0.5 inv_area = 1.0 / area code = """ r1 = random() tmp = 1.0 - r1 tmp = sqrt(tmp) beta = 1.0 - tmp gamma = tmp * random() shadepoint.light_position = (1.0 - beta - gamma) * p0 + beta * p1 + gamma * p2 shadepoint.light_pdf = inv_area shadepoint.light_normal = normal """ inv_area = FloatArg('inv_area', inv_area) normal = Vec3Arg('normal', self.normal) p0 = Vec3Arg('p0', self.p0) p1 = Vec3Arg('p1', self.p1) p2 = Vec3Arg('p2', self.p2) args = [inv_area, normal, p0, p1, p2] func_args = [StructArgPtr('hitpoint', HitPoint.factory()), StructArgPtr('shadepoint', ShadePoint.factory(spectrum))] name = 'triangle_sample_%i' % id(self) return Shader(code=code, args=args, name=name, func_args=func_args, is_func=True)
def light_sample(self, spectrum): area = self.edge_a.length() * self.edge_b.length() inv_area = 1.0 / area code = """ rnd = random2() shadepoint.light_pdf = inv_area shadepoint.light_normal = normal shadepoint.light_position = point + edge_a * rnd[0] + edge_b * rnd[1] """ inv_area = FloatArg('inv_area', inv_area) normal = Vec3Arg('normal', self.normal) point = Vec3Arg('point', self.point) eda = Vec3Arg('edge_a', self.edge_a) edb = Vec3Arg('edge_b', self.edge_b) args = [inv_area, normal, point, eda, edb] func_args = [ StructArgPtr('hitpoint', HitPoint.factory()), StructArgPtr('shadepoint', ShadePoint.factory(spectrum)) ] name = 'rect_sample_%i' % id(self) return Shader(code=code, args=args, name=name, func_args=func_args, is_func=True)
def _sampled_to_rgb_shader(sampled_mgr): code = """ x = cie_x * spec y = cie_y * spec z = cie_z * spec X = sum_samples(x) * scale Y = sum_samples(y) * scale Z = sum_samples(z) * scale r = 3.240479 * X - 1.537150 * Y - 0.498535 * Z g = -0.969256 * X + 1.875991 * Y + 0.041556 * Z b = 0.055648 * X - 0.204043 * Y + 1.057311 * Z return float3(r, g, b) """ spec = sampled_mgr.zero() spec_arg = SampledArgPtr('spec', 0, spec) scale = (sampled_mgr.end - sampled_mgr.start) / (sampled_mgr.yint * sampled_mgr.nsamples) p1 = FloatArg('scale', scale) cie_x = SampledArg('cie_x', sampled_mgr._cie_x) cie_y = SampledArg('cie_y', sampled_mgr._cie_y) cie_z = SampledArg('cie_z', sampled_mgr._cie_z) shader = Shader(code=code, args=[p1, cie_x, cie_y, cie_z], name='spectrum_to_rgb', func_args=[spec_arg], is_func=True) return shader
def args(self): self._tiles = tiles = create_tiles(self._width, self._height, self._nthreads) n = self.nsamples() subx, suby = self._subpixel_location() args = [IntArg('width', self._width), IntArg('height', self._height), FloatArg('pixelsize', self._pixelsize), IntArg('nsamples', n), IntArg('npass', self._pass), IntArg('subx', subx), IntArg('suby', suby)] targs = [StructArg('tile', tile) for tile in tiles] targ = ArgList('tile', targs) args.append(targ) curx_args = [IntArg('curx', 0) for tile in tiles] curx_arg = ArgList('curx', curx_args) args.append(curx_arg) cury_args = [IntArg('cury', tile.y) for tile in tiles] cury_arg = ArgList('cury', cury_args) args.append(cury_arg) endx_args = [IntArg('endx', tile.width) for tile in tiles] endx_arg = ArgList('endx', endx_args) args.append(endx_arg) endy_args = [IntArg('endy', tile.y + tile.height) for tile in tiles] endy_arg = ArgList('endy', endy_args) args.append(endy_arg) return args
def load(self, shader_name): args = [] text = self._loader.load(shader_name, 'props.txt') if text is not None: args = parse_args(text) w = Vec3Arg('w', self._w) u = Vec3Arg('u', self._u) v = Vec3Arg('v', self._v) distance = FloatArg('distance', self._distance) eye = Vec3Arg('eye', self._eye) lookat = Vec3Arg('lookat', self._lookat) args.extend([w, u, v, distance, eye, lookat]) code = self._loader.load(shader_name, 'code.py') if code is None: raise ValueError("code.py in %s shader dont exist!" % shader_name) func_args = [ StructArgPtr('ray', Ray.factory()), StructArgPtr('sample', Sample.factory()) ] self._shader_name = shader_name self.shader = Shader(code=code, args=args, name='generate_ray', func_args=func_args, is_func=True)
def load(self, shader_name): args = [] text = self._loader.load(shader_name, 'props.txt') if text is not None: args = parse_args(text) args.append(FloatArg('xwidth', self.xwidth)) args.append(FloatArg('ywidth', self.ywidth)) code = self._loader.load(shader_name, 'code.py') if code is None: raise ValueError("code.py in %s shader dont exist!" % shader_name) func_args = [StructArgPtr('sample', Sample.factory())] self.shader = Shader(code=code, args=args, name='filter_sample', func_args=func_args, is_func=True)
def isect_shader(cls, shader_name): code = """ temp = ray.origin - sphere.origin r_dir = ray.direction a = dot(r_dir, r_dir) b = dot(temp, r_dir) * 2.0 c = dot(temp, temp) - sphere.radius * sphere.radius disc = b * b - 4.0 * a * c if disc < 0.0: return 0 e = sqrt(disc) denom = 2.0 * a t = (-1.0 * b - e) / denom if t > 0.0005: if t < min_dist: normal = (temp + r_dir * t) * (1.0 / sphere.radius) hit = ray.origin + r_dir * t hitpoint.t = t hitpoint.normal = normal hitpoint.hit = hit hitpoint.mat_idx = sphere.mat_idx hitpoint.light_id = sphere.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 t = (-1.0 * b + e) / denom if t > 0.0005: if t < min_dist: normal = (temp + r_dir * t) * (1.0 / sphere.radius) hit = ray.origin + r_dir * t hitpoint.t = t hitpoint.normal = normal hitpoint.hit = hit hitpoint.mat_idx = sphere.mat_idx hitpoint.light_id = sphere.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 return 0 """ func_args = [ StructArgPtr('ray', Ray.factory()), StructArgPtr('sphere', Sphere.factory()), StructArgPtr('hitpoint', HitPoint.factory()), FloatArg('min_dist', 0.0) ] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def argument_factory(name, cls): if cls == int: return IntArg(name, int()) elif cls == float: return FloatArg(name, float()) elif cls == Vector3: return Vec3Arg(name, Vector3.zero()) else: raise ValueError("Argument factory. Unsuported arugment type", name, cls)
def test_rgb_area_light(self): sam_mgr = SampledManager() register_rgb_shadepoint() point = Vector3(0.0, 0.0, 55.92) e1 = Vector3(55.28, 0.0, 0.0) e2 = Vector3(0.0, 54.88, 0.0) normal = Vector3(0.0, 0.0, -1.0) rectangle = Rectangle(point, e1, e2, normal) material = Material() material.load('lambertian_emiter', sam_mgr) e = RGBSpectrum(0.5, 0.5, 0.5) material.set_value('emission', e) runtimes = [Runtime()] lgt = AreaLight(shape=rectangle, material=material) lgt.load('general', sam_mgr, spectral=False) lgt.compile() lgt.prepare(runtimes) ptrs = lgt.shader.get_ptrs() ptr_func = PointerArg('ptr_func', ptrs[0]) spec = RGBArg('spec', RGBSpectrum(0.5, 0.5, 0.5)) wi = Vec3Arg('wi', Vector3(0.0, 0.0, 0.0)) pos = Vec3Arg('position', Vector3(0.0, 0.0, 0.0)) n = Vec3Arg('normal', Vector3(0.0, 0.0, 0.0)) pdf = FloatArg('pdf', 0.0) emission = RGBArg('emission', RGBSpectrum(0.0, 0.0, 0.0)) code = """ hp = HitPoint() hp.hit = (4.0, 5, 6) sp = ShadePoint() __light_radiance(hp, sp, ptr_func) spec = sp.light_intensity wi = sp.wi position = sp.light_position normal = sp.light_normal pdf = sp.light_pdf emission = sp.material_emission """ shader = Shader(code=code, args=[ptr_func, wi, spec, pos, n, pdf, emission]) shader.compile() shader.prepare(runtimes) shader.execute() print("Position ", shader.get_value('position')) print("Normal ", shader.get_value('normal')) print("Light pdf ", shader.get_value('pdf')) print("Emission ", shader.get_value('emission')) print("Wi ", shader.get_value('wi')) print("Intensity ", shader.get_value('spec'))
def isect_shader(cls, shader_name): code = """ temp1 = dot(ray.direction, rectangle.normal) if temp1 == 0.0: return 0 tmp = rectangle.point - ray.origin t = dot(tmp, rectangle.normal) / temp1 if t < 0.00001: return 0 if t > min_dist: return 0 p = ray.origin + ray.direction * t d = p - rectangle.point ddota = dot(d, rectangle.edge_a) if ddota < 0.0: return 0 if ddota > rectangle.edge_a_squared: return 0 ddotb = dot(d, rectangle.edge_b) if ddotb < 0.0: return 0 if ddotb > rectangle.edge_b_squared: return 0 hitpoint.t = t hitpoint.normal = rectangle.normal hitpoint.hit = p hitpoint.mat_idx = rectangle.mat_idx hitpoint.light_id = rectangle.light_id hitpoint.u = 0.0 hitpoint.v = 0.0 return 1 """ func_args = [ StructArgPtr('ray', Ray.factory()), StructArgPtr('rectangle', Rectangle.factory()), StructArgPtr('hitpoint', HitPoint.factory()), FloatArg('min_dist', 0.0) ] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def light_pdf(self, spectrum): area = (self.p1 - self.p0).cross(self.p2 - self.p0).length() * 0.5 inv_area = 1.0 / area code = """ shadepoint.light_pdf = inv_area """ inv_area = FloatArg('inv_area', inv_area) args = [inv_area] func_args = [StructArgPtr('hitpoint', HitPoint.factory()), StructArgPtr('shadepoint', ShadePoint.factory(spectrum))] name = 'triangle_light_pdf_%i' % id(self) return Shader(code=code, args=args, name=name, func_args=func_args, is_func=True)
def isect_b_shader(cls, shader_name): label = 'ray_triangle_isect_b_%s' % id(cls) tri_isect = ray_triangle_isect_shader(label, isect_bool=True) code = """ return %s(ray, triangle.p0, triangle.p1, triangle.p2, min_dist) """ % label args = [] func_args = [StructArgPtr('ray', Ray.factory()), StructArgPtr('triangle', FlatTriangle.factory()), FloatArg('min_dist', 0.0)] shader = Shader(code=code, args=args, name=shader_name, func_args=func_args, is_func=True) isect_shader = DependencyShader(shader, [tri_isect]) return isect_shader
def test_material_sampling_manager(self): sam_mgr = SampledManager() register_rgb_shadepoint() runtimes = [Runtime(), Runtime()] mat = Material() mat.load('lambertian', sam_mgr, spectral=False) mat.set_value('diffuse', RGBSpectrum(0.2, 0.3, 0.4)) mgr = MaterialManager() mgr.add('material1', mat) mgr.compile_shaders(sam_mgr, spectral=False) mgr.prepare_shaders(runtimes) code = """ hp = HitPoint() hp.normal = (0.1, 0.4, 0.66) hp.normal = normalize(hp.normal) sp = ShadePoint() material_sampling(hp, sp, 0) pdf = sp.pdf wi = sp.wi spec = sp.material_reflectance """ pdf = FloatArg('pdf', 0.0) wi = Vec3Arg('wi', Vector3(0.0, 0.0, 0.0)) spec = RGBArg('spec', RGBSpectrum(0.5, 0.5, 0.5)) shader = Shader(code=code, args=[pdf, wi, spec]) shader.compile(shaders=[mgr.sampling_shader]) shader.prepare(runtimes) shader.execute() s = shader.get_value('pdf') print(s) s = shader.get_value('wi') print(s) s = shader.get_value('spec') print(s) normal = Vector3(0.1, 0.4, 0.66) normal.normalize() print(cos_hemisphere(r1=0.1, r2=0.06, normal=normal, e=1.0))
def _sampled_luminance_shader(sampled_mgr): code = """ y = cie_y * spec y_sum = sum_samples(y) return y_sum * scale """ spec = sampled_mgr.zero() spec_arg = SampledArgPtr('spec', 0, spec) scale = (sampled_mgr.end - sampled_mgr.start) / (sampled_mgr.yint * sampled_mgr.nsamples) p1 = FloatArg('scale', scale) cie_y = SampledArg('cie_y', sampled_mgr._cie_y) shader = Shader(code=code, args=[p1, cie_y], name='luminance', func_args=[spec_arg], is_func=True) return shader
def light_pdf(self, spectrum): area = self.edge_a.length() * self.edge_b.length() inv_area = 1.0 / area code = """ shadepoint.light_pdf = inv_area """ inv_area = FloatArg('inv_area', inv_area) args = [inv_area] func_args = [ StructArgPtr('hitpoint', HitPoint.factory()), StructArgPtr('shadepoint', ShadePoint.factory(spectrum)) ] name = 'rect_light_pdf_%i' % id(self) return Shader(code=code, args=args, name=name, func_args=func_args, is_func=True)
def isect_shader(self): origin = Vector3(0.0, 0.0, 0.0) direction = Vector3(0.0, 0.0, 0.0) ray = Ray(origin, direction) hitpoint = HitPoint(0.0, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), 0, 0.0, 0.0) func_args = [StructArgPtr('ray', ray), StructArgPtr('hitpoint', hitpoint), FloatArg('min_dist', 99999.0)] args = [] code = "hit_happend = 0\n" for shp_type in self.shp_mgr.shape_types(): code1, args1 = self._get_shape_code(shp_type) args.extend(args1) code += code1 code += "\nreturn hit_happend\n" shader = Shader(code=code, args=args, name='isect_scene', func_args=func_args, is_func=True) return shader
def isect_b_shader(cls, shader_name): code = """ temp = ray.origin - sphere.origin r_dir = ray.direction a = dot(r_dir, r_dir) b = dot(temp, r_dir) * 2.0 c = dot(temp, temp) - sphere.radius * sphere.radius disc = b * b - 4.0 * a * c if disc < 0.0: return 0 e = sqrt(disc) denom = 2.0 * a t = (-1.0 * b - e) / denom if t > 0.0005: if t < min_dist: return 1 t = (-1.0 * b + e) / denom if t > 0.0005: if t < min_dist: return 1 return 0 """ func_args = [ StructArgPtr('ray', Ray.factory()), StructArgPtr('sphere', Sphere.factory()), FloatArg('min_dist', 0.0) ] shader = Shader(code=code, args=[], name=shader_name, func_args=func_args, is_func=True) return DependencyShader(shader)
def isect_shader(cls, shader_name): label = 'ray_triangle_isect_%s' % id(cls) tri_isect = ray_triangle_isect_shader(label, isect_bool=False) code = """ ret = %s(ray, triangle.p0, triangle.p1, triangle.p2, min_dist, hitpoint) if ret: hitpoint.normal = triangle.normal hitpoint.u = 0.0 hitpoint.v = 0.0 hitpoint.mat_idx = triangle.mat_idx hitpoint.light_id = triangle.light_id return 1 else: return 0 """ % label args = [] origin = Vector3(0.0, 0.0, 0.0) direction = Vector3(0.0, 0.0, 0.0) ray = Ray(origin, direction) hitpoint = HitPoint(0.0, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), 0, 0.0, 0.0) triangle = FlatTriangle(Vector3(1.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), Vector3(0.0, 0.0, 1.0), 0) func_args = [StructArgPtr('ray', ray), StructArgPtr('triangle', triangle), StructArgPtr('hitpoint', hitpoint), FloatArg('min_dist', 0.0)] shader = Shader(code=code, args=args, name=shader_name, func_args=func_args, is_func=True) isect_shader = DependencyShader(shader, [tri_isect]) return isect_shader
def atest_material_glass(self): sam_mgr = SampledManager() register_rgb_shadepoint() runtimes = [Runtime()] mat = Material() mat.load('glass', sam_mgr, spectral=False) mat.set_value('ior', 1.5) mgr = MaterialManager() mgr.add('material1', mat) shaders = shaders_functions() for shader in shaders: shader.compile() shader.prepare(runtimes) mgr.compile_shaders(sam_mgr, spectral=False, shaders=shaders) mgr.prepare_shaders(runtimes) code = """ hp = HitPoint() hp.normal = normal sp = ShadePoint() sp.wo = wo material_sampling(hp, sp, 0) pdf = sp.pdf wi = sp.wi spec = sp.material_reflectance """ pdf = FloatArg('pdf', 0.0) wi = Vec3Arg('wi', Vector3(0.0, 0.0, 0.0)) ww = Vector3(5.0, 1.0, 0.0) ww.normalize() wo = Vec3Arg('wo', ww) nn = Vector3(0.0, 1.0, 0.0) nn.normalize() normal = Vec3Arg('normal', nn) spec = RGBArg('spec', RGBSpectrum(0.5, 0.5, 0.5)) shader = Shader(code=code, args=[pdf, wi, wo, normal, spec]) shader.compile(shaders=[mgr.sampling_shader]) shader.prepare(runtimes) shader.execute() s = shader.get_value('wi') print(s) s = shader.get_value('pdf') print(s) s = shader.get_value('spec') print(s) print('------------------------------') print('wo', ww) wi, pdf, ref = sampling_glass(1.5, ww, nn) print("wi", wi) print("pdf", pdf) print("ref", ref) ndotwi = abs(nn.dot(wi)) print("ndotwi", ndotwi) tmp = ndotwi / pdf path_weight = ref * tmp print("path weight", path_weight)
def ray_triangle_isect_shader(name, isect_bool=False): code = """ origin = ray.origin direction = ray.direction a = p0[0] - p1[0] b = p0[0] - p2[0] c = direction[0] d = p0[0] - origin[0] e = p0[1] - p1[1] f = p0[1] - p2[1] g = direction[1] h = p0[1]- origin[1] i = p0[2] - p1[2] j = p0[2] - p2[2] k = direction[2] l = p0[2] - origin[2] m = f * k - g * j n = h * k - g * l p = f * l - h * j q = g * i - e * k s = e * j - f * i temp3 = a * m + b * q + c * s if temp3 == 0.0: return 0 inv_denom = 1.0 / temp3 e1 = d * m - b * n - c * p beta = e1 * inv_denom if beta < 0.0: return 0 r = e * l - h * i e2 = a * n + d * q + c * r gamma = e2 * inv_denom if gamma < 0.0: return 0 betagamma = beta + gamma if betagamma > 1.0: return 0 e3 = a * p - b * r + d * s t = e3 * inv_denom epsilon = 0.00001 if t < 0.00001: return 0 if t > min_dist: return 0 """ if isect_bool: code += """ return 1 """ else: code += """ hitpoint.t = t hitpoint.hit = direction * t + origin hitpoint.u = beta hitpoint.v = gamma return 1 """ ray_a = StructArgPtr('ray', Ray.factory()) p0 = Vec3Arg('p0', Vector3(0.0, 0.0, 0.0)) p1 = Vec3Arg('p1', Vector3(0.0, 0.0, 0.0)) p2 = Vec3Arg('p2', Vector3(0.0, 0.0, 0.0)) dist = FloatArg('min_dist', 0.0) hit_a = StructArgPtr('hitpoint', HitPoint.factory()) if isect_bool: func_args = [ray_a, p0, p1, p2, dist] else: func_args = [ray_a, p0, p1, p2, dist, hit_a] shader = Shader(code=code, args=[], name=name, func_args=func_args, is_func=True) return shader