Пример #1
0
    def step(self, ext_input: np.array):
        if (self.cfg.run_scheme == SchemeType.Advection_Projection):
            self.advect(self.cfg.dt)
            self.externalForce(ext_input, self.cfg.dt)
            self.project()
            self.grid.subtract_gradient(self.grid.v_pair.cur,
                                        self.grid.p_pair.cur)

        elif (self.cfg.run_scheme == SchemeType.Advection_Reflection):
            # ref: https://github.com/ShaneFX/GAMES201/blob/master/HW01/Smoke3d/smoke_3D.py
            self.advect(self.cfg.half_dt)
            self.externalForce(ext_input, self.cfg.half_dt)
            utils.copy_ti_field(self.grid.tmp_v, self.grid.v_pair.cur)
            # cur_v = tmp_v = u^{~1/2}, in Fig.2 in advection-reflection solver paper

            self.project()
            self.grid.subtract_gradient(self.grid.tmp_v, self.grid.p_pair.cur)
            # after projection, tmp_v = u^{1/2}, cur_v = u^{~1/2}
            utils.reflect(self.grid.v_pair.cur, self.grid.tmp_v)

            self.advect(self.cfg.half_dt)
            self.externalForce(ext_input, self.cfg.half_dt)
            self.project()
            self.grid.subtract_gradient(self.grid.v_pair.cur,
                                        self.grid.p_pair.cur)

        self.render_frame()
Пример #2
0
    def castRay(self, origin, direction, recursion=0):
        material, intersect = self.sceneIntersect(origin, direction)

        if material is None or recursion >= MAX_RECURSION_DEPTH:
            return self.currentColor
            # Si el rayo no golpeo nada o si llego al limite de recursion

        lightDir = norm(sub(self.light.position, intersect.point))
        lightDistance = length(sub(self.light.position, intersect.point))

        offsetNormal = mul(intersect.normal, 1.1)
        shadowOrigin = sub(
            intersect.point,
            offsetNormal) if dot(lightDir, intersect.normal) < 0 else sum(
                intersect.point, offsetNormal)
        shadowMaterial, shadowIntersect = self.sceneIntersect(
            shadowOrigin, lightDir)
        shadowIntensity = 0

        if shadowMaterial and length(sub(shadowIntersect.point,
                                         shadowOrigin)) < lightDistance:
            shadowIntensity = 0.9

        intensity = self.light.intensity * max(
            0, dot(lightDir, intersect.normal)) * (1 - shadowIntensity)

        reflection = reflect(lightDir, intersect.normal)
        specularIntensity = self.light.intensity * (max(
            0, -dot(reflection, direction))**material.spec)

        if material.albedo[2] > 0:
            reflectDir = reflect(direction, intersect.normal)
            reflectOrigin = sub(intersect.point, offsetNormal) if dot(
                reflectDir, intersect.normal) < 0 else sum(
                    intersect.point, offsetNormal)
            reflectedColor = self.castRay(reflectOrigin, reflectDir,
                                          recursion + 1)
        else:
            reflectedColor = self.currentColor

        if material.albedo[3] > 0:
            refractDir = refract(direction, intersect.normal,
                                 material.refractionIndex)
            refractOrigin = sub(intersect.point, offsetNormal) if dot(
                refractDir, intersect.normal) < 0 else sum(
                    intersect.point, offsetNormal)
            refractedColor = self.castRay(refractOrigin, refractDir,
                                          recursion + 1)
        else:
            refractedColor = self.currentColor

        diffuse = material.diffuse * intensity * material.albedo[0]
        specular = Color(255, 255,
                         255) * specularIntensity * material.albedo[1]
        reflected = reflectedColor * material.albedo[2]
        refracted = refractedColor * material.albedo[3]

        return diffuse + specular + reflected + refracted
Пример #3
0
    def ray_trace(self, ray, depth=0):
        # Find nearest intersection for ray, compute reflected ray and call recursively
        # with depth += 1 until depth == max_depth or no intersection is found.
        color = np.array([0, 0, 0], dtype=np.float32)
        dist, obj = self.find_nearest_hit(ray)
        if dist is None:
            return color
        point = ray.origin + ray.dir * dist
        normal = obj.get_normal(point)
        if np.dot(-ray.dir, normal) < 0:
            normal = -normal

        lights = []
        for light in self.scene.lights:
            dist = math.inf
            if type(light) == scene.point_light.PointLight:
                dist = np.linalg.norm(point - light.pos)
            if not self.is_blocked(point + normal * self.bias, light, dist):
                lights.append(light)

        color += obj.material.get_color(point, normal, ray, lights)

        if depth < self.max_depth:
            if type(obj.material) is RefBlinnMaterial or type(
                    obj.material) is ReflectiveMaterial:
                color += self.ray_trace(
                    Ray(point + normal * self.bias, None,
                        reflect(ray.dir, normal)),
                    depth + 1) * obj.material.ref
            else:
                kr = obj.material.fresnel(ray.dir, normal)
                outside = np.dot(ray.dir, normal) < 0
                bias = self.bias * normal
                refraction_col = np.zeros(3)
                if kr < 1:
                    if outside:
                        refraction_orig = point - bias
                    else:
                        refraction_orig = point + bias
                    refraction_dir = refract(ray.dir, normal, obj.material.ior)
                    refraction_col = self.ray_trace(
                        Ray(refraction_orig, None, refraction_dir), depth + 1)
                reflection_dir = reflect(ray.dir, normal)
                if outside:
                    reflection_orig = point + bias
                else:
                    reflection_orig = point - bias
                reflection_col = self.ray_trace(
                    Ray(reflection_orig, None, reflection_dir), depth + 1)
                color += (reflection_col * kr + refraction_col *
                          (1 - kr) * self.refr_att)
        return color
