Я пишу простой raytracer на 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 (изначально глубина) неправильны, но я не понимаю, почему, каждый пример, который я нашел в Интернете, использует точно такие же вычисления нормалей и отражений, так почему я получаю такой странный результат?.