def test_vec_normalization(self):
     values = [
         vector.Vec3(1., 3., 10.),
         vector.Vec3(0., 1., 0.),
         vector.Vec3(50, -50, 30)
     ]
     for v in values:
         self.assertAlmostEqual(v.normalized().length(), 1.0)
Beispiel #2
0
def main():

    arglen = len(sys.argv)

    instancevar = -1

    if arglen > 1:
        arg0 = sys.argv[0]
        arg1 = sys.argv[1]
        instancevar = arg1

    aspect_ratio = 16.0 / 9.0
    image_width = 384
    #image_width = 800
    image_height = int(image_width / aspect_ratio)
    samples_per_pixel = 10
    max_depth = 50

    lookfrom = vector.Vec3(13, 2, 3)
    lookat = vector.Vec3(0, 0, 0)
    dist_to_focus = 10.0
    aperture = 0.1

    vup = vector.Vec3(0, 1, 0)

    cam = camera.Camera(lookfrom, lookat, vup, 20, aspect_ratio, aperture,
                        dist_to_focus)

    world = random_scene(-1)

    random.seed(instancevar)

    print("P3")
    print("" + str(image_width) + " " + str(image_height))
    print("255")

    for j in range(image_height - 1, 0, -1):

        if instancevar == -1:
            sys.stderr.write("\rScanlines remaining: " + str(j) + "     ")

        for i in range(0, image_width, 1):

            pixel_color = vector.Vec3(0.0, 0.0, 0.0)

            for _ in range(samples_per_pixel):

                u1 = (i + util.random_double()) / (image_width - 1)
                v1 = (j + util.random_double()) / (image_height - 1)

                r = cam.get_ray(u1, v1)

                pixel_color = pixel_color + ray_color(r, world, max_depth)

            write_color(pixel_color, samples_per_pixel)

    sys.stderr.write("\nDone (instance: " + str(instancevar) + ")")
Beispiel #3
0
 def calc_view_matrix(self):
     eye = vector.Vec3(self.x, self.y, self.z)
     up = vector.Vec3(0, 1, 0)
     target = vector.Vec3(eye.x + self.x_tilt, eye.y + self.y_tilt, 0)
     # view axes
     forward = (target - eye).normalize()
     side = forward.cross(up).normalize()
     upward = side.cross(forward)
     m = [[side.x, upward.x, -forward.x, 0],
          [side.y, upward.y, -forward.y, 0],
          [side.z, upward.z, -forward.z, 0],
          [-eye.dot(side), -eye.dot(upward), eye.dot(forward), 1]]
     self.view_matrix = np.array(m, dtype=np.float32)
     self.look_x, self.look_y, self.look_z = side, upward, forward
Beispiel #4
0
    def scatter(self, ray_in: vector.Ray, hit_record: hittable.HitRecord):
        attenuation = vector.Vec3(1.0, 1.0, 1.0)
        etai_over_etat = self.ref_idx

        if hit_record.front_face:
            etai_over_etat = 1.0 / self.ref_idx

        unit_direction = vector.unit_vector(ray_in.direction)

        cos_theta = min(vector.dot(-unit_direction, hit_record.normal), 1.0)
        sin_theta = math.sqrt(1.0 - cos_theta*cos_theta)

        if etai_over_etat * sin_theta > 1.0:
            reflected = vector.reflect(unit_direction, hit_record.normal)
            scattered = vector.Ray(hit_record.position, reflected)
            return True, attenuation, scattered

        reflect_prob = vector.schlick(cos_theta, etai_over_etat)
        if util.random_double() < reflect_prob:
            reflected = vector.reflect(unit_direction, hit_record.normal)
            scattered = vector.Ray(hit_record.position, reflected)
            return True, attenuation, scattered

        refracted = vector.refract(unit_direction, hit_record.normal, etai_over_etat)
        scattered = vector.Ray(hit_record.position, refracted)
        return True, attenuation, scattered
