Exemple #1
0
    def basic(self):
        self.lookfrom = np.array([3.0, 3.0, 2.0])
        self.lookat = np.array([0.0, 0.0, -1.0])
        self.vup = np.array([0.0, 1.0, 0.0])
        self.vfov = 20.0
        # self.aperature = 2.0
        # self.focus_dist = ru.length(self.lookfrom - self.lookat)

        self.camera = Camera(self.img_width, self.img_height, self.lookfrom,
                             self.lookat, self.vup, self.vfov, self.aperature,
                             self.focus_dist)

        mat_ground = Lambertian(np.array([0.8, 0.8, 0.0]))
        mat_center = Lambertian(np.array([0.1, 0.2, 0.5]))
        mat_left = Dielectric(1.5)
        mat_right = Metal(np.array([0.8, 0.6, 0.2]), 0.0)

        self.world.add(Sphere(np.array([0.0, -100.5, -1.0]), 100, mat_ground))
        self.world.add(Sphere(np.array([0.0, 0.0, -1.0]), 0.5, mat_center))
        self.world.add(Sphere(np.array([-1.0, 0.0, -1.0]), 0.5, mat_left))
        self.world.add(Sphere(np.array([-1.0, 0.0, -1.0]), -0.45, mat_left))
        self.world.add(Sphere(np.array([1.0, 0.0, -1.0]), 0.5, mat_right))

        self.world.add(
            BVHNode(self.world.objects, 0, len(self.world.objects), 0, 1))
        self.background = np.array([0.7, 0.8, 1.0])
Exemple #2
0
def random_scene():
    hitables = []
    hitables.append(
        Sphere(Vec3(0, -1000, 0), 1000, Lambertian(Vec3(0.5, 0.5, 0.5))))
    for a in range(-11, 11):
        for b in range(-11, 11):
            choose_mat = random()
            center = Vec3(a + 0.9 * random(), 0.2, b + 0.9 * random())
            if (center - Vec3(4, 0.2, 0)).length > 0.9:
                if choose_mat < 0.8:
                    hitables.append(
                        Sphere(
                            center, 0.2,
                            Lambertian(
                                Vec3(random() * random(),
                                     random() * random(),
                                     random() * random()))))
                elif choose_mat < 0.95:
                    hitables.append(
                        Sphere(
                            center, 0.2,
                            Metal(
                                Vec3(0.5 * (1 + random()),
                                     0.5 * (1 + random()),
                                     0.5 * (1 + random())), 0.5 * random())))
                else:
                    hitables.append(Sphere(center, 0.2, Dielectric(1.5)))
    hitables.append(Sphere(Vec3(0, 1, 0), 1.0, Dielectric(1.5)))
    hitables.append(
        Sphere(Vec3(-4, 1, 0), 1.0, Lambertian(Vec3(0.4, 0.2, 0.1))))
    hitables.append(Sphere(Vec3(4, 1, 0), 1.0, Metal(Vec3(0.7, 0.6, 0.5),
                                                     0.0)))
    return HitableList(hitables)
def two_spheres():
    l = []
    checker = CheckerTexture(ConstantTexture(Vec3(0.2, 0.3, 0.1)),
                             ConstantTexture(Vec3(0.9, 0.9, 0.9)))
    l.append(Sphere(Vec3(0.0, -10.0, 0.0), 10, Lambertian(checker)))
    l.append(Sphere(Vec3(0.0, 10.0, 0.0), 10, Lambertian(checker)))
    return HitableList(l)
