Отражения Raytracer противоречивы - PullRequest
0 голосов
/ 20 мая 2018

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

1 Ответ

0 голосов
/ 20 мая 2018

Оказывается, это была простая опечатка в моей функции величины.

У меня было это:

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))

Я пыталсячтобы понять это часами, урок усвоен.

...