0

I implemented phong shading on my raytracer. Unfortunatelly I am receiving a segmentation fault when running it. The likely cause is related to the "specular_color" Vec3f variable (with is an object made of three floats). When I print its values, I receive:

specular_color: inf inf inf

To figure out the reason was not complicated:

It is calculated this way:

specular_color += light_intensity * std::pow (reflected*camera_dir,mat.ns);

where mat.ns is the specular exponent, that exhibits the expected values.

reflected*camera_dir is the cause, because it always end being a big value. In three of four of my test cases it is a five digit value. In the other is a six digit value (close to seven). So five or six digit values taken to any exponent that isn't fairly close to one is likely to overflow the float variables.

Now the questions is why these values are so big, if they can or cannot be that way. If they cannot, then likely there is a bug in previous code. If they can, all that is missing is to normalize the reflected vector (camera_dir is already unitary)

Reflected vector is calculated this way:

 Vec3f reflected = light_ray_dir - 2 * (light_ray_dir * hit_normal) * hit_normal;

where light_ray_dir is calculated as:

Vec3f light_ray_dir (current.pos - intersection);

With current being the name of the light_source and intersection being the point of encounter of the ray with the triangle.

It always worked fine when it did only diffuse light.

hit_normal, however, is new code and is calculated as:

Vec3f hit_normal = (1 - u - v) * vert1 + u * vert2 + v * vert3;

with u and v being the barycentric coordinates and vertX the triangle's vertices.

So what seems more likely? A more complex bug perhaps in the above code or just a missing normalization to the reflected vector. Or perhaps something else? Thanks for your time.

user2752471
  • 444
  • 1
  • 6
  • 14

1 Answers1

0

Yes, the phong reflection model uses normalised vectors to compute the intensity of the reflected light. Note the hats in the expression:

enter image description here

source: https://en.wikipedia.org/wiki/Phong_reflection_model

R denotes the reflection vector, L the light direction, and N the normal of the surface at the point being rendered, note also that you've transposed the two parts of the expression - this could be a problem if you expect both the light vector and reflection vector to point away from the surface, but depending on your model you might have computed this differently.

enter image description here

I had a look at your code and your light direction is away from the light, rather than away from the surface, so I guess the main thing to be mindful of is that your direction vectors might be pointing into or out of the surface, i.e with or against the normal. I don't think that would have caused the NaN though. I'd ensure that the camera direction is also normalised, and check everywhere for zero length vectors as these can blow out your normal calculations when you divide by zero.

I also had a bit of a look at your normal calculation. Did you mean to calculate the normal from the triangles vertices? Or did you mean the normal at each of the vertices?

Hope this helps

phillip voyle
  • 1,863
  • 2
  • 15
  • 18
  • Thanks for the answer. The code I used as base does this that way: https://www.scratchapixel.com/code.php?id=32&origin=/lessons/3d-basic-rendering/phong-shader-BRDF (lines 477 and 564). Could you develop the "this wouldn't matter if the directions were also reversed" ? About the normal, my idea is to use this code to simulate the normal at each point, to give it smooth shading instead a flat one. So I think "normal from the triangle vertices" ? – user2752471 Apr 08 '19 at 19:10
  • I went into this in a little more detail, direction of the vector is just something to be mindful of – phillip voyle Apr 12 '19 at 21:02