Exemple #4
0
def make_world():
    world = []
    ground = Lambertian(Color(0.5, 0.5, 0.5))
    world.append(Sphere(Point3(0, -1000, 0), 1000, ground))
    num_balls = 2
    for x in range(-num_balls, num_balls):
        for y in range(-num_balls, num_balls):
            mat = random()
            center = Point3(x + 0.9 * random(), 0.2, y + 0.9 * random())

            if (SubtractVectors(center, Point3(4, 0.2, 0)).length() > 0.9):
                if mat < 0.8:
                    color = Color(random(), random(), random())
                    sphere_mat = Lambertian(color)
                    world.append(Sphere(center, 0.2, sphere_mat))
                elif mat < 0.95:
                    color = Color(random(), random(), random())
                    fuzz = random() * 0.5
                    sphere_mat = Metal(color, fuzz)
                    world.append(Sphere(center, 0.2, sphere_mat))
                else:
                    sphere_mat = Dialectric(1.5)
                    world.append(Sphere(center, 0.2, sphere_mat))
    mat1 = Dialectric(1.5)
    world.append(Sphere(Point3(0, 1, 0), 1.0, mat1))
    mat2 = Lambertian(Color(0.4, 0.2, 0.1))
    world.append(Sphere(Point3(-4, 1, 0), 1.0, mat2))
    mat3 = Metal(Color(0.7, 0.6, 0.5), 0.0)
    world.append(Sphere(Point3(4, 1, 0), 1.0, mat3))
    return world
Exemple #5
0
def main():

    # image dimensions (pixel)
    nx = 200
    ny = 100

    # number of samples (rays) per pixel
    ns = 100

    # define camera
    lookfrom = np.array([-3., 3., 3.])
    lookat = np.array([0., 0., 0.])
    vfov = np.pi/9
    aperture = 1.
    focus_dist = np.linalg.norm(lookat - lookfrom)
    cam = Camera(lookfrom, lookat, np.array([0., 1., 0.]), vfov, nx / ny, aperture, focus_dist)

    # define scene geometry
    scene = SurfaceAssembly()
    scene.add_object(Sphere(np.array([ 0., 0., 0.]), 0.5, Lambertian(np.array([0.1, 0.2, 0.5]))))
    scene.add_object(Sphere(np.array([ 1., 0., 0.]), 0.5, Metal(np.array([0.8, 0.6, 0.2]), 1.0)))
    # imitate hollow glass sphere
    scene.add_object(Sphere(np.array([-1., 0., 0.]),  0.5,  Dielectric(1.5)))
    scene.add_object(Sphere(np.array([-1., 0., 0.]), -0.45, Dielectric(1.5)))
    # large sphere imitating ground floor
    scene.add_object(Sphere(np.array([0., -100.5, 0.]), 100., Lambertian(np.array([0.8, 0.8, 0.0]))))

    # render image
    im = render_image(nx, ny, ns, scene, cam)

    imageio.imwrite('depth_of_field.png', im.transpose((1, 0, 2)))
def random_scene():
    l = []
    l.append(Sphere(Vec3(0, -1000, -1), 1000, Lambertian(Vec3(0.5, 0.5, 0.5))))
    for a in range(-11, 11):
        for b in range(-11, 11):
            choose_mat = random()
            center = Vec3(a + 0.9 * random(), 0.2, b + 0.9 * random())
            if (center - Vec3(4, 0.2, 0)).length() > 0.9:
                if choose_mat < 0.8:  #diffuse
                    l.append(
                        MovingSphere(
                            center, center + Vec3(0.0, 0.5 * random(), 0.0),
                            0.0, 1.0, 0.2,
                            Lambertian(
                                Vec3(random() * random(),
                                     random() * random(),
                                     random() * random()))))
                elif choose_mat < 0.95:  #metal
                    l.append(
                        Sphere(
                            center, 0.2,
                            Metal(
                                Vec3(0.5 * (1 + random()),
                                     0.5 * (1 + random()),
                                     0.5 * (1 + random())), 0.5 * random())))
                else:  #glass
                    l.append(Sphere(center, 0.2, Dielectric(1.5)))
    l.append(Sphere(Vec3(0, 1, 0), 1.0, Dielectric(1.5)))
    l.append(Sphere(Vec3(-4, 1, 0), 1.0, Lambertian(Vec3(0.4, 0.2, 0.1))))
    l.append(Sphere(Vec3(4, 1, 0), 1.0, Metal(Vec3(0.7, 0.6, 0.5), 0.0)))
    return HitableList(l)
