光线追踪反射不正确

Raytracing reflection incorrect

你好,我在 java 中构建了一个光线追踪器,一切正常,但如果我在同一 z 轴上设置 3 个球体,则反射不起作用,如果我从球体更改 z 轴,它将正常工作。在下面你可以看到图片。如果一个球体不在同一个 z 轴上,您可以在那里看到它正确地进行了反射。

[光线追踪器] [1]: https://i.stack.imgur.com/MSeCp.png

下面是我计算交点的代码。

private float raySphereIntersect(float[] rayE, float[] rayV, RTFile scene) {
    float t = Float.MAX_VALUE;
    float t1, t2;
    I_Sphere sphere = (I_Sphere) scene;
    
    float rayEx = rayE[0];
    float rayEy = rayE[1];
    float rayEz = rayE[2];
    
    float rayVx = rayV[0];
    float rayVy = rayV[1];
    float rayVz = rayV[2];


    // ray intersection uses quadratic equation
    float a, b, c, d;
    

    // me = vector from sphere center to eye point
    float mex, mey, mez;

    mex = rayEx - sphere.center[0];
    mey = rayEy - sphere.center[1];
    mez = rayEz - sphere.center[2];

    
    a = rayVx * rayVx + rayVy * rayVy + rayVz * rayVz;
    
    b = 2.0f * (rayVx * mex + rayVy * mey + rayVz * mez);
    
    c = mex * mex + mey * mey + mez * mez - sphere.radius * sphere.radius;

    // -> d = Diskriminante:

    // positive discriminant determines intersection
    
    d = (float) (b * b - 4 * a * c);
    // no intersection point? => next object
    

    
    if (d > 0) {
        // from here: intersection takes place!

    // calculate first intersection point with sphere along the ray
        t1 = (float) ((-b - Math.sqrt(d)) / (2 * a));
        t2 = (float) ((-b + Math.sqrt(d)) / (2 * a));
        
            

            if(t2>t1&&t1>0) {
                
                
                t=t1;
            }
            
            
            if(t2>0&&t1<0) {
                
                t=t2;
                
            }else {
                
                t=t1;
            }
        
    }

    return t;
}

然后我用另一种方法:

    if (scene instanceof I_Sphere) {
            t = raySphereIntersect(rayE, rayV, scene);
        } 

        
        if(t >= minT)
            continue;
        
        minT = t;

下面我计算反射

float [] rayE = {rayEx, rayEy, rayEz};
            float [] rayV = {rayVx, rayVy, rayVz};
            
            int maxDepth = 2;
            
            for (int d = 0; d <= gui.depth; d++) {
                float [] intersectionPoint = traceRay(rayE, rayV);
                if (intersectionPoint != null) {
                    
                    float [] intersectionNormal = getNormalFromIntersection(intersectionPoint);
                    
                    color = getColor(intersectionPoint, intersectionNormal, rayV);
                    
                    // set new origin and direction
                    rayE = intersectionPoint;
                
                    float n [] = intersectionNormal;
                    float v [] = rayV;
                    
                    normalize(v);
                    normalize(n);
                    
                    float vn = v[0] * n[0] + v[1] * n[1] + v[2] * n[2];
                    
                    rayV[0] = (v[0] + 2 * vn * n[0]);
                    rayV[1] = (v[1] + 2 * vn * n[1]);
                    rayV[2] = (v[2] + 2 * vn * n[2]);
                    

我不明白为什么反射工作正常并且计算一切正确,但只有当它是相同的 z 轴时它才不起作用。如果有人能帮助我,我将非常高兴:)

问题出在 v[]:

 rayV[0] = (v[0] + 2 * vn * n[0]);
 rayV[1] = (v[1] + 2 * vn * n[1]);
 rayV[2] = (v[2] + 2 * vn * n[2]);

我删除了 v[],它工作得很好:)

 rayV[0] = (2 * vn * n[0]);
 rayV[1] = (2 * vn * n[1]);
 rayV[2] = (2 * vn * n[2]);