Search code examples
javareflectionintersectionraytracing

Raytracing reflection incorrect


Hello I build a raytracer in java and everything works fine but if i set 3 spheres on the same z axis the reflection doesnt work and if I change the z axis from the spheres it will work fine. In the following you can see the picture. There you can see the one sphere does the reflection correctly if it is not on the same z axis.

[Raytracer] [1]: https://i.sstatic.net/MSeCp.png

In the following is my code for calculate the Intersection.

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;
}

and then in the other method i do:

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

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

In the following I calculate the reflection

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

I cant understand why the reflection works fine and calculated everything right and only if its the same z axis it doesnt work. I will be really happy if somebody can help me :)


Solution

  • the problem was the 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]);
    

    I removed the v[] and it worked perfektly :)

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