Exemple #7
0
    def my_scene(self):
        self.vfov = 65
        self.lookfrom = np.array([800, 180, 200])
        self.lookat = np.array([200, 0, 800])
        self.background = np.array([0, 0, 0])
        self.camera = Camera(self.img_width, self.img_height, self.lookfrom,
                             self.lookat, self.vup, self.vfov, self.aperature,
                             self.focus_dist)
        light = DiffuseLight(np.array([1, 1, 1]))
        mirror = Metal(np.array([0.95, 0.95, 0.95]), 0)
        mat_ground = Lambertian(np.array([0.5, 0.5, 0.5]))
        glass = Dielectric(2.0)
        mat_sphere = Lambertian(np.array([0.8, 0.8, 0.8]))

        self.world.add(XZRectangle(200, 800, 200, 800, 0, mat_ground))

        self.world.add(XYRectangle(425, 575, 0, 100, 700, light))

        self.world.add(XYRectangle(425, 575, 0, 100, 310, light))

        self.world.add(YZRectangle(0, 250, 200, 800, 200, mirror))

        self.world.add(YZRectangle(0, 250, 200, 800, 800, mirror))

        self.world.add(XYRectangle(200, 800, 0, 250, 800, mirror))

        self.world.add(XYRectangle(200, 800, 0, 250, 200, mirror))

        for x in range(470, 531, 30):
            for z in range(535, 474, -30):
                self.world.add(Sphere(np.array([x, 15, z]), 15, glass))

        for x in range(485, 516, 30):
            for z in range(520, 489, -30):
                self.world.add(
                    Sphere(np.array([x, 15 * (1 + np.sqrt(3)), z]), 15, glass))

        self.world.add(
            Sphere(np.array([500, 15 * (1 + 2 * np.sqrt(3)), 505]), 15, glass))

        self.world.add(Sphere(np.array([500, 15, 445]), 15, mirror))
        self.world.add(Sphere(np.array([500, 15, 565]), 15, mirror))

        self.world.add(Sphere(np.array([440, 15, 505]), 15, mat_sphere))
        self.world.add(Sphere(np.array([560, 15, 505]), 15, mat_sphere))

        dist = 15 * np.sqrt(2)
        self.world.add(
            Sphere(np.array([470 - dist, 15, 535 + dist]), 15, light))
        self.world.add(
            Sphere(np.array([530 + dist, 15, 535 + dist]), 15, light))
        self.world.add(
            Sphere(np.array([470 - dist, 15, 475 - dist]), 15, light))
        self.world.add(
            Sphere(np.array([530 + dist, 15, 475 - dist]), 15, light))

        self.world.add(
            BVHNode(self.world.objects, 0, len(self.world.objects), 0, 1))
def simple_light():
    pertext = NoiseTexture(4)
    l = []
    l.append(Sphere(Vec3(0, -1000, 0), 1000, Lambertian(pertext)))
    l.append(Sphere(Vec3(0, 2, 0), 2, Lambertian(pertext)))
    l.append(
        Sphere(Vec3(0, 7, 0), 2, DiffuseLight(ConstantTexture(Vec3(4, 4, 4)))))
    l.append(
        XyRect(3, 5, 1, 3, -2, DiffuseLight(ConstantTexture(Vec3(4, 4, 4)))))
    return HitableList(l)
Exemple #9
0
def cornell_box():
    l = []
    red = Lambertian(ConstantTexture(Vec3(0.65, 0.05, 0.05)))
    white = Lambertian(ConstantTexture(Vec3(0.73, 0.73, 0.73)))
    green = Lambertian(ConstantTexture(Vec3(0.12, 0.45, 0.15)))
    light = DiffuseLight(ConstantTexture(Vec3(15, 15, 15)))
    l.append(FlipNormals(YzRect(0, 555, 0, 555, 555, green)))
    l.append(YzRect(0, 555, 0, 555, 0, red))
    l.append(XzRect(213, 343, 227, 332, 554, light))
    l.append(FlipNormals(XzRect(0, 555, 0, 555, 555, white)))
    l.append(XzRect(0, 555, 0, 555, 0, white))
    l.append(FlipNormals(XyRect(0, 555, 0, 555, 555, white)))
    return HitableList(l)
Exemple #10
0
def get_small_world() -> World:
    mat_ground = Lambertian(Color(.8, .8, .3))
    ground = Sphere(Vector(0, -100.5, -1), 100, mat_ground)

    mat_center = Lambertian(Color(.7, .3, .3))
    center = Sphere(Vector(0, 0, -1), .5, mat_center)

    mat_left = Metal(Color(.8, .8, .8))
    left = Sphere(Vector(-1, 0, -1), .5, mat_left)

    mat_right = Dielectric(1.5)
    right = Sphere(Vector(1, 0, -1), .5, mat_right)

    return World([ground, center, left, right])
