Beispiel #1
0
    def from_yaml(cls, obj, defines) -> 'Group':
        path = obj['file']
        if 'material' in obj:
            mat = Material.from_yaml(obj['material'])
        else:
            mat = Material()

        if 'transform' in obj:
            xform = Transform.from_yaml(obj['transform'])
        else:
            xform = matrix4x4identity()
        g = obj_file_to_group(path, mat)
        g.transform = xform
        return g
Beispiel #2
0
    def default(cls):
        world = cls()
        world.add_light(PointLight(point(-10, 10, -10), color(1, 1, 1)))

        sphere1 = Sphere()
        mat = Material()
        mat.color = color(0.8, 1.0, 0.6)
        mat.diffuse = 0.7
        mat.specular = 0.2
        sphere1.material = mat

        sphere2 = Sphere()
        sphere2.set_transform(scaling(0.5, 0.5, 0.5))

        world.objects.append(sphere1)
        world.objects.append(sphere2)

        return world
Beispiel #3
0
def yaml_file_to_world_objects(file_path):
    tree = None
    with open(file_path, 'r') as f:
        tree = yaml.load(f, Loader=Loader)

    if tree is None:
        return []

    rv = {'camera': None, 'lights': [], 'world': [], 'config': None}

    defines = {}
    extends_map = {}

    for obj in tree:
        if "define" in obj:
            k = obj["define"]
            v = obj.get("value")
            opt = obj.get("extend")
            defines[k] = v
            if opt is not None:
                extends_map[k] = opt

    # replace 'extends' in defines map
    for obj_name in extends_map:
        parent_name = extends_map[
            obj_name]  # name of object which will be extended
        parent_value = defines[parent_name]
        child_value = defines[
            obj_name]  # name of object with 'extends' keyword
        new_parent_value = deepcopy(parent_value)
        if type(new_parent_value) == dict:
            # assume child value is same type
            for k in child_value:
                new_parent_value[k] = child_value[k]
            defines[obj_name] = new_parent_value

    expand_defines_in_tree(tree, defines)

    for obj in tree:
        if "add" in obj:
            if obj["add"] == "camera":
                rv['camera'] = Camera.from_yaml(obj)
            elif obj["add"] == "light":
                rv['lights'].append(Light.from_yaml(obj))
            elif obj['add'] == 'config':
                rv['config'] = GlobalConfig.from_yaml(obj)
            else:
                possible_item = recursive_add(obj, defines)
                if possible_item is not None:
                    rv['world'].append(possible_item)

    g = Group(material=Material(),
              transform=matrix4x4identity(),
              children=rv['world'])
    rv['world'] = [g]
    return rv
Beispiel #4
0
 def __init__(self, open_file, default_material=Material()):
     self.open_file = open_file
     self.default_material = default_material
     self.vertices = []
     self.normals = []
     self.vertices.append(None)
     self.normals.append(None)
     self.named_groups = {
         '##default_group':
         Group(self.default_material, matrix4x4identity(), set())
     }
     self.current_group_name = '##default_group'
     self.default_group = self.named_groups['##default_group']
     self._parse_file()
def main():
    canvas_pixels = 500
    canvas = Canvas(canvas_pixels, canvas_pixels)
    shape = Sphere()

    # assign material
    shape.material = Material()
    shape.material.color = color(1, 0.2, 1)

    light_position = point(-10, 10, -10)
    light_color = color(1, 1, 1)
    light = PointLight(light_position, light_color)

    ray_origin = point(0, 0, -5)
    wall_z = 10
    wall_size = 7.0

    pixel_size = wall_size / canvas_pixels
    half = wall_size / 2

    for y in range(canvas_pixels):
        world_y = half - pixel_size * y

        for x in range(canvas_pixels):
            world_x = -half + pixel_size * x

            pos = point(world_x, world_y, wall_z)

            r = Ray(ray_origin, normalize(subtract(pos, ray_origin)))
            xs = shape.intersect(r)

            shape_hit = hit(xs)
            if shape_hit is not None:
                hit_point = r.position_at(shape_hit.t)
                normal = shape_hit.object.normal_at(hit_point)
                eye = negate(r.direction)
                px_color = lighting(shape_hit.object.material,
                                    shape_hit.object, light, hit_point, eye,
                                    normal)
                canvas.set_pixel(x, y, px_color)

    with open('render_phong_sphere.ppm', 'w') as out_file:
        out_file.write(canvas.to_ppm())
