Last active
February 28, 2021 16:23
-
-
Save spacekitcat/cc3ae3b73076561796872507e6e7b9dc to your computer and use it in GitHub Desktop.
Naive ray tracer implementation 00. It renders two spheres with inverted z values, the z value goes between 0 and 15, simulating a bounce effect.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame as pg | |
import numpy as np | |
def is_exit_key(e): | |
return e.type == pg.KEYUP and (e.key == pg.K_ESCAPE or e.key == pg.K_q) | |
class GameObject: | |
def __init__(self, position, colour): | |
self.position = position | |
self.colour = colour | |
def get_position(self): | |
return self.position | |
def get_colour(self): | |
return self.colour | |
def increment_position(self, increment): | |
self.position = np.add(self.position, increment) | |
def intersect(game_object, origin, draw_distance): | |
for i in range(0, draw_distance): | |
distance = abs(np.linalg.norm( | |
np.subtract(origin, np.array([0, 0, i]) + game_object[1].get_position()))) | |
result = distance < game_object[0] | |
if result: | |
return True | |
return False | |
def sort_game_objects_by_distance(game_objects): | |
sorted_game_objects = [] | |
# TODO: Blah bee de blah, sort the whole list | |
# TODO: Use vector distance from viewport (not z distance from viewport z) | |
if game_objects[0][1].get_position()[2] < game_objects[1][1].get_position()[2]: | |
sorted_game_objects.append(game_objects[1]) | |
sorted_game_objects.append(game_objects[0]) | |
else: | |
sorted_game_objects.append(game_objects[0]) | |
sorted_game_objects.append(game_objects[1]) | |
return sorted_game_objects | |
def render(screen, origin, view, game_objects, draw_distance): | |
info = pg.display.Info() | |
for i in range(0, info.current_w): | |
for j in range(0, info.current_h): | |
current_origin = np.add(np.subtract(origin, view), (i, j, 0)) | |
for game_object in sort_game_objects_by_distance(game_objects): | |
if intersect(game_object, current_origin, draw_distance): | |
screen.set_at((i, j), game_object[1].get_colour()) | |
def main(): | |
game_objects = [ | |
(20, GameObject(np.array([25, 25, 0]), (98, 220, 227))), | |
(20, GameObject(np.array([50, 25, 15]), (227, 98, 98))) | |
] | |
clock = pg.time.Clock() | |
pg.init() | |
pg.mouse.set_visible(False) | |
screen = pg.display.set_mode([75, 50]) | |
pg.display.set_caption("Jump! Bounce! Down! Up!") | |
black = 20, 20, 40 | |
screen.fill(black) | |
done = 0 | |
increment = np.array([0, 0, 1]) | |
origin = np.array([0, 0, 0]) | |
view = np.array([0, 0, 0]) | |
while not done: | |
for e in pg.event.get(): | |
if e.type == pg.QUIT or is_exit_key(e): | |
done = 1 | |
break | |
if e.type == pg.KEYUP and e.key == pg.K_LEFT: | |
view = np.add(view, np.array([-1, 1, 1])) | |
if e.type == pg.KEYUP and e.key == pg.K_RIGHT: | |
view = np.add(view, np.array([1, -1, 1])) | |
screen.fill(black) | |
render(screen, origin, view, game_objects, 20) | |
pg.display.update() | |
if (game_objects[0][1].get_position()[2] > 15): | |
increment = np.array([0, 0, -1]) | |
elif (game_objects[0][1].get_position()[2] < 0): | |
increment = np.array([0, 0, 1]) | |
game_objects[0][1].increment_position(increment) | |
game_objects[1][1].increment_position(-increment) | |
clock.tick(5) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ray-trace-demo.mov
Look how slow it is!