def look_at_matrix(camera_position: np.ndarray, camera_target: np.ndarray, camera_up: np.ndarray): z_axis = Utils.normalize(np.array(camera_position - camera_target)) x_axis = Utils.normalize(np.cross(camera_up, z_axis)) y_axis = np.cross(z_axis, x_axis) translation_x = -np.dot(x_axis, camera_position) translation_y = -np.dot(y_axis, camera_position) translation_z = -np.dot(z_axis, camera_position) translation = np.array([translation_x, translation_y, translation_z]).reshape((3, 1)) x_axis = x_axis.reshape((3, 1)) y_axis = y_axis.reshape((3, 1)) z_axis = z_axis.reshape((3, 1)) translation = translation.reshape((3, 1)) #TODO: Make this more efficient mat = np.append(np.append(np.append(x_axis, y_axis, axis=1), z_axis, axis=1), translation, axis=1) return np.append(mat, Utils.homogenous_for_SE3(), axis=0)
def render(self): (height, width) = self.resolution for x in range(0, width): for y in range(0, height): ray_direction_camera_space = self.camera.camera_ray_direction_camera_space( x, y, width, height, self.fov) camera_to_world = self.camera.se3_inv rot = SE3.extract_rotation(camera_to_world) ray_world_space = Utils.normalize( np.matmul(rot, ray_direction_camera_space)) ray = Geometry.Ray(self.camera.origin_ws[0:3], ray_world_space) (b, t, sphere) = self.find_closest_intersection(ray) if sphere.is_intersection_acceptable(b, t): intersection_point = Geometry.point_for_ray(ray, t) normal = sphere.normal_for_point(intersection_point) depth = intersection_point[2] self.depth_buffer[y, x] = fabs(depth) self.frame_buffer[y, x] = phong_shading( self.light_ws, intersection_point, normal)
def camera_ray_direction_camera_space(self, pixel_x, pixel_y, width, height, fov): (camera_x, camera_y) = self.pixel_to_camera(pixel_x, pixel_y, width, height, fov) ray_cs = np.array([camera_x, camera_y, -1]).reshape(3, 1) return Utils.normalize(ray_cs)
def normal_for_point(self,point_on_shpere): return Utils.normalize(point_on_shpere - self.origin)
def phong_shading(light_ws, position_ws, normal): view = Utils.normalize(light_ws - position_ws) return Utils.fast_dot(view, normal)