def parse_obj_file(content, material=Material()):
    obj_file = ObjFile()

    current_group = obj_file.groups["default"]

    for line in content:
        parts = line.split()

        if len(parts) < 1:
            obj_file.ignored += 1
            continue

        if parts[0] == "v":
            obj_file.vertices.append(
                point(float(parts[1]), float(parts[2]), float(parts[3])))
        elif parts[0] == "vn":
            obj_file.normals.append(
                vector(float(parts[1]), float(parts[2]), float(parts[3])))
        elif parts[0] == "g":
            current_group = Group()
            obj_file.groups[parts[1]] = current_group
        elif parts[0] == "f":
            vertices = [None]
            normals = [None]
            for index in range(1, len(parts)):
                v, vt, vn = to_ints(parts[index])
                vertices.append(obj_file.vertices[v])
                if vn:
                    normals.append(obj_file.normals[vn])

            triangles = fan_triangulation(vertices, normals, material)

            for triangle in triangles:
                current_group.add_child(triangle)
        else:
            obj_file.ignored += 1

    return obj_file
Beispiel #7
0
    print('Start Raytracer')


    # color blueprints
    blue = np.array([0.498, 0.403, 0.])
    gray = np.array([0.48, 0.48, 0.48])
    light_green = np.array([0.756, 0.929, 0.862])
    light_pink = np.array([0.666, 0.756, 1.])
    
    red = np.array([.047, .09, .447])
    orange = np.array([.137, .568, .901])
    green = np.array([.274, .627, .431])
    white = np.array([1., 1., 1])

    MatGray = Material(color=gray, ambient=0.7, diffuse=0.9, specular=1., shinyness=80.)
    MatBlue = Material(color=blue, ambient=0.7, diffuse=0.9, specular=.9, shinyness=80.)
    MatRed = Material(color=white, ambient=0.7, diffuse=0.9, specular=.9, shinyness=80., refraction_weight=.8)
    MatGreen = Material(color=green, ambient=0.7, diffuse=0.6, specular=1., shinyness=80.)
    MatOrange = Material(color=orange, ambient=0.1, diffuse=0.9, specular=1., shinyness=80., refraction_weight=.4)
    MatWhite = Material(color=white, ambient=0.1, diffuse=0.9, specular=1., shinyness=80.)
    MatBack = Material(color=light_green, ambient=0.1, diffuse=0.9, specular=1., shinyness=80.)
    MatBack2 = Material(color=light_pink, ambient=0.1, diffuse=0.9, specular=1., shinyness=80.)

    # build shapes 
    s1 = Sphere(np.array([170.,0.,20]), 20, MatBlue)
    s2 = Sphere(np.array([250.,95.,60]), 60, MatGreen)
    s3 = Sphere(np.array([260.,-35.,35]), 35, MatRed)
    s4 = Sphere(np.array([200.,-15.,45]), 5, MatOrange)
    s5 = Sphere(np.array([0., 0., 20.]), 20, MatRed)
    s6 = Sphere(np.array([-20., 10., 5.]), 5, MatOrange)
Beispiel #8
0
def step_assert_material_of_s_equals_default_material(context):
    assert context.s.material == Material()
Beispiel #9
0
def obj_file_to_group(file_path, material=Material()):
    with open(file_path, 'r') as f:
        parser = OBJParser(f, default_material=material)
        return obj_to_group(parser)
Beispiel #10
0
def obj_to_group(parser):
    obj_group = Group(Material(), matrix4x4identity(), set())
    obj_group.add_child(
        [v for k, v in parser.named_groups.items() if len(v.children) > 0])
    return obj_group
def step_create_material_m_from_yaml(context):
    context.m = Material.from_yaml(context.data)
def step_create_default_material_m(context):
    context.m = Material()