Пример #4
0
    def castRay(self, origin, direction):
        material, intersect = self.sceneIntersect(origin, direction)
        
        if material is None:
            return self.currentColor

        lightDir = norm(sub(self.light.position, intersect.point))
        lightDistance = length(sub(self.light.position, intersect.point))
        
        offsetNormal = mul(intersect.normal, 1.1)
        shadowOrigin = sub(intersect.point, offsetNormal) if dot(lightDir, intersect.normal) < 0 else sum(intersect.point, offsetNormal)
        shadowMaterial, shadowIntersect = self.sceneIntersect(shadowOrigin, lightDir)
        shadowIntensity = 0

        if shadowMaterial and length(sub(shadowIntersect.point, shadowOrigin)) < lightDistance:
            shadowIntensity = 0.9

        intensity = self.light.intensity * max(0, dot(lightDir, intersect.normal)) * (1 - shadowIntensity)

        reflection = reflect(lightDir, intersect.normal)
        specularIntensity = self.light.intensity * (
            max(0, -dot(reflection, direction)) ** material.spec
        )

        diffuse = material.diffuse * intensity * material.albedo[0]
        specular = Color(255, 255, 255) * specularIntensity * material.albedo[1]
        return diffuse + specular
Пример #5
0
    def calculate_intensity(self, origin, direction, intersection, dept):
        light_intensity = 0
        specular_light_intensity = 0

        if not self._options['light']:
            return 1, 0

        for light in self._scene.lights:
            light_dir = (light.position - intersection.point).normalize()
            light_distance = (light.position - intersection.point).norm()
            
            if self._options['shadow']:
                shadow_origin = utils.build_origin(intersection.point, light_dir, intersection.normal)
                shadow_intersection = self._scene.intersect(shadow_origin, light_dir)

                if shadow_intersection:
                    if (shadow_intersection.point - shadow_origin).norm() < light_distance:
                        continue
            
            light_intensity += light.intensity * max(0, light_dir * intersection.normal)

            if self._options['specular_light']:
                reflect_scalar = -utils.reflect(-light_dir, intersection.normal) * direction
                reflect_scalar = max(0, reflect_scalar)

                specular_light_intensity += math.pow(reflect_scalar, intersection.material.specular_exponent) * light_intensity
            else:
                specular_light_intensity = 0

        return light_intensity, specular_light_intensity
Пример #6
0
    def scatter(self, ray, hitrec):
        reflected = reflect(ray.direction, hitrec.normal)
        if (np.dot(ray.direction, hitrec.normal) > 0.0):
            outward_normal = -hitrec.normal
            ni_over_nt = self.ref_idx
            cosine = self.ref_idx * np.dot(ray.direction, hitrec.normal) / (
                math.sqrt(np.sum(ray.direction * ray.direction)))
        else:
            outward_normal = hitrec.normal
            ni_over_nt = 1.0 / self.ref_idx
            cosine = -np.dot(ray.direction, hitrec.normal) / (math.sqrt(
                np.sum(ray.direction * ray.direction)))

        is_refract, refracted = refract(ray.direction, outward_normal,
                                        ni_over_nt)
        if (is_refract):
            reflect_prob = schlick(cosine, self.ref_idx)
        else:
            reflect_prob = 1.0
        if (random.uniform(0.0, 1.0) < reflect_prob):
            scattered = Ray(hitrec.p, reflected)
        else:
            scattered = Ray(hitrec.p, refracted)

        return True, scattered, np.array([1.0, 1.0, 1.0])
Пример #7
0
    def scatter(self, info, r):
        normal = info['normal']
        ray_inside = info['ray_inside']
        p = info['P']

        v = r.direc
        cos_theta = numpy.dot(-v, normal)
        sin_theta = sqrt(1 - cos_theta**2)
        eta_ratio = self.eta if ray_inside else 1 / self.eta

        if eta_ratio * sin_theta > 1.0:
            return Ray(p, reflect(v, normal))

        if random() < schlick(cos_theta, eta_ratio):
            return Ray(p, reflect(v, normal))

        return Ray(p, refract(v, normal, eta_ratio))
Пример #8
0
 def scatter(self, info, r):
     normal = info['normal']
     p = info['P']
     v = r.direc
     ref_v = reflect(v, normal) + self.blur * random_unit_sphere()
     if numpy.dot(ref_v, normal) > 0.0:
         return Ray(p, ref_v)
     else:
         return None
Пример #9
0
    def collides_with_player(self):
        """Update the velocity when a collision with the player occurs."""
        if self.current_power_up == PowerUpType.CATCH:
            self.stick(self.player)
            self.bottom = self.player.top
        else:
            v = Vector(x=self.change_x, y=self.change_y)
            location = self.player.collision_location(self)
            normal = Vector(0, 1)

            # Determine where the ball collided to "enhance" angle of reflection
            if location == Player.LEFT:
                normal = Vector(0.196, -0.981)
            elif location == Player.RIGHT:
                normal = Vector(-0.196, -0.981)

            new_v = reflect(v, normal)
            self.change_x = new_v.x
            self.change_y = new_v.y

            # Increase the speed modifier on each collision when the
            # SLOW power up is picked up
            self.increase_speed_mod()
Пример #10
0
 def extract_v(array, collumns):
     out = array[:, collumns]
     return reflect(out)
Пример #11
0
 def _reflect(cls, v, normal):
     return utils.reflect(v, normal)