Python 光线追踪
我正在用纯 Python 构建一个简单的 Python 光线追踪器(只是为了好玩),但我遇到了障碍。
目前我的场景设置是这样的:
- 相机位于
0, -10, 0
,沿着 y 轴指向。 - 半径
1
位于0, 0, 0
的球体。 - 成像平面物体距离相机
1
,宽度和高度为0.5
。
我在成像平面上以均匀随机分布的方式拍摄光子,如果光子碰巧与物体相交,我会在图像画布上画一个红点,对应于图像平面上光线穿过的点。
我的交集代码(我只有球体):
def intersection(self, ray):
cp = self.pos - ray.origin
v = cp.dot(ray.direction)
discriminant = self.radius**2 - cp.dot(cp) + v * v
if discriminant < 0:
return False
else:
return ray.position(v - sqrt(discriminant)) # Position of ray at time t
和我的渲染代码(它渲染一定数量的光子,而不是逐像素):
def bake(self, rays):
self.image = Image.new('RGB', [int(self.camera.focalplane.width * 800), int(self.camera.focalplane.height * 800)])
canvas = ImageDraw.Draw(self.image)
for i in xrange(rays):
x = random.uniform(-camera.focalplane.width / 2.0, camera.focalplane.width / 2.0)
z = random.uniform(-camera.focalplane.height / 2.0, camera.focalplane.height / 2.0)
ray = Ray(camera.pos, Vector(x, 1, z))
for name in scene.objects.keys():
result = scene.objects[name].intersection(ray)
if result:
n = Vector(0, 1, 0)
d = ((ray.origin - Point(self.camera.pos.x, self.camera.pos.y + self.camera.focalplane.offset, self.camera.pos.z)).dot(n)) / (ray.direction.dot(n))
pos = ray.position(d)
x = pos.x
y = pos.y
canvas.point([int(self.camera.focalplane.width * 800) * (self.camera.focalplane.width / 2 + x) / self.camera.focalplane.width,
int(self.camera.focalplane.height * 800) * (self.camera.focalplane.height / 2 + z) / self.camera.focalplane.height],
fill = 128)
它应该正常工作,但是当我渲染测试图像时,我没有得到任何看起来像的东西球体的轮廓:
我期待这样的内容:
有人知道为什么我的代码无法正常运行吗?我已经调整和重写这一部分太久了......
I'm building a simple Python raytracer with pure Python (just for the heck of it), but I've hit a roadblock.
The setup of my scene is currently this:
- Camera located at
0, -10, 0
pointing along the y-axis. - Sphere with radius
1
located at0, 0, 0
. - Imaging plane-thing is a distance of
1
away from the camera and has a width and height of0.5
.
I'm shooting photons in a uniformly randomly distribution through the imaging plane, and if a photon happens to intersect an object, I draw a red dot on the image canvas corresponding to the point on the image plane through which the ray passed.
My intersection code (I only have spheres):
def intersection(self, ray):
cp = self.pos - ray.origin
v = cp.dot(ray.direction)
discriminant = self.radius**2 - cp.dot(cp) + v * v
if discriminant < 0:
return False
else:
return ray.position(v - sqrt(discriminant)) # Position of ray at time t
And my rendering code (it renders a certain number of photons, not pixel-by-pixel):
def bake(self, rays):
self.image = Image.new('RGB', [int(self.camera.focalplane.width * 800), int(self.camera.focalplane.height * 800)])
canvas = ImageDraw.Draw(self.image)
for i in xrange(rays):
x = random.uniform(-camera.focalplane.width / 2.0, camera.focalplane.width / 2.0)
z = random.uniform(-camera.focalplane.height / 2.0, camera.focalplane.height / 2.0)
ray = Ray(camera.pos, Vector(x, 1, z))
for name in scene.objects.keys():
result = scene.objects[name].intersection(ray)
if result:
n = Vector(0, 1, 0)
d = ((ray.origin - Point(self.camera.pos.x, self.camera.pos.y + self.camera.focalplane.offset, self.camera.pos.z)).dot(n)) / (ray.direction.dot(n))
pos = ray.position(d)
x = pos.x
y = pos.y
canvas.point([int(self.camera.focalplane.width * 800) * (self.camera.focalplane.width / 2 + x) / self.camera.focalplane.width,
int(self.camera.focalplane.height * 800) * (self.camera.focalplane.height / 2 + z) / self.camera.focalplane.height],
fill = 128)
It should work properly, but when I render a test image, I get nothing that looks like the outline of a sphere:
I was expecting something like this:
Does anybody know why my code isn't functioning properly? I've been tweaking and rewriting this one part for way too long...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在标准化光线的方向矢量吗?
Are you normalising the ray's direction vector?