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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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.
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.
also, I think it is better to compare det with some epsilon instead of 0 because of dividing by det in further code.