#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

  •  
    Attachments
  • 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
     
  • 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.