Hello, I'm working on a ray tracer in Java (but the problem I am having are the math kind, not the programming kind). In my scene (as seen in the first image), I have 3 spheres at:
s1, pos: 0 0 -10, and scale: 2 2 1
s2, pos: 4 4 -10, and scale: 2 2 1
s3, pos: -4 2 -10, and scale: 2 2 1
Then I have 3 lights at:
l1, pos: 0 -5 0
l2, pos: 10 5 0
l3, pos: -10 5 0
Then, we have the second image, where all I've done, is change the z-scale of the spheres to 2. That is each sphere's scale values are now: 2 2 2. And as you can see, their shading completely stops making sense.
I will shortly explain my methodology on what I did to get this scene.
- From a point at the origin of world, I send rays through a near plane at z = -1, where I have as many rays as the resolution I want.
- Then I take each of these rays (parametrized by t) and check if they intersect with any sphere currently in the scene.
2.1 Since position and scale change for each sphere are just affine transformations, I have a 4X4 forward matrix that handles that.
2.2 Intersection works by taking the ray and transforming it with inverse of previous affine matrix (ray's point by the whole thing while the direction vector with only the first 3X3 of it since translating direction makes no sense).
2.2.1 I take that transformed ray and plug it into the famous quadratic equation for finding intersection of ray with spheres and find the 't.'
2.3 Using that 't,' I find the point of intersection in world scale (by plugging it into untransformed ray).
2.4 Using that point, I find the normal of the sphere which is used for the calculating the Lambertian diffuse model.
2.4.1 I For normals, I am actually doing: take the global point, transform it back using the full 4X4 inverse matrix for that sphere, normalize, then multiply it with inverse transpose of 3X3 of the affine, and finally normalize again.
2.5 Then I find vector L for each light (just subtract light's position with world-scale intersection point)
2.6 I do the usual Lambert L.N * Intensity * Material Diffuse
Now, as you can see, most of it works fine. I can have my spheres in any position and it works. Even, x,y-scales are fine (I've tried deforming them), but the moment I introduce the z-scaling, everything goes out of whack. And I can't figure out what could be the underlying reason that could be causing this.
Now I am not expecting anyone to give me a full solution on how to do it, but I was hoping someone with knowledge can look at both the images and backward reason as to where I might be going wrong.
I am not sure where exactly in the pipeline could having a bad z-axis scale cause problems. So if anyone has any clues on where to start looking, that'd be great.
TL;DR: Diffuse shading doesn't work properly if I change the z-scaling of the sphere, whereas x,y-scaling and (x,y,z) position transforms always work.
Thank you very much for looking into this!