Beispiel #13
0
def render_scene_with_plane():
    floor = Plane()
    floor.set_transform(scaling(10, 0.01, 10))
    # floor.set_transform(
    # multiply_matrix(translation(0, 0.33, 0), scaling(10, 0.01, 10)))
    floor.material = Material()
    floor.material.color = color(1, 0.9, 0.9)
    floor.material.specular = 0

    # left_wall = Plane()
    # left_wall.set_transform(
    #     multiply_matrix(
    #         translation(0, 0, 5),
    #         multiply_matrix(rotation_y(-pi / 4),
    #                  multiply_matrix(rotation_x(pi / 2), scaling(10, 0.01, 10)))))
    # left_wall.material = floor.material

    # right_wall = Plane()
    # right_wall.set_transform(
    #     multiply_matrix(
    #         translation(0, 0, 5),
    #         multiply_matrix(rotation_y(pi / 4),
    #                  multiply_matrix(rotation_x(pi / 2), scaling(10, 0.01, 10)))))

    middle = Sphere()
    middle.set_transform(translation(-0.5, 1, 0.5))
    middle.material = Material()
    middle.material.pattern = StripePattern(color(0.6, 1.0, 0.6),
                                            color(0.3, 0.6, 0.3))
    middle.material.color = color(0.1, 1, 0.5)
    middle.material.diffuse = 0.7
    middle.material.specular = 0.3

    middle.material.pattern.set_transform(
        multiply_matrix(scaling(0.2, 0.2, 0.2), rotation_y(pi / 4)))

    right = Sphere()
    right.set_transform(
        multiply_matrix(translation(1.5, 0.5, -0.5), scaling(0.5, 0.5, 0.5)))
    right.material = Material()
    right.material.color = color(0.5, 1, 0.1)
    # right.material.diffuse = 0.7
    right.material.diffuse = 0.2
    right.material.specular = 0.3
    right.material.reflective = 0.7

    left = Sphere()
    left.set_transform(
        multiply_matrix(translation(-1.5, 0.33, -0.75),
                        scaling(0.33, 0.33, 0.33)))
    left.material = Material()
    left.material.color = color(1, 0.8, 0.1)
    left.material.diffuse = 0.7
    left.material.specular = 0.3

    world = World()
    world.add_light(PointLight(point(-10, 10, -10), color(1, 1, 1)))
    world.objects.append(floor)
    # world.objects.append(left_wall)
    # world.objects.append(right_wall)
    world.objects.append(middle)
    world.objects.append(right)
    world.objects.append(left)

    camera = Camera(600, 500, pi / 3)
    camera.set_transform(
        view_transform(point(0, 1.5, -5), point(0, 1, 0), vector(0, 1, 0)))
    # camera.set_transform(
    # view_transform(point(0, 4, -1), point(0, 1, 0), vector(0, 1, 0)))

    canvas = RayTracer().render(camera, world)
    ppm = canvas.to_ppm()
    outf = open('render_scene_with_plane.ppm', 'w')
    outf.write(ppm)
def render_simple_scene():
    floor = Sphere()
    floor.set_transform(scaling(10, 0.01, 10))
    floor.material = Material()
    floor.material.color = color(1, 0.9, 0.9)
    floor.material.specular = 0

    left_wall = Sphere()
    left_wall.set_transform(
        multiply_matrix(
            translation(0, 0, 5),
            multiply_matrix(
                rotation_y(-pi / 4),
                multiply_matrix(rotation_x(pi / 2), scaling(10, 0.01, 10)))))
    left_wall.material = floor.material

    right_wall = Sphere()
    right_wall.set_transform(
        multiply_matrix(
            translation(0, 0, 5),
            multiply_matrix(
                rotation_y(pi / 4),
                multiply_matrix(rotation_x(pi / 2), scaling(10, 0.01, 10)))))
    right_wall.material = floor.material

    middle = Sphere()
    middle.set_transform(translation(-0.5, 1, 0.5))
    middle.material = Material()
    middle.material.color = color(0.1, 1, 0.5)
    middle.material.diffuse = 0.7
    middle.material.specular = 0.3

    right = Sphere()
    right.set_transform(
        multiply_matrix(translation(1.5, 0.5, -0.5), scaling(0.5, 0.5, 0.5)))
    right.material = Material()
    right.material.color = color(0.5, 1, 0.1)
    right.material.diffuse = 0.7
    right.material.specular = 0.3

    left = Sphere()
    left.set_transform(
        multiply_matrix(translation(-1.5, 0.33, -0.75),
                        scaling(0.33, 0.33, 0.33)))
    left.material = Material()
    left.material.color = color(1, 0.8, 0.1)
    left.material.diffuse = 0.7
    left.material.specular = 0.3

    world = World()
    world.add_light(PointLight(point(-10, 10, -10), color(1, 1, 1)))
    world.objects.append(floor)
    world.objects.append(left_wall)
    world.objects.append(right_wall)
    world.objects.append(middle)
    world.objects.append(right)
    world.objects.append(left)

    camera = Camera(600, 500, pi / 3)
    camera.set_transform(
        view_transform(point(0, 1.5, -5), point(0, 1, 0), vector(0, 1, 0)))

    canvas = RayTracer().render(camera, world)

    with open('render_simple_scene.ppm', 'w') as out_file:
        out_file.write(canvas.to_ppm())