문제

I am struggling massively with an assignment where I am supposed to implement a raytracer. I have a basic raytracer done but I have almost no idea how to implement shadows. I will include some of the functions we have to program and some of the data structures we are given. I think I know in theory on what to do but I am completely clueless on how to implement any of this properly.

void Raytracer::computeShading( Ray3D& ray ) {
LightListNode* curLight = _lightSource;
Ray3D shadowRay;
for (;;) {
    if (curLight == NULL) break;
    // Each lightSource provides its own shading function.

    // Implement shadows here if needed.
    if (!ray.intersection.none) {
        shadowRay.origin = ray.intersection.point + 0.01 * ray.dir;
        shadowRay.dir = (curLight->light->get_position() - ray.intersection.point);
        shadowRay.dir.normalize();
        
    }

        curLight->light->shade(ray);
        curLight = curLight->next;
    }
    
}

}

Colour Raytracer::shadeRay( Ray3D& ray ) {
Colour col(0.0, 0.0, 0.0);
traverseScene(_root, ray);

// Don't bother shading if the ray didn't hit 
// anything.
if (!ray.intersection.none) {
    
    computeShading(ray); 
    col = ray.col;  
}


// You'll want to call shadeRay recursively (with a different ray, 
// of course) here to implement reflection/refraction effects.  

return col; 

}

struct Intersection {
// Location of intersection.
Point3D point;
// Normal at the intersection.
Vector3D normal;
// Material at the intersection.
Material* mat;
// Position of the intersection point on your ray.
// (i.e. point = ray.origin + t_value * ray.dir)
// This is used when you need to intersect multiply objects and
// only want to keep the nearest intersection.
double t_value; 
// Set to true when no intersection has occured.
bool none;

};

// Ray structure. 
struct Ray3D {
Ray3D() {
    intersection.none = true; 
}
Ray3D( Point3D p, Vector3D v ) : origin(p), dir(v) {
    intersection.none = true;
}
// Origin and direction of the ray.
Point3D origin;
Vector3D dir;
// Intersection status, should be computed by the intersection
// function.
Intersection intersection;
// Current colour of the ray, should be computed by the shading
// function.
Colour col;

};

endif

We are supposed to implement shadows in computerShading, although I trhink we have to do something in shadeRay as well but I am not really sure. I am not sure whether in computerShading I am supposed to calculate the ray intersectiion or create a new ray before I calculate the ray intersection or after or I must computer the new ray first and calculate the intersection. We also have a colour function. I also implemented some intersection functions for a unit square and sphere, both work, but I just don't understand how to get shadows! I am just really really lost. Please any help would be great!

EDIT: Okay so I added some stuff but I am not getting any shadow or I am getting a complete black image depending on the change of parameters:

void Raytracer::computeShading( Ray3D& ray ) {
LightListNode* curLight = _lightSource;
for (;;) {
    Ray3D shadowRay;
    if (curLight == NULL) break;
    // Each lightSource provides its own shading function.

    // Implement shadows here if needed.
    shadowRay.origin = ray.intersection.point + 0.01*ray.dir;
    shadowRay.dir = curLight->light->get_position() - ray.intersection.point;
    shadowRay.dir.normalize();
    traverseScene(_root, shadowRay);
    if (shadowRay.intersection.t_value >= 0.0 && shadowRay.intersection.t_value <= 1.0) {
        shadowRay.col = Colour(0,0,0);
    }
    else {
        curLight->light->shade(ray);
    }
    
     curLight = curLight->next;
                

}

}

Where traversescene goes through every object and does the intersection and puts the proper value. Maybe I didn't put this stuff in the proper area.

도움이 되었습니까?

해결책

You should have somewhere in the code a function which does the intersection, i.e. fill the proper values in Ray3D::intersection, right? After you create the shadowRay, you have to invoke that function to check if shadowRay intersects any object in the scene and that intersection is between the origin and the light position. If there is such intersection, then the current point is not lit by that light.

다른 팁

Where you have

// You'll want to call shadeRay recursively (with a different ray, 
// of course) here to implement reflection/refraction effects.  

you should have the position of the point the ray hit. You should build rays between this point and the light sources. If the rays intersect something (doesn't matter where) the point is in shadow, if not then it's lit. Once you have this information pass it to the compute shading to know if you apply the full pong model (or whatever you are using), if there was no intersection, or only the ambient color, if there was.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top