def main(): with open("output.ppm", "w") as f: nx, ny, ns = 200, 100, 100 header = "P3\n{} {}\n255\n".format(nx, ny) f.write(header) camera = Camera() sphere1 = Sphere(Vec3(0.0, 0.0, -1.0), 0.5, Lambertian(Vec3(0.8, 0.3, 0.3))) sphere2 = Sphere(Vec3(0.0, -100.5, -1.0), 100.0, Lambertian(Vec3(0.8, 0.8, 0.0))) sphere3 = Sphere(Vec3(1.0, 0.0, -1.0), 0.5, Metal(Vec3(0.8, 0.6, 0.2))) sphere4 = Sphere(Vec3(-1.0, 0.0, -1.0), 0.5, Metal(Vec3(0.8, 0.8, 0.8))) world = Hitable_list([sphere1, sphere2, sphere3, sphere4]) for j in range(ny - 1, -1, -1): for i in range(nx): col = Vec3(0.0, 0.0, 0.0) for k in range(0, ns): u = float(i + random()) / float(nx) v = float(j + random()) / float(ny) ray = camera.get_ray(u, v) col += color(ray, world, 0) col /= float(ns) col = Vec3(sqrt(col.e0), sqrt(col.e1), sqrt(col.e2)) ir = int(255.99 * col.r()) ig = int(255.99 * col.g()) ib = int(255.99 * col.b()) line = "{} {} {}\n".format(ir, ig, ib) f.write(line)
def main(): # nx = 100 # ny = 100 # ns = 10 nx = 1000 ny = 1000 ns = 100 f = open("generated_images/balls_world_fuzz_glass.ppm", "w") f.write("P3\n%d %d\n255\n" % (nx, ny)) cam = Camera(look_from=Vec3(0.5,0.5,0.0), look_at=Vec3(0.0,0.5,-1.0), vec_up=Vec3(0.0, 1.0, 0.0), v_fov=90.0, aspect=nx/ny, aperture=0.0, focus_dist=1.0) world = Object3DList( [Sphere(Vec3(0.0, -1000.0, -1.0), 1000.0, Lambertian(albedo=Vec3(0.8, 0.8, 0.8))), Sphere(Vec3(0.0, 0.5, -1.0), 0.5, Lambertian(albedo=Vec3(0.8, 0.3, 0.3))), Sphere(Vec3(0.0, 0.1, -0.5), 0.1, Lambertian(albedo=Vec3(0.5, 0.2, 0.5))), Sphere(Vec3(-0.2, 0.5, -0.3), 0.1, Dielectric(ref_idx=1.5)), Sphere(Vec3(0.75, 0.25, -0.5), 0.25, Metal(albedo=Vec3(0.6, 0.8, 0.8), fuzz=0.02)), Sphere(Vec3(-0.75, 0.25, -0.75), 0.25, Metal(albedo=Vec3(0.8, 0.6, 0.2), fuzz=0.0)) ]) # Note break with guide convention, vertical pixels start with index 0 at top for y in range(0, ny): for x in range(0, nx): col = Vec3(0.0, 0.0, 0.0) for _ in range(0, ns): u = (float(x) + random.random()) / float(nx) v = (float(y) + random.random()) / float(ny) r = cam.get_ray(u, v) col += color(r, world, 0) print(y*100000 + x*ns + _) col /= ns col = col ** 0.5 f.write(col.color_string(scale=255.99)) f.close()
def three_spheres(i, j, nx, ny, num_samples=100): s1 = Sphere(Vec3(0, 0, -1), 0.5, Lambertian(Vec3(0.1, 0.2, 0.5))) s2 = Sphere(Vec3(0, -100.5, -1), 100, Lambertian(Vec3(0.8, 0.8, 0.0))) s3 = Sphere(Vec3(-1, 0, -1), 0.5, Dielectric(2.5)) s4 = Sphere(Vec3(1, 0, -1), 0.5, Metal(Vec3(0.8, 0.6, 0.2), 0.0)) spheres = HitableList([s1, s2, s3, s4]) cam = Camera() # cam = Camera(origin = Vec3(0, 0, 0), # lower_left_corner = Vec3(-3, -1.5, -1), # horizontal = Vec3(6, 0, 0), # vertical = Vec3(0, 3, 0)) def color(r, world, depth): if world.hit(r, 0.001, float("inf")): scattered, attenuation = world.matrl.scatter( r, world.p, world.normal) if not scattered or depth >= 50: return Vec3(0, 0, 0) return color(scattered, world, depth + 1) * attenuation else: v = r.direction().unit_vector( ) # use y-coordinate of unit direction to scale blueness t = (v.y() + 1) / 2 # ranges between 0 and 1 return Vec3(255.99, 255.99, 255.99) * (1 - t) + Vec3( 255.99 * 0.5, 255.99 * 0.7, 255.99) * t col = Vec3(0, 0, 0) for k in range(num_samples): col += color( cam.get_ray((i + random.random()) / nx, (j + random.random()) / ny), spheres, 0) return col / num_samples
def main(): # nx = 1000 # ny = 500 # ns = 30 nx = 200 ny = 100 ns = 10 f = open("generated_images/balls_world_fuzz.ppm", "w") f.write("P3\n%d %d\n255\n" % (nx, ny)) cam = Camera(upper_left_corner=Vec3(-2.0, 1.5, -1.0), horizontal=Vec3(4.0, 0.0, 0.0), vertical=Vec3(0.0, -2.0, 0.0), origin=Vec3(0.0, 0.5, 0.0)) world = Object3DList([ Sphere(Vec3(0.0, -1000.0, -1.0), 1000.0, Lambertian(albedo=Vec3(0.8, 0.8, 0.8))), Sphere(Vec3(0.0, 0.5, -1.0), 0.5, Lambertian(albedo=Vec3(0.8, 0.3, 0.3))), Sphere(Vec3(0.0, 0.1, -0.5), 0.1, Lambertian(albedo=Vec3(0.5, 0.2, 0.5))), Sphere(Vec3(0.75, 0.25, -0.5), 0.25, Metal(albedo=Vec3(0.6, 0.8, 0.8), fuzz=0.5)), Sphere(Vec3(-0.75, 0.25, -0.75), 0.25, Metal(albedo=Vec3(0.8, 0.6, 0.2), fuzz=0.0)) ]) # Note break with guide convention, vertical pixels start with index 0 at top for y in range(0, ny): for x in range(0, nx): col = Vec3(0.0, 0.0, 0.0) for _ in range(0, ns): u = (float(x) + random.random()) / float(nx) v = (float(y) + random.random()) / float(ny) r = cam.get_ray(u, v) col += color(r, world, 0) col /= ns col = col**0.5 f.write(col.color_string(scale=255.99)) f.close()
def main(): categories = [ Category("Stocks", Stock.factory()), Category("Bank deposits", BankDeposit.factory()), Category("Precious metals", Metal.factory()), Category("Bonds", Bond.factory()) ] root = Tk() menu = Menu(root, categories) menu.mainloop()
def random_scene(): scene = [] scene.append( Sphere(Vec3(0, -1000, 0), 1000, Lambertian(Vec3(0.5, 0.5, 0.5)))) i = 1 for a in range(-11, 11): for b in range(-11, 11): choose_mat = random.random() center = Vec3(a + 0.9 * random.random(), 0.2, b + 0.9 * random.random()) if ((center - Vec3(4, 0.2, 0)).length > 0.9): if (choose_mat < 0.8): scene.append( Sphere( center, 0.2, Lambertian( Vec3(random.random() * random.random(), random.random() * random.random(), random.random() * random.random())))) elif (choose_mat < 0.95): scene.append( Sphere( center, 0.2, Metal( Vec3(0.5 * (1 + random.random()), 0.5 * (1 + random.random()), 0.5 * (1 + random.random())), 0.5 * random.random()))) else: scene.append(Sphere(center, 0.2, Dielectric(1.5))) scene.append(Sphere(Vec3(0, 1, 0), 1.0, Dielectric(1.5))) scene.append(Sphere(Vec3(-4, 1, 0), 1.0, Lambertian(Vec3(0.4, 0.2, 0.1)))) scene.append(Sphere(Vec3(4, 1, 0), 1.0, Metal(Vec3(0.7, 0.6, 0.5), 0.0))) return scene
def populate_world() -> Object3DList: obj_list = [Sphere(Vec3(0.0, -1000.0, -0.0), 1000.0, Lambertian(albedo=Vec3(0.8, 0.8, 0.8))) ] sphere_radius = 0.5 for idx in range(0, 3): for idz in range(0, 3): for idy in range(0, 3): pos = Vec3( (idx - 1) * 4 * sphere_radius, (2 * idy + 1) * sphere_radius, (idz - 1) * 4 * sphere_radius) n = random.random() if n < 0.33: alb = 0.8 * Vec3(random.random(), random.random(), random.random()) obj_list.append( Sphere(pos, sphere_radius, Lambertian(albedo=alb))) elif n >= 0.33 and n < 0.66: alb = 0.8 * Vec3(random.random(), random.random(), random.random()) fuzz = 0.2 * random.random() obj_list.append( Sphere(pos, sphere_radius, Metal(albedo=alb, fuzz=fuzz))) else: ref_idx = random.random() * 0.5 + 1 obj_list.append( Sphere(pos, sphere_radius, Dielectric(ref_idx=ref_idx))) return Object3DList(obj_list)
def test_Metal(): monte_carlo_metal_source = ''' #include <metal_stdlib> using namespace metal; kernel void monte_carlo( const device float2 *in_points [[buffer(0)]], // input points(x,y) device atomic_uint &counter [[buffer(1)]], // generated counter uint pos [[thread_position_in_grid]]) { if (length(in_points[pos]) < 1.0) atomic_fetch_add_explicit(&counter, 1, memory_order_relaxed); } ''' print('generating pi using monte carlo metal code') size = 1024 * 4 s2 = size**2 m = Metal(monte_carlo_metal_source) # , 'monte_carlo') # size*size x,y pairs input and one int output set to 0 m.set_buffers(buffers=(m.buffer(Metal.rand(s2 * 2, numpy.float32)), cnt_buf := m.buffer(0)))
s: float32 = 0 sq: float32 = 0 n: int = len(data) for i in prange(n): s += data[i] sq += sqr(data[i]) return s / n, sqrt((sq - sqr(s) / n) / (n - 1)) # mean, std print('metal random generator') t0 = lap() m = Metal('random.metal', 'randomf') t0 = lap() - t0 sz = 16 n = 1024 * sz print(f'metal compiled in {t0:.2} run random on size {n * n:,}', end='') # create i/o buffers to match kernel func. params brand = m.empty_float(n * n) # output bseeds = m.float_buf(np.random.randint(0, 1000000, (3, ), dtype='u4')) # 3 seeds input m.set_buffers(buffers=(brand, bseeds), threads=(n, n)) t = lap()
import numpy as np from PIL import Image from metal import Metal predef_funcs = ['acos(c(1,2)*log(sin(z*z*z-1)/z))', 'c(1,1)*log(sin(z*z*z-1)/z)', 'c(1,1)*sin(z)', 'z + z*z/sin(z*z*z*z-1)', 'log(sin(z))', 'cos(z)/(sin(z*z*z*z-1))', 'z*z*z*z*z*z-1', '(z*z-1) * pow((z-c(2,1)),2) / (z*z+c(2,1))', 'sin(z)*c(1,2)', 'sin(c(1)/z)', 'sin(z)*sin(c(1)/z)', 'c(1)/sin(c(1)/sin(z))', 'z', '(z*z+1)/(z*z-1)', '(z*z+c(1))/z', '(z+3)*pow((z+1),2)', 'pow((z/c(2)),2)*(z+c(1,2))*(z+c(2,2))/(z*z*z)', '(z*z)-0.75-c(0,0.2)', 'z*sin(z/cos(sin(c(2.2)/z)*tan(z)))'] # replace in original metal file %%FUNC%% by string z expression for fz in predef_funcs: metal_file, func_name = Metal.file_replace(file_in='dc.metal', file_out='dcz.metal', search_str='%%FUNC%%', rpl_str=fz) t0 = lap() m = Metal(metal_file, func_name) t0 = lap() - t0 sz = 4 w, h = 640 * sz, 480 * sz print(f'compiled in {t0:.2} run dc on size {w, h}', end='') bgeo = m.buffer(np.array([w, h], dtype=np.int32)) bpix = m.empty(w * h * 4) m.set_buffers(buffers=(bpix, bgeo), threads=(w, h)) t = lap()
ny = 200 ns = 100 num_of_processes = 2 assert (ns % 2 != 0) with open('output.ppm', 'w') as out: out.write(f"P3\n{nx} {ny}\n255\n") sphere_list = [] sphere_list.append( Sphere(Vec3(1.0, 0.0, -1.0), 0.5, Lambertian(Vec3(0.1, 0.2, 0.5)))) sphere_list.append( Sphere(Vec3(0.0, 0.0, -1.0), 0.5, Metal(Vec3(0.8, 0.8, 0.8), 1.0))) sphere_list.append( Sphere(Vec3(0.0, -100.5, -1), 100, Lambertian(Vec3(0.8, 0.8, 0.0)))) sphere_list.append(Sphere(Vec3(-1.0, 0.0, -1.0), 0.5, Dielectric(1.5))) sphere_list.append( Sphere(Vec3(-1.0, 0.0, -1.0), -0.45, Dielectric(1.5))) world = HitableList(sphere_list) lookfrom = Vec3(3, 3, 2) lookat = Vec3(0, 0, -1) dist_to_focus = (lookfrom - lookat).length aperture = 1.0 camera = Camera(lookfrom, lookat, Vec3(0, 1, 0), 30, nx / ny, aperture,
''' test for fractal metal app. with several funcs directly replace in source code ''' from timeit import default_timer as lap import numpy as np from PIL import Image from metal import Metal t0 = lap() m = Metal('fractal.metal', 'fractal') t0 = lap() - t0 sz = 4 w, h = 640 * sz, 480 * sz print(f'compiled in {t0:.2} run fractal on size {w, h}={w * h} pix', end='') # create i/o buffers to match kernel func. params bsize = m.int_buf([w, h]) # input: size(w,h), center(x,y), range(x,y) bcenter = m.float_buf([0.5, 0]) brange = m.float_buf([-2, 2]) bpix = m.empty_int(w * h) # output m.set_buffers(buffers=(bpix, bsize, bcenter, brange), threads=(w, h)) t = lap() m.run()
else: unit_direction = r.direction.unit_vector() t = (unit_direction.y + 1.0) * 0.5 return Vec3(1.0, 1.0, 1.0) * (1.0 - t) + Vec3(0.5, 0.7, 1.0) * t nx = 200 ny = 100 ns = 100 print('P3\n%d %d 255' % (nx, ny)) sphere1 = Sphere(Vec3(0.0, 0.0, -1.0), 0.5, Lambertian(Vec3(0.8, 0.3, 0.3))) sphere2 = Sphere(Vec3(0.0, -100.5, -1.0), 100.0, Lambertian(Vec3(0.8, 0.8, 0.0))) sphere3 = Sphere(Vec3(1.0, 0.0, -1.0), 0.5, Metal(Vec3(0.8, 0.6, 0.2), 0.3)) sphere4 = Sphere(Vec3(-1.0, 0.0, -1.0), 0.5, Metal(Vec3(0.8, 0.8, 0.8), 1.0)) hlist = [sphere1, sphere2, sphere3, sphere4] world = HitableList(hlist) cam = Camera() for j in range(ny)[::-1]: for i in range(nx): col = Vec3(0.0, 0.0, 0.0) for s in range(ns): u = (float(i) + random()) / float(nx) v = (float(j) + random()) / float(ny) r = cam.get_ray(u, v) p = r.point_at_parameter(2.0)