Question

I am attempting to add features to a ray tracer in C++. Namely, I am trying to add texture mapping to the spheres. For simplicity, I am using an array to store the texture data. I obtained the texture data by using a hex editor and copying the correct byte values into an array in my code. This was just for my testing purposes. When the values of this array correspond to an image that is simply red, it appears to work close to what is expected except there is no shading. first image http://dl.dropbox.com/u/367232/Texture.jpg The bottom right of the image shows what a correct sphere should look like. This sphere's colour using one set colour, not a texture map.

Another problem is that when the texture map is of something other than just one colour pixels, it turns white. My test image is a picture of water, and when it maps, it shows only one ring of bluish pixels surrounding the white colour.

bmp http://dl.dropbox.com/u/367232/vPoolWater.bmp

When this is done, it simply appears as this: second image http://dl.dropbox.com/u/367232/texture2.jpg

Here are a few code snippets:

  Color getColor(const Object *object,const Ray *ray, float *t)
  {
   if (object->materialType == TEXTDIF || object->materialType == TEXTMATTE) {
    float distance = *t;
    Point pnt = ray->origin + ray->direction * distance;
    Point oc = object->center; 
    Vector ve = Point(oc.x,oc.y,oc.z+1) - oc;
    Normalize(&ve);
    Vector vn = Point(oc.x,oc.y+1,oc.z) - oc;
    Normalize(&vn);
    Vector vp = pnt - oc;
    Normalize(&vp);

    double phi = acos(-vn.dot(vp));

    float v = phi / M_PI;
    float u;

    float num1 = (float)acos(vp.dot(ve));
    float num = (num1 /(float) sin(phi));

    float theta = num /(float) (2 * M_PI);
    if (theta < 0 || theta == NAN) {theta = 0;}
    if (vn.cross(ve).dot(vp) > 0) {
        u = theta;
    }
    else {
        u = 1 - theta;
    }
    int x = (u * IMAGE_WIDTH) -1;
    int y = (v * IMAGE_WIDTH) -1;
    int p = (y * IMAGE_WIDTH + x)*3;

    return Color(TEXT_DATA[p+2],TEXT_DATA[p+1],TEXT_DATA[p]);

}
else {
    return object->color;
}
};

I call the colour code here in Trace:

if (object->materialType == MATTE)
    return getColor(object, ray, &t);

Ray shadowRay;
int isInShadow = 0;
shadowRay.origin.x = pHit.x + nHit.x * bias;
shadowRay.origin.y = pHit.y + nHit.y * bias;
shadowRay.origin.z = pHit.z + nHit.z * bias;
shadowRay.direction = light->object->center - pHit;
float len = shadowRay.direction.length();
Normalize(&shadowRay.direction);
float LdotN = shadowRay.direction.dot(nHit);
if (LdotN < 0)
    return 0;
Color lightColor = light->object->color;
for (int k = 0; k < numObjects; k++) {
    if (Intersect(objects[k], &shadowRay, &t) && !objects[k]->isLight) {
        if (objects[k]->materialType == GLASS)
            lightColor *= getColor(objects[k], &shadowRay, &t); // attenuate light color by glass color
        else
            isInShadow = 1;
        break;
    }
}
lightColor *= 1.f/(len*len);
return (isInShadow) ? 0 : getColor(object, &shadowRay, &t) * lightColor * LdotN;
}

I left out the rest of the code as to not bog down the post, but it can be seen here. Any help is greatly appreciated. The only portion not included in the code, is where I define the texture data, which as I said, is simply taken straight from a bitmap file of the above image.

Thanks.

Was it helpful?

Solution

It could be that the texture is just washed out because the light is so bright and so close. Notice how in the solid red case, there doesn't seem to be any gradation around the sphere. The red looks like it's saturated.

Your u,v mapping looks right, but there could be a mistake there. I'd add some assert statements to make sure u and v and really between 0 and 1 and that the p index into your TEXT_DATA array is also within range.

OTHER TIPS

If you're debugging your textures, you should use a constant material whose color is determined only by the texture and not the lights. That way you can make sure you are correctly mapping your texture to your primitive and filtering it properly before doing any lighting on it. Then you know that part isn't the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top