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
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
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
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
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)
def step_assert_material_of_s_equals_default_material(context): assert context.s.material == Material()
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)
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()
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())