Exemple #11
0
    def random_spheres(self):
        self.lookfrom = np.array([13.0, 2.0, 3.0])
        self.lookat = np.array([0.0, 0.0, 0.0])
        self.vfov = 20.0
        self.aperature = 0.1
        self.background = np.array([0.7, 0.8, 1.0])

        self.camera = Camera(self.img_width, self.img_height, self.lookfrom,
                             self.lookat, self.vup, self.vfov, self.aperature,
                             self.focus_dist)

        mat_ground = Lambertian(np.array([0.5, 0.5, 0.5]))
        self.world.add(Sphere(np.array([0.0, -1000, 0.0]), 1000, mat_ground))

        for a in range(-11, 11):
            for b in range(-11, 11):
                choose_mat = ru.get_random()
                center = np.array([
                    a + 0.9 * ru.get_random(), 0.2, b + 0.9 * ru.get_random()
                ])

                if ru.length(center - np.array([4.0, 0.2, 0.0])) > 0.9:
                    sphere_material: Material
                    if choose_mat < 0.8:
                        albedo = ru.get_random_point() * ru.get_random_point()
                        sphere_material = Lambertian(albedo)
                    elif choose_mat < 0.95:
                        albedo = ru.get_random_point_in_range(0.5, 1.0)
                        fuzz = ru.get_random_in_range(0.0, 0.5)
                        sphere_material = Metal(albedo, fuzz)
                    else:
                        sphere_material = Dielectric(1.5)
                    self.world.add(Sphere(center, 0.2, sphere_material))

        mat1 = Dielectric(1.5)
        self.world.add(Sphere(np.array([0.0, 1.0, 0.0]), 1.0, mat1))

        mat2 = Lambertian(np.array([0.4, 0.2, 0.1]))
        self.world.add(Sphere(np.array([-4.0, 1.0, 0.0]), 1.0, mat2))

        mat3 = Metal(np.array([0.7, 0.6, 0.5]), 0.0)
        self.world.add(Sphere(np.array([4.0, 1.0, 0.0]), 1.0, mat3))

        # BVH implementation
        self.world.add(
            BVHNode(self.world.objects, 0, len(self.world.objects), 0, 1))
Exemple #12
0
def get_world() -> World:
    world = []
    glass = Dielectric(1.5)

    # Ground
    ground_mat = Lambertian(Color(0.5, 0.5, 0.5))
    world.append(Sphere(Vector(0, -1000, 0), 1000, ground_mat))

    # Marbles
    for x in range(-11, 11):
        for z in range(-11, 11):
            choose_material = random()
            material: Material

            center = Vector(x + .9 * random(), .2, z + .9 * random())

            if (center - Vector(4, .2, 0)).norm() <= .9:
                continue

            if choose_material < .8:
                # Diffuse
                albedo = Color(*(random(3) * random(3)))
                material = Lambertian(albedo)
            elif choose_material < .95:
                # Metal
                albedo = Color(*(random(3) * .5 + .5))
                fuzz = random() * .4
                material = Metal(albedo, fuzziness=fuzz)
            else:
                # Glass
                material = glass

            world.append(Sphere(center, .2, material))

    # Big Spheres
    world.append(Sphere(Vector(4, 1, 0),  1.0, glass))
    world.append(Sphere(Vector(-4, 1, 0), 1.0, Lambertian(Color(.6, .1, .1))))
    world.append(Sphere(Vector(0, 1, 0),  1.0, Metal(Color(.7, .6, .5))))

    return World(world)
