如何解决Raymarcher 很慢
我正在 pygame 中制作一个 raymarcher,它超级慢。我想不出办法让它更快。我尝试使用多个线程,但没有用。我尝试了所有我能想到的方法,但没有奏效。如果有人能给我一个答案以加快速度,我将不胜感激。
raymarcher.py:
import pygame as pg
import math
import threading as t
def clamp(num,sml,lrg):
return max(sml,min(num,lrg))
class Vector3:
def __init__(self,x,y,z):
self.x = x
self.y = y
self.z = z
def __add__(self,other):
return Vector3(self.x + other.x,self.y + other.y,self.z + other.z)
def __sub__(self,other):
return Vector3(self.x - other.x,self.y - other.y,self.z - other.z)
def __repr__(self):
return f"({self.x},{self.y},{self.z})"
@staticmethod
def norm(pos):
return (pos.x ** 2 + pos.y ** 2 + pos.z ** 2) ** 0.5
def magnitude(self):
return math.sqrt(self.x ** 2 + self.y ** 2 + self.z ** 2)
def normalize(self):
m = self.magnitude()
if m > 0:
return Vector3(self.x / m,self.y / m,self.z / m)
class Vector2:
def __init__(self,y):
self.x = x
self.y = y
def __add__(self,other):
return Vector2(self.x + other.x,self.y + other.y)
def __sub__(self,other):
return Vector2(self.x - other.x,self.y - other.y)
def __repr__(self):
return f"({self.x},{self.y})"
@staticmethod
def norm(pos):
return (pos.x ** 2 + pos.y ** 2) ** 0.5
def magnitude(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
def normalize(self):
m = self.magnitude()
if m > 0:
return Vector2(self.x / m,self.y / m)
class Color:
def __init__(self,r,g,b):
self.r = r
self.g = g
self.b = b
@staticmethod
def hex(hexCol):
if hexCol[0] == "#":
if len(hexCol) == 7:
red = int(hex(int("0x" + hexCol[1:2],16)))
green = int(hex(int("0x" + hexCol[3:4],16)))
blue = int(hex(int("0x" + hexCol[5:6],16)))
return Color(red,green,blue)
else:
raise Exception("Invalid hex color")
else:
raise Exception("Hex color doesn't start with '#'")
def __mul__(self,other):
return Color(self.r * other,self.g * other,self.b * other)
def __repr__(self):
return f"({self.r},{self.g},{self.b})"
class Ray:
def __init__(self,pos,ang):
self.pos = pos
self.point = pos
self.angle = ang
def advance(self,amount):
self.point += Vector3(math.sin(self.angle.x) * amount,math.sin(self.angle.z))
class Sphere:
def __init__(self,radius,color):
self.pos = pos
self.radius = radius
self.color = color
def getdist(self,point):
return Vector3.norm(point - self.pos) - self.radius
class Light:
def __init__(self,pos):
self.pos = pos
WIDTH = 800
HEIGHT = 600
screen = pg.display.set_mode((WIDTH,HEIGHT))
shapes = [Sphere(Vector3(0,10),2,Color(255,0))]
def Raymarch():
tiMetaken = 0
left = 0
y = 0
while y < HEIGHT:
x = 0
while x < WIDTH:
r = Ray(Vector3(x - WIDTH // 2,y - HEIGHT // 2,0),Vector3(0,0))
dist = 0
collides = False
i = 0
while i < 10:
distance = min([s.getdist(r.point) / 10 for s in shapes])
if distance < 5:
collides = True
break
r.advance(distance)
i += 1
finalPos = r.point
if collides:
dists = [[s.getdist(finalPos),s.color] for s in shapes]
dists.sort(key=lambda x: x[0])
color = dists[0][1]
else:
color = Color(255,255,255)
screen.set_at((x,y),(clamp(round(color.r),255),clamp(round(color.g),clamp(round(color.b),255)))
x += 1
tiMetaken += 1
left = round(tiMetaken / (WIDTH * HEIGHT) * 100,1)
leftPrint = f"{left}%"
print(leftPrint,end="\r")
y += 1
thread = t.Thread(target=Raymarch,daemon=True)
thread.start()
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
pg.display.update()
解决方法
我修改了 def RayMarch
以仅在每行末尾打印:
def RayMarch():
timeTaken = 0
left = 0
y = 0
while y < HEIGHT:
total_prints = ''
...
total_prints += f"{left}%" + '\r'
y += 1
print(total_prints)
似乎 print()
命令需要很长时间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。