Menu

#109 1 sided triangle polygon doesn't cast raytraced shadows.

open-invalid
nobody
None
5
2009-06-24
2009-06-19
No

Using simple triangle polygon and turning Sides to 1 - raytraced shadow is dissapear!

See example rib attached. If set Sides 2 - shadow is Ok.

Discussion

  • Sergey Kolesnichenko

     
  • Okan Arikan

    Okan Arikan - 2009-06-24

    Hi Sergey,

    I don't this is a bug. When sides = 1, the triangle will only be visible from front. The triangle is facing the camera, so it is visible to the camera. But the light source is hitting the triangle from behind so it is not visible to the light for shadows.

    Does this make sense?

    Okan

     
  • Okan Arikan

    Okan Arikan - 2009-06-24
    • status: open --> open-invalid
     
  • Sergey Kolesnichenko

    But - adding 1 point to polygon it's became quad - and shadow appear. By the way - In this small example how to get opposite result when object not visible to camera but do shadow? Changing the order of polygon points as I tried change nothing...
    We use scenes that all consist of triangulated polygons, even cubes and spheres and no shadows when sides 1.

     
  • Dmitry Yunchik

    Dmitry Yunchik - 2009-06-25

    Dear Okan,

    I think there is a bug anyway. If you add another reversed triangle in attached *.rib you still do not get any shadows!
    The same example works ok in Aqsis renderer.

    I briefly looked at the source code of CPolygonTriangle::intersect(CShadingContext *context,CRay *cRay) method. Triangle intersection code for one-sided triangle looks very strange when det<=0 and ((attributes->flags & ATTRIBUTES_FLAGS_INSIDE) ^ xform->flip)==false.

    Indeed, lets look at the code with my comments closer:

    ........................................................
    } else {

    if ((attributes->flags & ATTRIBUTES_FLAGS_INSIDE) ^ xform->flip) {
    if (det < 0) return;
    } else {
    if (det > 0) return; //dyunchik: if we get det<=0 continue to test
    }

    subvv(tvec, cRay->from, vert0);

    const float u = dotvv(tvec, pvec);
    if (u < 0.0 || u > det) return; //dyunchik: but we will never pass further for det<0 !!! this makes cases with det<0 pointless

    crossvv(qvec, tvec, edge1);

    const float v = dotvv(cRay->dir, qvec);
    if (v < 0.0 || u + v > det) return;

    const float t = dotvv(edge2, qvec);
    const float inv_det = 1.0f / det;
    if ((t > cRay->tmin) && (t < cRay->t)) {
    cRay->object = this;
    cRay->t = t*inv_det;
    cRay->u = (u + v)*inv_det;
    cRay->v = u / (u + v);
    if ((attributes->flags & ATTRIBUTES_FLAGS_INSIDE) ^ xform->flip) crossvv(cRay->N,edge2,edge1);
    else crossvv(cRay->N,edge1,edge2);
    }
    }
    ...........................................................

    So, I think the code works correctly for ((attributes->flags & ATTRIBUTES_FLAGS_INSIDE) ^ xform->flip)==true case only.

     
  • Dmitry Yunchik

    Dmitry Yunchik - 2009-06-25

    also, I think it is better to compare det with some epsilon instead of 0 because of dividing by det in further code.

     

Log in to post a comment.