예제 #1
0
파일: camera.py 프로젝트: vesas/snake-ray
    def __init__(self, lookfrom: vector.Vec3, lookat: vector.Vec3,
                 vup: vector.Vec3, vfov: float, aspect_ratio: float,
                 aperture: float, focus_dist: float):

        self.origin = lookfrom
        self.lens_radius = aperture / 2

        theta = util.degrees_to_radians(vfov)

        half_height = math.tan(theta / 2)
        half_width = aspect_ratio * half_height

        self.w1 = vector.unit_vector(lookfrom - lookat)
        self.u1 = vector.unit_vector(vector.cross(vup, self.w1))
        self.v1 = vector.cross(self.w1, self.u1)

        self.lower_left_corner = self.origin - self.u1.times(
            half_width * focus_dist) - self.v1.times(
                half_height * focus_dist) - self.w1.times(focus_dist)

        self.horizontal = self.u1.times(half_width * 2 * focus_dist)
        self.vertical = self.v1.times(half_height * 2 * focus_dist)

        self.vfov = vfov
        self.aspect_ratio = aspect_ratio
예제 #2
0
 def angle_between(self, a, b):
     # based on http://stackoverflow.com/questions/2827393/angles-between-two-n-dimensional-vectors-in-python
     """ Returns the angle in radians between vectors 'v1' and 'v2'::
     """
     v0 = np.array([a.slope_v.x, a.slope_v.y])
     v1 = np.array([b.slope_v.x, b.slope_v.y])
     v0_u = unit_vector(v0)
     v1_u = unit_vector(v1)
     angle = np.arccos(np.dot(v0_u, v1_u))
     if np.isnan(angle):
         if (v0_u == v1_u).all():
             return 0.0
         else:
             return 360.0
     return np.degrees(angle)
예제 #3
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
예제 #4
0
def raytrace(r, scene, depth):

    # Determine the closest hits
    distances = [s.intersect(r, 0.001, 1.0e39) for s in scene]
    nearest = ft.reduce(np.minimum, distances)

    # Ambient
    color = rgb(0.0, 0.0, 0.0)

    unit_dir = unit_vector(r.direction())
    t = (unit_dir.y + 1.0) * 0.5
    # bgc = (vec3(1.0, 1.0, 1.0)*(1.0 - t) + vec3(0.5, 0.7, 1.0)*t)
    bgc = vec3(0.5, 0.7, 1.0) * t

    for (s, d) in zip(scene, distances):
        hit = (nearest != 1.0e39) & (d == nearest)
        print("depth: %s | Radius: %s | Shape: %s" %
              (depth, s.radius, hit.shape))
        time.sleep(0.1)
        if np.any(hit) and depth < 5:
            dc = np.extract(hit, d)
            oc = r.origin().extract(hit)
            dirc = r.direction().extract(hit)
            er = ray(oc, dirc)

            p = er.point_at_parameter(dc)
            N = (p - s.center) / vec3(s.radius, s.radius, s.radius)

            shader = s.material()
            scattered = shader.scatter(er, p, N)
            cc = raytrace(scattered, scene, depth + 1) * shader.albedo
            # cc = vec3(shader.albedo, shader.albedo, shader.albedo)
            color += cc.place2(hit, bgc)
    return color
예제 #5
0
    def scatter(self, ray_in: vector.Ray, hit_record: hittable.HitRecord):


        reflected = vector.reflect(vector.unit_vector(ray_in.direction), hit_record.normal)
        scattered = vector.Ray(hit_record.position, reflected + vector.random_in_unit_sphere().times(self.fuzz))

        didscatter = (vector.dot(scattered.direction, hit_record.normal) > 0)

        return didscatter, self.color, scattered
예제 #6
0
    def angle_x_axis(self):
        # based on http://stackoverflow.com/questions/2827393/angles-between-two-n-dimensional-vectors-in-python
        """ Returns the angle in radians between vectors 'v1' and 'v2'::

                >>> angle_between((1, 0, 0), (0, 1, 0))
                1.5707963267948966
                >>> angle_between((1, 0, 0), (1, 0, 0))
                0.0
                >>> angle_between((1, 0, 0), (-1, 0, 0))
                3.141592653589793
        """
        v0 = np.array([self.slope_v.x, self.slope_v.y])
        v1 = np.array([1, 0])
        v0_u = unit_vector(v0)
        v1_u = unit_vector(v1)
        angle = np.arccos(np.dot(v0_u, v1_u))
        if np.isnan(angle):
            if (v0_u == v1_u).all():
                return 0.0
            else:
                return 360.0
        return np.degrees(angle)
예제 #7
0
    def angle_between(self, a, b):
        # based on http://stackoverflow.com/questions/2827393/angles-between-two-n-dimensional-vectors-in-python
        """ Returns the angle in radians between vectors 'v1' and 'v2'::

                angle_between((1, 0, 0), (0, 1, 0))
                1.5707963267948966
                angle_between((1, 0, 0), (1, 0, 0))
                0.0
                angle_between((1, 0, 0), (-1, 0, 0))
                3.141592653589793
        """
        v0 = a[1] - a[0]
        v1 = b[1] - b[0]
        v0_u = unit_vector(v0)
        v1_u = unit_vector(v1)
        angle = np.arccos(np.dot(v0_u, v1_u))
        if np.isnan(angle):
            if (v0_u == v1_u).all():
                return 0.0
            else:
                return 360
        return np.degrees(angle)
예제 #8
0
파일: main_old.py 프로젝트: Hartman-/Pyray
def raytrace_OLD(r, scene):
    hitpts = hit_sphere(vec3(0.0, 0.0, -1.0), 0.4, r)
    m = np.copy(hitpts)

    unit_direction = unit_vector(r.direction())
    t = 0.5 * (unit_direction.y + 1.0)

    mask = np.where(m > 0.0, 0, 1)

    N = (r.point_at_parameter(t) - vec3(0.0, 0.0, -1.0)) * (1.0 / 0.4)
    Nc = (vec3(N.x + 1, N.y + 1, N.z + 1) * 0.5)
    color = (vec3(1.0, 1.0, 1.0) *
             (1.0 - t) + vec3(0.5, 0.7, 1.0) * t) * mask + (Nc * (1 - mask))

    return (color)
예제 #9
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)
예제 #10
0
파일: common.py 프로젝트: Hartman-/Pyray
 def scatter(self, r_in, P, N):
     reflected = reflect(unit_vector(r_in.direction()), N)
     scattered = ray(P, reflected)
     # isReflected = (N.dot(scattered.direction()) > 0)
     # return np.where(isReflected, True, False)
     return scattered