1
votes

I'm working on a ray tracer for spheres and I'm trying to implement an illuminate function to calculate the light intensity per ray. I'm currently stuck on calculating the diffuse reflection:

Given a ray R, a sphere S, a point P where R intersects S, and a light source L

I understand that to use Lambert's Law to calculate diffuse reflection, I need the light direction vector and the normal vector.

I know I can get the light direction vector by calculating L - P. I'm stuck now on calculating the normal.

I know I need to use the inverse of the S transform matrix but I don't understand conceptually what inverting the S transform matrix does so I was hoping to get some guidance on how to do this.

1
I think its light direction = normalized(L - P) and the normal = normalize(P - center of S); - WacławJasper
P - center of S is the surface normal at P. The light direction is L's position - P. What source are you learning from? - molbdnilo
could you please explains what this `S transform matrix" is for you ? - Guiroux
@Guiroux it would be the translate * scale matrix to position the sphere in 3d space - Chang Liu
@WacławJasper thank you, sorry I wrote the equations wrong. I looked at some code to do this and noticed that some people took the scale transform matrix and transposed it and then inverted it. And then they multiplied (invertedScale * invertedScale * normal) to get the normal vector. Do you know why that is? Especially the double multiplication. - Chang Liu

1 Answers

2
votes

As stated in the answer to your other question, using the inverse of the sphere matrix will move things transformed by it into sphere space(where the sphere is at origin[0,0,0]).

To calculate the normal you transform your light position into sphere space using S⁻¹, if you're not using anisotropic scalings you can just normalize your transformed light position to get the normal:

transform light position by inverted scaling matrix

normalize transformed light position

otherwise you'll need to transform transformed light position using the inverted scaling matrix.

I noticed that some people took the normal calculated from P - center of S

It depends on what data and in what space that data is stored. This way assumes the primitives data is available in world space, so a sphere is defined by its center and its radius. From your previous question I assumed you only have a transform matrix describing your sphere.

and multiplied it by the inverse of the sphere's scale matrix squared like so: normalize(inv(S.scale) * inv(S.scale) * (P - center of S)).

Squaring the inverse makes the scaling agnostic to its sign, e.g. when the sphere is scaled uniformly by -1 the calculated normal will be the same as if no scaling was applied. When not squaring the scaling matrix a negative scaling would result in the normal pointing in the opposite direction and (under proper lighting conditions) resemble the inner surface of the sphere(-shell).