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)
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 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)
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)
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)
unit_dir = unit_vector(ray_.direction) t = 0.5 * (unit_dir.y + 1.0) return Vec3(1, 1, 1) * (1.0 - t) + Vec3(0.5, 0.7, 1.0) * t if __name__ == '__main__': nx = 200 ny = 100 ns = 100 lower_left = Vec3(-2, -1, -1) horizontal = Vec3(4, 0, 0) vertical = Vec3(0, 2, 0) origin = Vec3(0, 0, 0) world = HitableList() world.append(Sphere(Vec3(0, 0, -1), 0.5, Lambertian(Vec3(0.8, 0.3, 0.3)))) world.append(Sphere(Vec3(0, -100.5, -1), 100, Lambertian(Vec3(0.8, 0.8, 0.0)))) world.append(Sphere(Vec3(1, 0, -1), 0.5, Metal(Vec3(0.8, 0.6, 0.2), fuzz=0.3))) world.append(Sphere(Vec3(-1, 0, -1), 0.5, Metal(Vec3(0.8, 0.8, 0.8), fuzz=1.0))) cam = Camera() pbar = ProgressBar(widgets=['Percentage ', Percentage(), ' ', ETA(), ' ', Bar()], maxval=nx*ny).start() with open('image.ppm', 'w') as f: f.write('P3\n{} {}\n255\n'.format(nx, ny)) for y, j in enumerate(xrange(ny-1, -1, -1)): for i in xrange(nx): col = Vec3(0, 0, 0) for _ in xrange(ns): u = float(i + random()) / nx
if __name__ == '__main__': seed() look_from = Vec3(3, 3, 2) look_to = Vec3(0, 0, -1) dist_to_focus = (look_from - look_to).length() aperture = 2.0 cam = Camera(look_from, look_to, Vec3(0, 1, 0), 90, RES_WIDTH / RES_HEIGHT, aperture, dist_to_focus) # hit_list = [] # hit_list.append(Sphere(Vec3(0,0,-1), 0.5, Lambertian(Vec3(0.1, 0.2, 0.5)))) # hit_list.append(Sphere(Vec3(0,-100.5,-1), 100, Lambertian(Vec3(0.8, 0.8, 0)))) # hit_list.append(Sphere(Vec3(1,0,-1), 0.5, Specular(Vec3(0.8, 0.6, 0.2)))) # hit_list.append(Sphere(Vec3(-1,0,-1), 0.5, Dielectric(1.5))) # hit_list.append(Sphere(Vec3(-1,0,-1), -0.45, Dielectric(1.5))) hit_list = random_scene() world = HitableList(hit_list) # S is the screen coordinates (x0, y0, x1, y1) # np.linspace(start, stop, num) produces num evenly spaced samples over [start, stop] # np.tile(A, reps) constructs an array by repeating A, reps amount of times # np.repeat(a, repeats) repeats a, repeats amount of times # S = (-1, RES_HEIGHT/RES_WIDTH + .25, 1, -RES_HEIGHT/RES_WIDTH + .25) # x = np.tile(np.linspace(S[0], S[2], RES_WIDTH), RES_HEIGHT) # y = np.repeat(np.linspace(S[1], S[3], RES_HEIGHT), RES_WIDTH) start = time() # r = Ray(Vec3(0,0,0), cam.lower_left + cam.width.data * x + cam.height.data * y) # col = color(r, world, 0)
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)
unit_dir = unit_vector(ray_.direction) t = 0.5 * (unit_dir.y + 1.0) return Vec3(1, 1, 1) * (1.0 - t) + Vec3(0.5, 0.7, 1.0) * t if __name__ == '__main__': nx = 200 ny = 100 ns = 100 lower_left = Vec3(-2, -1, -1) horizontal = Vec3(4, 0, 0) vertical = Vec3(0, 2, 0) origin = Vec3(0, 0, 0) world = HitableList() world.append(Sphere(Vec3(0, 0, -1), 0.5, Lambertian(Vec3(0.8, 0.3, 0.3)))) world.append( Sphere(Vec3(0, -100.5, -1), 100, Lambertian(Vec3(0.8, 0.8, 0.0)))) world.append( Sphere(Vec3(1, 0, -1), 0.5, Metal(Vec3(0.8, 0.6, 0.2), fuzz=0.3))) world.append( Sphere(Vec3(-1, 0, -1), 0.5, Metal(Vec3(0.8, 0.8, 0.8), fuzz=1.0))) cam = Camera() pbar = ProgressBar( widgets=['Percentage ', Percentage(), ' ', ETA(), ' ', Bar()], maxval=nx * ny).start()
def file_ppm_write(file_name, width, height, samples): file = open(file_name, "wt") file_header = "P3\n" + str(width) + " " + str(height) + "\n255\n" file.write(file_header) # SCENE scene = [] scene.append(Sphere(Vector3(0, -1000.5, 0), 1000, Lambertian(Vector3(0.5, 0.5, 0.5)))) for a in range(-4, 4): for b in range(-4, 4): choose_mat = random.uniform(0, 1) center = Vector3(a + 0.9 * random.uniform(0,1), -0.3, b + 0.9 * random.uniform(0,1)) if ((center - Vector3(4, 0.0, 0)).length() > 0.9): if (choose_mat < 0.8): scene.append(Sphere(center, 0.2, Lambertian(Vector3(random.uniform(0,1) * random.uniform(0,1), random.uniform(0,1) * random.uniform(0,1), random.uniform(0,1) * random.uniform(0,1))))) elif (choose_mat < 0.95): scene.append(Sphere(center, 0.2, Metal(Vector3(0.5 * (1 + random.uniform(0, 1)), 0.5 * (1 + random.uniform(0, 1)), 0.5 * random.uniform(0,1))))) else: scene.append(Sphere(center, 0.2, Dielectric(1.5))) scene.append(Sphere(Vector3(0, 0.5, 0), 1.0, Dielectric(1.5))) scene.append(Sphere(Vector3(0, 0.5, 0), 0.9, Dielectric(1.5))) world = HitableList(scene, len(scene)) lookform = Vector3(5, 3, 15) lookat = Vector3(-5, 0, -1) dist_to_focus = (lookform - lookat).length() aperture = 2.0 camera = Camera(lookform, lookat, Vector3(0, 1, 0), 20, 16/9, aperture, dist_to_focus) print("Calculating Render...") for y in range(height-1, -1, -1): if (y%2 == 0): print(str(round(100-(y/height * 100), 2)) + "% done") for x in range(0, width): col = Vector3(0.0, 0.0, 0.0) u,v = 0,0 if (samples == 0): u = float(x) / width v = float(y) / height ray = camera.get_ray(u, v) col += color(ray, world, 0) else: for s in range(samples): u = float(x + random.uniform(0.0, 1.0)) / width v = float(y + random.uniform(0.0, 1.0)) / height ray = camera.get_ray(u, v) col += color(ray, world, 0) col = col.scalar_div(samples) col = Vector3(math.sqrt(col.x), math.sqrt(col.y), math.sqrt(col.z)) rgb = Vector3(col.x * 255.99, col.y * 255.99, col.z * 255.99) file_pixel_write(file, rgb) file.close()