Ray reflection artifacts and transparency

I was working on a raytracing algorithm for a class and ran into some weird problem.

img

This is the main scene I'm working on. Nothing serious, everything is in order. Now my code is organized like this:

Image* Tracer::render()
{
    int w = _scr.width();
    int h = _scr.height();
    Image* im = new Image(w, h);
    int i, j;
    for(i = 0; i < h; i++)
    {
        for(j = 0; j < w; j++)
        {
            im->setColour(i, j, render(i, j));
        }
    }
    return im;
}

I call this function to generate an image. To color each pixel:

Vec Tracer::render(int i, int j)
{
    Vec pxlcol(0,0,0);
    Vec p(0,0,0);
    int obj;
    Vec dir = _scr.point(i,j);
    dir = dir - _obs;
    obj = intercept(_obs, dir, p);
    if(obj != -1)
    {
        pxlcol = objCol(_obs, p, obj, _ref);
    }
    return pxlcol;
}

Where int Tracer :: intercept (Vec o, Vec d, Vec & p) is the next function

int Tracer::intercept(Vec o, Vec d, Vec& p)
{
    int obj, k;
    Vec temp = o;
    Vec ptry = o;
    obj = -1;
    for(k = 0; k < _nobj; k++)
    {
        temp = _obj[k]->intercept(o, d);
        if( !(temp == o) && (((temp - o).mod() < (ptry - o).mod()) || (ptry == o)))
        {
            ptry = temp;
            obj = k;
        }
    }
    p = ptry;
    return obj;
}

which finds the index k of the object that is intercepted by the ray d , starting from o , and also returns the point p where such interception occurs, and Vec Tracer :: objCol (Vec o, Vec p, int obj, int r) is a function

Vec Tracer::objCol(Vec o, Vec p, int obj, int r)
{
    Vec colour(0,0,0);
    Vec point(0,0,0), reflected(0,0,0);
    unit ref = _obj[obj]->ref(p);
    if((1 - ref) > 0)
        point = pointCol(o, p, obj);
    if(ref > 0 && r > 0)
        reflected = refCol(o, p, _obj[obj]->normal(o, p), r - 1);
    colour = (point*(1 - ref)) + (reflected*ref);
    return colour;
}

, p o, , obj r.

() , :

img

, . , () , :

img

( , , ). , :

img

! , , , .

:

Vec Tracer::pointCol(Vec o, Vec p, int obj)
{
    Vec pcol(0,0,0);
    Vec inten(0,0,0);
    unit cos = 0;
    Vec c(0,0,0);
    Vec normal = _obj[obj]->normal(o, p);
    Vec inter = o;
    Vec objcol = _obj[obj]->colour(p);
    bool block = false;
    if(_amb == 1)
        return objcol;
    int l = 0;
    int k = 0;
    for(l = 0; l < _nlight; l++)
    {
        c = _li[l]->getPos() - p;
        block = false;
        if(c*normal > 0)
        {
            for(k = 0; k < _nobj; k++)
            {
                if(k != obj)
                {
                    inter = _obj[k]->intercept(p, c);
                    inter = inter - p;
                    if(!(inter.null()) && (inter.mod() < c.mod()))
                    {
                        block = true;
                        k = _nobj;
                    }
                }
            }

            if(!block)
            {
                cos = (c*normal)/(c.mod()*normal.mod());
                inten = inten + _li[l]->getInt()*cos;
            }
        }
    }

    inten = inten.div(_totalinten);
    pcol = objcol*_amb + objcol.multi(inten)*(1 - _amb);
    return pcol;
}

_amb , .

Vec Vec:: div (Vec v) (, (a, b, c).div((x, y, z)) = (a/x, b/y, c/z)). Vec Vec:: multi (Vec v) .

Vec Tracer::refCol(Vec o, Vec p, Vec n, int r)
{
    Vec rcol(0,0,0);
    Vec i = p - o;
    Vec refl(0,0,0);
    int obj = 0;
    Vec point(0,0,0);
    i.normalise();
    refl = reflected(i, n);
    obj = intercept(p, refl, point);
    if(obj != -1)
    {
        rcol = objCol(p, point, obj, r);
    }
    return rcol;
}

objCol refCol r-1, _ref.

, ?

+3
1

, , :

, z-fight/floating point - , " t , .

, , , , , , ( ) - , , () - () , .

+3

All Articles