Exemple #13
0
    def cornell_box(self):
        self.lookfrom = np.array([278, 278, -800])
        self.lookat = np.array([278, 278, 0])

        self.camera = Camera(self.img_width, self.img_height, self.lookfrom,
                             self.lookat, self.vup, self.vfov, self.aperature,
                             self.focus_dist)

        red = Lambertian(np.array([0.65, 0.05, 0.05]))
        white = Lambertian(np.array([0.73, 0.73, 0.73]))
        green = Lambertian(np.array([0.12, 0.45, 0.15]))
        light = DiffuseLight(np.array([15, 15, 15]))

        self.world.add(YZRectangle(0, 555, 0, 555, 555, green))
        self.world.add(YZRectangle(0, 555, 0, 555, 0, red))
        self.world.add(XZRectangle(213, 343, 227, 332, 554, light))
        self.world.add(XZRectangle(0, 555, 0, 555, 0, white))
        self.world.add(XZRectangle(0, 555, 0, 555, 555, white))
        self.world.add(XYRectangle(0, 555, 0, 555, 555, white))

        self.world.add(
            BVHNode(self.world.objects, 0, len(self.world.objects), 0, 1))
Exemple #14
0
def main():

    # image dimensions (pixel)
    nx = 200
    ny = 100

    # number of samples (rays) per pixel
    ns = 100

    # define camera
    lookfrom = np.zeros(3)
    lookat = np.array([0., 0., -1.])
    vfov = np.pi / 2
    aperture = 0.
    focus_dist = 1.
    cam = Camera(lookfrom, lookat, np.array([0., 1., 0.]), vfov, nx / ny,
                 aperture, focus_dist)

    # define scene geometry
    scene = SurfaceAssembly()
    scene.add_object(
        Sphere(np.array([0., 0., -1.]), 0.5,
               Lambertian(np.array([0.8, 0.3, 0.3]))))
    scene.add_object(
        Sphere(np.array([1., 0., -1.]), 0.5,
               Metal(np.array([0.8, 0.6, 0.2]), 1.0)))
    scene.add_object(
        Sphere(np.array([-1., 0., -1.]), 0.5,
               Metal(np.array([0.8, 0.8, 0.8]), 0.3)))
    # large sphere imitating ground floor
    scene.add_object(
        Sphere(np.array([0., -100.5, -1.]), 100.,
               Lambertian(np.array([0.8, 0.8, 0.0]))))

    # render image
    im = render_image(nx, ny, ns, scene, cam)

    imageio.imwrite('metal_spheres.png', im.transpose((1, 0, 2)))
Exemple #15
0
def random_scene():
    """Generate a random scene."""

    result = []
    sphere = Sphere(Vec3(0, -1000, 0), 1000, Lambertian(Vec3(0.5, 0.5, 0.5)))
    result.append(sphere)

    for a in range(-11, 11):
        for b in range(-11, 11):
            choose_mat = random()
            center = Vec3(a + 0.9 * random(), 0.2, b + 0.9 * random())
            if (center - Vec3(4, 0.2, 0)).length > 0.9:
                if choose_mat < 0.8:
                    # make diffuse
                    sphere = Sphere(
                        center, 0.2,
                        Lambertian(
                            Vec3(random() * random(),
                                 random() * random(),
                                 random() * random())))
                elif choose_mat < 0.95:
                    # make metallic
                    sphere = Sphere(
                        center, 0.2,
                        Metal(
                            Vec3(0.5 * (1 + random()), 0.5 * (1 + random()),
                                 0.5 * (1 + random())), 0.5 * random()))
                else:
                    # make glassy
                    sphere = Sphere(center, 0.2, Dielectric(1.5))
                result.append(sphere)

    result.append(Sphere(Vec3(0, 1, 0), 1.0, Dielectric(1.5)))
    result.append(Sphere(Vec3(-4, 1, 0), 1.0, Lambertian(Vec3(0.4, 0.2, 0.1))))
    result.append(Sphere(Vec3(4, 1, 0), 1.0, Metal(Vec3(0.7, 0.6, 0.5), 0.0)))

    return Hitable_List(result)
