我正在用Python编写一个简单的光线跟踪器,但是我在向球体添加反射时遇到了麻烦。我的代码适用于飞机,让我相信我正在错误地计算球体法线。我还注意到从不同角度观看时反射不一样,所以我添加了视频输出并获得了this。
这是我所有的球体和反射相关代码:
def get_first_intersect(ray):
distance = DRAW_DISTANCE
closest = 0.0
for s in spheres:
A = dot(ray.direction, ray.direction)
dist = ray.origin - s.center
B = 2.0 * dot(ray.direction, dist)
C = dot(dist, dist) - (s.radius*s.radius)
discr = (B*B) - (4*A*C)
if discr <= 0.0:
continue
t0 = (-B - np.sqrt(discr))/(2*A)
t1 = (-B + np.sqrt(discr))/(2*A)
if t0 < 0.0 and t1 < 0.0:
continue
elif t0 < 0.0:
d = t1
elif t1 < 0.0:
d = t0
else:
d = min(t0, t1)
if d < distance:
closest = s
distance = d
return closest, d
def normalize (a):
d = magnitude(a)
if d == 0.0:
return Vector3(0,0,0)
return Vector3(a.x/d, a.y/d, a.z/d)
def scale (a, k):
b = Vector3(a.x * k, a.y * k, a.z * k)
return b
def dot (a, b):
return (a.x*b.x) + (a.y*b.y) + (a.z*b.z)
def reflect (incident, intersect, normal):
incident = normalize(incident)
normal = normalize(normal)
direction = incident - scale(normal, 2.0*dot(incident, normal))
direction = normalize(direction)
origin = intersect + scale(direction, 0.0001)
return Ray(origin, direction)
def trace (ray, reursion_depth):
reursion_depth += 1
o, d = get_first_intersect(ray)
scaled = scale(normalize(ray.direction), d)
intersect = ray.origin + scaled
norm = intersect - o.center
norm = normalize(norm)
if o.reflectivity > 0.0 and reursion_depth < MAX_RECURSIONS:
reflection_color = trace( reflect(ray.direction, intersect, norm), reursion_depth )
color = (color[0] + (reflection_color[0]*o.reflectivity),
color[1] + (reflection_color[1]*o.reflectivity),
color[2] + (reflection_color[2]*o.reflectivity))
color = (np.clip(color[0], 0, 255),
np.clip(color[1], 0, 255),
np.clip(color[2], 0, 255))
return color
已删除代码的照明和平面部分。视频输出似乎表明Z方向上的反射(最初的深度)不正确,但我不明白为什么,我在网上找到的每个例子都使用完全相同的法线和反射计算,为什么我会得到如此奇怪的结果
答案 0 :(得分:0)
原来这是我的量级函数中的一个简单错字。
我有这个:
def magnitude (a):
return np.sqrt((a.z*a.z) + (a.y*a.y) + (a.z*a.z))
而不是:
def magnitude (a):
return np.sqrt((a.x*a.x) + (a.y*a.y) + (a.z*a.z))
我试图弄清楚这几个小时,吸取了教训。