Exemplo n.º 1
0
def render(width=200, height=100):
    hor_size = 4.0
    ver_size = hor_size * 0.5
    line = []
    # Preload function
    line_append = line.append
    frame = []
    # Preload function
    frame_append = frame.append
    nx = width
    ny = height
    lower_left_corner = vec3(-(hor_size / 2.0), -(ver_size / 2.0), -1.0)
    horizontal = vec3(hor_size, 0.0, 0.0)
    vertical = vec3(0.0, ver_size, 0.0)
    origin = vec3(0.0, 0.0, 0.0)

    for j in range(ny - 1, -1, -1):
        line.clear()
        v = float(j) / float(ny)
        for i in range(nx):
            u = float(i) / float(nx)
            r = ray(origin, lower_left_corner + u * horizontal + v * vertical)
            col = color(r)
            #pix = vec3(int(255.99 * col.r), int(255.99 * col.g), int(255.99 * col.b))
            #line.append([pix.x, pix.y, pix.z])
            # line.append([int(255.99 * col.r), int(255.99 * col.g), int(255.99 * col.b)])
            line_append([
                int(255.99 * col.r),
                int(255.99 * col.g),
                int(255.99 * col.b)
            ])
        # frame.append(line.copy())
        frame_append(line.copy())
    return frame
Exemplo n.º 2
0
def color(r):
    # bgColor = vec3(0.5, 0.7, 1.0)
    t = hit_sphere(vec3(0, 0, -1), 0.50, r)
    if t > 0.0:
        N = vec3.unit_vector(r.point_at_parameter(t) - vec3(0, 0, -1))
        return 0.5 * vec3(N.x + 1, N.y + 1, N.z + 1)
    unit_direction = vec3.unit_vector(r.direction)
    t = 0.5 * (unit_direction.y + 1.0)
    return (1.0 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0)
Exemplo n.º 3
0
 def scatter(self, r_in, rec):
     reflected = reflect(r_in.direction(), rec.record[2])
     attenuation = vec3(1.0, 1.0, 1.0)
     
     if (vec3.dot(r_in.direction(), rec.record[2]) > 0):
         outworld_normal = -rec.record[2]
         ni_over_nt = self.ref_idx
         cosine = self.ref_idx * vec3.dot(r_in.direction(), rec.record[2]) / r_in.direction().length()
     else:
         outworld_normal = rec.record[2]
         ni_over_nt = 1.0 / self.ref_idx
         cosine = -vec3.dot(r_in.direction(), rec.record[2]) / r_in.direction().length()
     
     isok, refracted = refract(r_in.direction(), outworld_normal, ni_over_nt)
     if isok:
         reflect_prob = schlick(cosine, self.ref_idx)   
     else:
         reflect_prob = 1.0
         
     if random.random() < reflect_prob:
         scattered = ray(rec.record[1], reflected)
     else:
         scattered = ray(rec.record[1], refracted)
         
     return True, scattered, attenuation
Exemplo n.º 4
0
def color(r, world, depth):
    if isinstance(r, ray):
        infinity = float('inf')
        rec = hit_record()
        if world.hit(r, 0.001, infinity, rec):
            isscatter, s, a = rec.record[3].scatter(r, rec)
            if depth < 50 and isscatter:
                return a * color(s, world, depth+1)
            else:
                return vec3(0, 0, 0)
        else:
            unit_direction = vec3.unit_vector(r.direction())
            t = 0.5*(unit_direction.y() + 1.0)
            return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0)
    else:
        return NotImplemented
Exemplo n.º 5
0
def refract(v, n, ni_over_nt):
    uv = vec3.unit_vector(v)
    dt = vec3.dot(uv, n)
    discriminant = 1.0 - ni_over_nt*ni_over_nt*(1-dt*dt)
    refracted = vec3(0, 0, 0)
    if discriminant > 0:
        refracted = ni_over_nt*(uv - n*dt) - n*math.sqrt(discriminant)
        return True, refracted
    else:
        return False, refracted
Exemplo n.º 6
0
def random_in_unit_disk():
    while True:
        p = 2.0 * vec3(random.random(), random.random(), 0) - vec3(1, 1, 0)
        if vec3.dot(p, p) < 1:
            break
    return p
Exemplo n.º 7
0
 def __init__(self, t=0, p=vec3(0, 0, 0), normal=vec3(0, 0, 0), mat=0):
     if isinstance(p, vec3) and isinstance(normal, vec3) and isinstance(
             t, numbers.Real):
         self.record = [t, p, normal, mat]
     else:
         return NotImplemented
Exemplo n.º 8
0
def random_in_unit_sphere():
    while True:
        p = 2.0 * vec3(random.random(), random.random(), random.random()) - vec3(1, 1, 1)
        if p.length() < 1.0:
            break
    return p
Exemplo n.º 9
0
def random_scene():
    hlist = []
    hlist.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.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:
                    hlist.append(sphere(center, 0.2, lambertian(vec3(random.random(), random.random(), random.random()))))
                elif choose_mat < 0.95:
                    hlist.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:
                    hlist.append(sphere(center, 0.2, dielectric(1.5)))
    
    hlist.append(sphere(vec3(0, 1, 0), 1.0, dielectric(1.5)))
    hlist.append(sphere(vec3(-4, 1, 0), 1.0, lambertian(vec3(0.4, 0.2, 0.1))))
    hlist.append(sphere(vec3(4, 1, 0), 1.0, metal(vec3(0.7, 0.6, 0.5), 0.0)))
    return hittable_list(hlist)
Exemplo n.º 10
0
            unit_direction = vec3.unit_vector(r.direction())
            t = 0.5*(unit_direction.y() + 1.0)
            return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0)
    else:
        return NotImplemented

if __name__ == '__main__':
    file = r'.\out.ppm'
    
    nx = 200
    ny = 100
    ns = 100
    
    world = random_scene()

    lookfrom = vec3(11, 5, 2)
    lookat = vec3(0, 0, -1)
    dist_to_focus = (lookfrom - lookat).length()
    aperture = 0.05
    
    with open(file, 'w') as p:
        p.write("P3\n")
        p.write("{} {}\n".format(nx, ny))
        p.write("255\n")
    
        for y in range(ny):
            print(y)
            for x in range(nx):
                col = vec3(0, 0, 0)
                cam = camera(lookfrom, lookat, vec3(0,1,0), 25, float(nx)/float(ny), aperture, dist_to_focus)
                for z in range(ns):