Exemple #16
0
def main():

    # image dimensions (pixel)
    nx = 200
    ny = 100

    # number of samples (rays) per pixel
    ns = 100

    # define camera
    lookfrom = np.zeros(3)
    lookat = np.array([0., 0., -1.])
    vfov = np.pi / 2
    aperture = 0.
    focus_dist = 1.
    cam = Camera(lookfrom, lookat, np.array([0., 1., 0.]), vfov, nx / ny,
                 aperture, focus_dist)

    mat = Lambertian(0.5)

    # define scene geometry
    scene = SurfaceAssembly()
    scene.add_object(Sphere(np.array([0., 0., -1.]), 0.5, mat))
    scene.add_object(Sphere(np.array([0., -100.5, -1.]), 100, mat))

    # fill image pixels
    im = np.zeros((nx, ny, 3), dtype=np.uint8)
    for i in range(nx):
        for j in range(ny):
            col = np.zeros(3)
            for s in range(ns):
                u = (i + np.random.rand()) / nx
                v = (j + np.random.rand()) / ny
                ray = cam.get_ray(u, v)
                col += ray_color(ray, scene, 50)
            col /= ns

            im[i, -(j + 1)] = np.round(255 * col).astype(int)

    imageio.imwrite('simple_sphere.png', im.transpose((1, 0, 2)))
def two_perlin_spheres():
    pertext = NoiseTexture(4.0)
    l = []
    l.append(Sphere(Vec3(0, -1000, 0), 1000, Lambertian(pertext)))
    l.append(Sphere(Vec3(0, 2, 0), 2, Lambertian(pertext)))
    return HitableList(l)
Exemple #18
0
)

# ~ Scene Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

world = HittableList()

world.objects.append(
    # Object to add (only spheres are supported right now)
    Sphere(
        # Location of the sphere in 3d space
        Vec3(0, -100, -1),
        # Radius of the sphere
        100,
        # Material of the sphere (lambertian is just diffuse)
        Lambertian(
            # Color of the material (RGB)
            Vec3(0.4, 0.4, 0.4)),
    ))
world.objects.append(
    Sphere(
        Vec3(0, 1, -3),
        1,
        # Metal sphere
        Metal(
            # Tint of the metal
            Vec3(0.8, 0.8, 0.8),
            # "Blurriness"
            0.1,
        ),
    ))
world.objects.append(
Exemple #19
0
def main():

    # image dimensions (pixel)
    nx = 1200
    ny = 800

    # number of samples (rays) per pixel
    ns = 10

    # define camera
    lookfrom = np.array([13., 2., 3.])
    lookat = np.zeros(3)
    vfov = np.pi / 9
    aperture = 0.1
    focus_dist = 10.0
    cam = Camera(lookfrom, lookat, np.array([0., 1., 0.]), vfov, nx / ny,
                 aperture, focus_dist)

    # define scene geometry
    scene = SurfaceAssembly()
    # three large spheres
    scene.add_object(
        Sphere(np.array([4., 1., 0.]), 1.0, Metal(np.array([0.7, 0.6, 0.5]),
                                                  0.)))
    scene.add_object(Sphere(np.array([0., 1., 0.]), 1.0, Dielectric(1.5)))
    scene.add_object(
        Sphere(np.array([-4., 1., 0.]), 1.0,
               Lambertian(np.array([0.4, 0.2, 0.1]))))
    # smaller spheres with random parameters
    for a in range(-11, 12):
        for b in range(-11, 12):
            center = np.array([
                a + 0.9 * np.random.rand(), 0.2 + 0.1 * np.random.rand(),
                b + 0.9 * np.random.rand()
            ])
            # random choice between diffusive, metal or dielectric (glass)
            choose_mat = np.random.choice(3, p=[0.8, 0.15, 0.05])
            if choose_mat == 0:
                # diffusive
                scene.add_object(
                    Sphere(
                        center, 0.2,
                        Lambertian(np.random.triangular(0., 0.2, 1., size=3))))
            elif choose_mat == 1:
                # metal
                scene.add_object(
                    Sphere(
                        center, 0.2,
                        Metal(0.5 * (1 + np.random.rand(3)),
                              0.5 * np.random.rand())))
            else:
                # dielectric (glass)
                scene.add_object(Sphere(center, 0.2, Dielectric(1.5)))
    # huge sphere imitating ground floor
    scene.add_object(
        Sphere(np.array([0., -1000., 0.]), 1000.,
               Lambertian(np.array([0.5, 0.5, 0.5]))))

    # render image
    im = render_image(nx, ny, ns, scene, cam)

    imageio.imwrite('random_scene.png', im.transpose((1, 0, 2)))