Thread: RayTracer truble

  1. #1
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485

    RayTracer truble

    Hallo,

    I am working on a small raytracer and Im now at the point where I want to add lights to it.
    But for some reason I allways get no light on the object, so the object becomes black

    Here is my code for adding light:
    Code:
                    float r, g, b;
                    
                    // Check which if there is a light affecting the sphere
                    for (int currentLight = 0; currentLight <= thisScene.getAmountOfObjects(); currentLight++)
                    {
                        Vector3D sphereRayIntersection;
                        Point rayOrg = currentRay.getOrigin();
                        
                        // Add the start point of the ray and the direction of the sphere together
                        // and mult. it with the distance to closest sphere
                        sphereRayIntersection = currentRay.getDirection();
                        sphereRayIntersection.setX(sphereRayIntersection.getX() + rayOrg.getX());
                        sphereRayIntersection.setY(sphereRayIntersection.getY() + rayOrg.getY());
                        sphereRayIntersection.setZ(sphereRayIntersection.getZ() + rayOrg.getZ());
                        
                        sphereRayIntersection.scale(closesSphereDistance);
                        
                        
                        
                        // Find the normal to the sphere at point of intersection
                        Sphere thisSphere = thisScene.getSphere(closestSphere);
                        Vector3D normal;
                        float oneOverRadius = 1/thisSphere.getRadius();
                        
                        normal = sphereRayIntersection - thisSphere.getPosition();
                        normal.scale(oneOverRadius);
                        
                        normal.normalize();
                        
                        // Get the light direction
                        Vector3D lightDir;
                        
                        Sphere thisLight = thisScene.getLight(currentLight);
                        lightDir = thisLight.getPosition() - sphereRayIntersection;
                        
                        lightDir.normalize();
    
                        
                        
                        // Find light coefficient
                        float lightCoef = Dot(lightDir,normal);
                        if (lightCoef < 0)
                           lightCoef = 0;
                           
                        
                        // Get the color of the light and how much it affects the sphere
                        Material thisMaterial = thisLight.getMaterial();
                        
                        float lightR = thisMaterial.getR() * lightCoef;
                        float lightG = thisMaterial.getG() * lightCoef;
                        float lightB = thisMaterial.getB() * lightCoef;
                        
                        
                        // Add the effect of the light to the color of the sphere
                        Material sphereColor = thisSphere.getMaterial();
                        
                         r = ((sphereColor.getR() * lightR) / 255 );
                         g = ((sphereColor.getG() * lightG) / 255);
                         b = ((sphereColor.getB() * lightB) / 255);
                         
                         
                        
                        // Make sure that the color is not higher than 255
                        if (r > 255)
                           r = 255;
                        if (g > 255)
                           g = 255;
                        if (b > 255)
                           b = 255;
                           
                           //std::cout << r << "," << g << "," << b << std::endl;
                    }
                           
                    // Assign the color to the pixel
                    int colorR = r;
                    int colorG = g;
                    int colorB = b;
                    
                    colorBuffer[arrayTracer + 0] = colorR;
                    colorBuffer[arrayTracer + 1] = colorG;
                    colorBuffer[arrayTracer + 2] = colorB;
    I am almost sure the problem is the "lightCoef" variable, as it is never above 0. So when I later use that to multiply the color the result is 0.

    But I am not sure why this happpens.

    Sorry if this is the wrong place to post this and thanks for you time.

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    I think you're going to have to print out some of your variables to a file (if you can't output them to the screen) to see what's happening. But as you said, looking at your code, if lightCoef is zero, it would explain things.

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    If lightCoef is coming out negative it means that either the Dot() function is broken, or the angle between the two vectors is more than 90 degrees (which implies that the surface normal at the intersection point is facing away from the light source, in other words, it is shadowed by the rest of the sphere)

    When you intersect a ray with a sphere (you didn't post the code that does it), remember that there are usually two intersection points and you should use the closer one. The farther one is obviously shadowed by the sphere.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    Thanks for your reply.

    lightCoef = 0 is only part of the problem. A tryed to do AbsDot() insted of Dot() to see if that helped. Than I got the color and the sphere is displayed, but there is no gradient on the sphere eg. its still a flat color.

    I have been printing variables, but still no clue on what is wrong

    Any ideas would be great.

  5. #5
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    I think your problem might be here:

    // Add the start point of the ray and the direction of the sphere together
    // and mult. it with the distance to closest sphere

    If you always add the distance to the sphere, all intersection points are the same distance from the view plane, and thus you render a flat surface (which explains the lack of gradient you're seeing).

    in the line:
    sphereRayIntersection.scale(closesSphereDistance);

    is closesSphereDistance the distance from the view plane to the centre of the closest sphere? (this would be wrong). Or is it the distance to the intersection point of the ray and the sphere, to the origin of the ray?

  6. #6
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    I have found at that there is a mistake as you mentioned.
    It should be :
    Code:
                        // Add the start point of the ray and the direction of the sphere together
                        // and mult. it with the distance to closest sphere
                        sphereRayIntersection = currentRay.getDirection();
                        sphereRayIntersection.setX(rayOrg.getX() + (sphereRayIntersection.getX() * closesSphereDistance ));
                        sphereRayIntersection.setY(rayOrg.getY() + (sphereRayIntersection.getY() * closesSphereDistance ));
                        sphereRayIntersection.setZ(rayOrg.getZ() + (sphereRayIntersection.getZ() * closesSphereDistance ));
    Its the distance from where the ray is created to where it hits the sphere
    Last edited by h3ro; 04-19-2007 at 05:35 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array truble
    By Rune Hunter in forum C++ Programming
    Replies: 2
    Last Post: 07-12-2007, 10:02 PM
  2. More dynamic array truble
    By h3ro in forum C++ Programming
    Replies: 7
    Last Post: 04-19-2007, 02:50 AM