我正在用python编写一个小的光线跟踪器,一切都很好,但是当我实现平面几何体时,反射球体的底部会有奇怪的补丁。下图:
我想这是因为在使用错误法线计算照明时出现了一些错误?但我不知道到底是什么
编辑:当我将平面向下移动一个单位时,它消失了,这可能是因为球体上方的点光源吗?为了检查这一点,我删除了所有的灯,但仍然,我得到了这个补丁
用于查找palne ray交点的代码:
class Plane(Shape):
def __init__(self, color, y=0, specular=-1, reflective=0):
self.specular = specular
self.reflective = reflective
self.center = Vec3(0,y,0)
self.normal = Vec3(0,-1,0)
self.color = color
def intersect_at_point(self, origin, ray):
denom = ray.dot(self.normal)
if abs(denom) > 0.0001:
diff = self.center - ray
t = diff.dot(self.normal) / denom
if t > 0.0001:
return t
return None
跟踪光线功能
def trace_ray(self, origin, direction, t_min, t_max, depth):
closest_object, closest_t = self.closest_intersection(origin, direction, t_min, t_max)
if closest_object == None:
return Vec3(173/255, 216/255, 230/255)
# Compute local color
P = origin + closest_t * direction # Compute intersection
N = P - closest_object.center # Compute normal at intersection
N = N / N.mag()
local_color = closest_object.color * self.compute_light(P, N)
# If we hit the recursion limit or the object is not reflective, we're done
r = closest_object.reflective
if depth <= 0 or r <= 0:
return local_color
# Compute the reflected color
R = self.reflect_ray(-1*direction, N)
reflected_color = self.trace_ray(P, R, 0.001, math.inf, depth - 1)
return local_color * (1 - r) + reflected_color * r
最近交点法
def closest_intersection(self, O, D, t_min, t_max):
closest_t = math.inf
closest_object = None
for object in self.world.objects:
t1, t2 = object.intersect_at_point(O, D)
if (t_min < t1 < t_max) and t1 < closest_t:
closest_t = t1
closest_object = object
if (t_min < t2 < t_max) and t2 < closest_t:
closest_t = t2
closest_object = object
for plane in self.world.planes:
t = plane.intersect_at_point(O,D)
if t and (t_min < t < t_max) and t < closest_t:
closest_t = t
closest_object = plane
return closest_object, closest_t
计算光照法
def compute_light(self, Point, Normal):
i = 0.0
P = Point
N = Normal
for light in self.world.lights:
if light.type == 'ambient':
i += light.intensity
else:
if light.type == 'point':
L = light.position - P
t_max = 1
if light.type == 'directional':
L = light.direction
t_max = math.inf
# Shadow check
shadow_sphere, shadow_t = self.closest_intersection(P, L, 0.001, t_max)
if shadow_sphere != None:
continue
n_dot_l = N.dot(L)
if n_dot_l > 0:
# print(f'light intensity {light.intensity}')
i+= light.intensity * n_dot_l / (N.mag() * L.mag())
return i
目前没有回答
相关问题 更多 >
编程相关推荐