This is easy but usually tricky to get the hang of at first

EVERY VECTOR HERE IS A UNIT VECTOR EVEN IF IT DOESN’T APPEAR SO IN THE DIAGRAMS

If you have an incident vector hitting a surface (that has a normal defined for it!), then you can calc the angle of the reflected vector like so:

EVERY VECTOR HERE IS A UNIT VECTOR EVEN IF IT DOESN’T APPEAR SO IN THE DIAGRAMS

reflected = incident – 2 × (normal ⋅ incident) normal

WHY?

EVERY VECTOR HERE IS A UNIT VECTOR EVEN IF IT DOESN’T APPEAR SO IN THE DIAGRAMS

All you’ve gots to do is look at the angle the incident makes with the normal. That’s what the formula I gave says anyway.

But also consider this. If the incident is perpendicular to the normal, then the reflected angle has pretty much no change from the incident angle. IE AT the case where the incident vector has an angle of 90 degrees with the normal of the surface, the “reflected” vector (if you can call it that!) is in the same direction as the “incident” vector. That is because the dot product (normal ⋅ incident) goes to 0 when the angle between incident and normal is 90 degrees, so:

reflected = incident – 2 × (normal ⋅ incident) normal
reflected = incident – 2 × (0) normal
reflected = incident

So that’s interesting. Now consider the other case where the angle between the normal and incident is 180 degrees (ie the ray hits the surface head-on):

EVERY VECTOR HERE IS A UNIT VECTOR EVEN IF IT DOESN’T APPEAR SO IN THE DIAGRAMS

reflected = incident – 2 × (normal ⋅ incident) normal
reflected = incident – 2 × (-1) normal
reflected = incident + 2 × normal

IE reflected turns completely around.

For everything else in between, there’s cosine.

So there is LESS change in the direction of the reflected angle as the incident-normal angle grows. This is encoded by the dot product/cosine in the normal reflection.

Ok, here’s the math for it.

Using this diagram:

EVERY VECTOR HERE IS A UNIT VECTOR EVEN IF IT DOESN’T APPEAR SO IN THE DIAGRAMS

The angle THETA there is going to be the cosine of the NORMAL and the INCIDENT

The SMALLER ANGLE GAMMA is going to be (THETA – 90) because the normal is at an angle of 90 degrees with the surface. That’s why its a normal, duh!

Now then some simple vector math will give you:

The length of the pink side X (perp distance to surface from INCIDENT vector:)

X = sin( GAMMA ) (remember incident is a unit vector)

So, now

REFLECTED = INCIDENT + 2 (sin (GAMMA)) ( NORMAL )

This makes sense because WHEN (sin(GAMMA)) is small, (angle between INCIDENT and NORMAL == nearly 90 degrees) we don’t need to add a large “displacement” in the direction of the normal to get the reflected vector (we add 0 x normal in the extreme case of a 90 degree INCIDENT angle with NORMAL). As the angle between NORMAL and INCIDENT INcreases, so does the displacement we need to use to the reflected vector, until we get to the other extreme case where the REFLECTED = INCIDENT + 2 * NORMAL.

Ok then, simplify.

REFLECTED = INCIDENT + 2 (sin (GAMMA)) ( NORMAL )
REFLECTED = INCIDENT + 2 (sin (THETA – 90)) (NORMAL)
REFLECTED = INCIDENT + 2 (sin (THETA)cos(90) – sin(90)cos(THETA)) (NORMAL)

cos(90)=0, sin(90)=1

REFLECTED = INCIDENT + 2 (-cos(THETA)) (NORMAL)

cos(THETA) = INCIDENT ⋅ NORMAL

REFLECTED = INCIDENT – 2 ( INCIDENT ⋅ NORMAL ) (NORMAL)

And there you have it.