Пример #1
0
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)
Пример #2
0
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()
Пример #3
0
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
Пример #4
0
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()
Пример #5
0
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()
Пример #6
0
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
Пример #7
0
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)
Пример #8
0
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)))
Пример #9
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()
Пример #10
0
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()
Пример #11
0
    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,
Пример #12
0
'''
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()
Пример #13
0
    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)