Beispiel #5
0
def random_scene(seed):

    random.seed(seed)

    world = hittable.HittableList()

    world.add(
        hittable.Sphere(vector.Vec3(0, -1000, 0), 1000,
                        material.Lambertian(vector.Vec3(0.5, 0.5, 0.5))))

    for a in range(-11, 11):
        for b in range(-11, 11):
            choose_mat = util.random_double()

            center = vector.Vec3(a + 0.9 * util.random_double(), 0.2,
                                 b + 0.9 * util.random_double())

            if (center - vector.Vec3(4, 0.2, 0)).length() > 0.9:
                if choose_mat < 0.8:
                    # diffuse
                    albedo = vector.random() * vector.random()
                    world.add(
                        hittable.Sphere(center, 0.2,
                                        material.Lambertian(albedo)))

                elif choose_mat < 0.95:
                    # metal
                    albedo = vector.random_in_range(.5, 1)
                    fuzz = util.random_double_range(0, .5)

                    world.add(
                        hittable.Sphere(center, 0.2,
                                        material.Metal(albedo, fuzz)))
                else:
                    # glass
                    world.add(
                        hittable.Sphere(center, 0.2, material.Dielectric(1.5)))

    world.add(
        hittable.Sphere(vector.Vec3(0, 1, 0), 1.0, material.Dielectric(1.5)))

    world.add(
        hittable.Sphere(vector.Vec3(-4, 1, 0), 1.0,
                        material.Lambertian(vector.Vec3(.4, .2, .1))))

    world.add(
        hittable.Sphere(vector.Vec3(4, 1, 0), 1.0,
                        material.Metal(vector.Vec3(.7, .6, .5), 0.0)))

    return world
Beispiel #6
0
def ray_color(ray: vector.Ray, world: hittable.Hittable, depth):

    if depth <= 0:
        return vector.Vec3(0.0, 0.0, 0.0)

    did_hit, hit_rec = world.hit(ray, 0.001, util.INFINITY)

    if did_hit:

        tempmaterial = hit_rec.material

        didscatter, albedo, scattered = tempmaterial.scatter(ray, hit_rec)

        if didscatter:

            return albedo * ray_color(scattered, world, depth - 1)

        return vector.Vec3(0, 0, 0)

    unit_dir = vector.unit_vector(ray.direction)
    t = (unit_dir.y + 1.0) * 0.5
    return vector.Vec3(1.0, 1.0, 1.0).times(1.0 - t) + vector.Vec3(
        0.5, 0.7, 1.0).times(t)
Beispiel #7
0
import vector
import cProfile
import re
import hittable

p = vector.Vec3(0.0, 0.0, 0.0)
norm = vector.Vec3(0.0, 1.0, 0.0)

hit_rec = hittable.HitRecord(p, norm, 0.0, None)

sum = 0.0
for i in range(100):
    target = hit_rec.position + vector.random_in_hemisphere(hit_rec.normal)
    sum = sum + target.x

print("avg x: " + str(sum / 100.0))

r = vector.Ray(vector.Vec3(0.0, 0.0, 0.0), vector.Vec3(1.0, 1.0, 1.0))

r2 = r.at(-0.5)

print("" + str(r))
print("" + str(r2))
 def test_vec_addition(self):
     vec1 = vector.Vec3(5., 3., -2.)
     vec2 = vector.Vec3(-5., 2., 0.)
     expected = vector.Vec3(0., 5., -2.)
     self.assertEqual(vec1 + vec2, expected)
 def test_vec_printing(self):
     vec = vector.Vec3(5, 3, 0)
     self.assertEqual(str(vec), "(5, 3, 0)")
Beispiel #10
0
def test_scene(seed):

    random.seed(seed)

    world = hittable.HittableList()

    R = math.cos(util.PI / 4)

    world.add(
        hittable.Sphere(vector.Vec3(-R, 0, -1), R,
                        material.Lambertian(vector.Vec3(0, 0, 1))))
    world.add(
        hittable.Sphere(vector.Vec3(R, 0, -1), R,
                        material.Lambertian(vector.Vec3(1, 0, 0))))

    world.add(
        hittable.Sphere(vector.Vec3(0, 0, -1), 0.5,
                        material.Lambertian(vector.Vec3(0.1, 0.2, 0.5))))
    world.add(
        hittable.Sphere(vector.Vec3(0, -100.5, -1), 100,
                        material.Lambertian(vector.Vec3(0.8, 0.8, 0.0))))

    world.add(
        hittable.Sphere(vector.Vec3(1, 0, -1), 0.5,
                        material.Metal(vector.Vec3(.8, .6, .2), 0.0)))
    world.add(
        hittable.Sphere(vector.Vec3(-1, 0, -1), 0.5, material.Dielectric(1.5)))
    world.add(
        hittable.Sphere(vector.Vec3(-1, 0, -1), -0.45,
                        material.Dielectric(1.5)))