3
$\begingroup$

situation:

I've implemented a Whitted style ray tracing in C. Everything appear to works except the shadow cast by small object on big far objects

The problem :

red sphere have radius 0.5 orange sphere have radius 200 example zooming: enter image description here more: enter image description here increasing the distance and the radius of the orange sphere: enter image description here

Question:

So fare, I could only suspect rounding error due to the fact that I use float. In "normal" situation, the shadows work great. Have you already encounter that kind of error ? Is my guess correct, or could that be something else ?

Not sure the code could help because messy, but there it is:

static inline uint8_t diffuse(const struct s_bvh *bvh, const t_lght *lght, const t_hinfo *hi, t_vec3f diff) { t_vec3f light; struct s_hit h; float dp; float length; //make the [hit_pts -> light_pts] vector sub_(lght->pts, hi->r->o, hi->r->d); length = norm(hi->r->d); //minimum to avoid self intersection h.min = 0.001f; //maximum h.t = length; normalize(hi->r->d); dp = dotp(hi->n, hi->r->d); if (dp > 0.0f) { //invertion fo the ray_direction and traverse the BVH tree invert_(hi->r->d, hi->r->inv_d); traverser(bvh, hi->r, &h, 1); //if in shadow, return (0) if (h.t < length) return (0); // else apply the light s_scale(lght->color, dp, light); add_(light, diff, diff); return (1); } return (0); } void diffusel(const struct s_bvhl *s, const t_hinfo *hi, t_vec3f color) { t_vec3f ambi; t_vec3f diff; uint32_t i; i = 0; mult_(s->lghts.amb, color, ambi); set_vector(diff, 0.f, 0.f, 0.f); //for each light while (i < s->lghts.count) { diffuse(&s->bvh, s->lghts.lghts + i, hi, diff); ++i; } mult_(color, diff, color); add_(ambi, color, color); } 
$\endgroup$
4
  • 1
    $\begingroup$ I suspect you have "surface/shadow acne". Typically you may need to add an "epsilon" offset to the starting position of secondary rays. $\endgroup$ Commented Jul 1, 2021 at 8:22
  • 1
    $\begingroup$ Thank you for your reply Simon F, I think that if it was shadow acne the bug/artifact will be spread on all the shadow surface. For prevent self intersection my implementation use a min value (epsilon) so that any intersection find under that min is discarded. Anyway, I add an epsilon vector to the start of the shadow ray, as you propose. Unfortunately nothing change. Many thanks for your time, I really think now that the "bug" is the result of rounding error, so there is nothing I can do about it with my current knowledge. $\endgroup$ Commented Jul 1, 2021 at 16:09
  • 1
    $\begingroup$ Floating point rounding error at the size and distance you are talking about is less then 0.0001. I checked. If that much quantization is building to cause a visible error, then there is a bug in the code that is amplifying it, either way this is a coding bug. (reposted original copy pasted wrong value) $\endgroup$ Commented Jul 2, 2021 at 10:50
  • $\begingroup$ Interesting answer pmw1234 The problem scale with the distance / radius difference between the two objects. Need to precise that I use a BVH tree and for that I invert the ray direction in the intent to speed up the search (inv_d = {1/r.x, 1/r.y, 1/r.z}). I was thinking that the main source of error could come from floating error in that process. Anyway I will review my code hoping that the flaw come, as you stated, from it. Thank you for your concern <3 $\endgroup$ Commented Jul 6, 2021 at 11:25

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.