Raytracer反射不一致

时间:2018-05-20 12:48:08

标签: python vector 3d raytracing

我正在用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 :(得分: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))

我试图弄清楚这几个小时,吸取了教训。