Dealing with Non-normal Incidence
In the previous post we developed the TMM for the special case of light incident in a direction perpendicular onto a multilayer coating. And as developed in the post before that, our treatment of the reflection and transmission coefficients required nothing more complicated than some commonsense assumptions about the behavior of the electric field and its spatial slope at a boundary between different materials. These coefficients were incorporated into the TMM.
If we want to deal with the more complicated scenario in which light falls at some oblique angle onto the surface defined by the coating(s), we will need to be more mindful of the details of electromagnetism. The good news is that we can still use the same TMM approach, and that we only need to modify the field reflection and transmission coefficients that comprise the elements of the interface matrix, plus account for the oblique wave motion through the layers so as to modify to the propagation matrix. The new terms for the interface matrix come from the well-known Fresnel relations, which are derived from a careful analysis of the boundary conditions on the electric (“E“) and magnetic (“B“) fields which comprise the light, as well as the relationship of the E and B field amplitudes. All of these constraints come from Maxwell’s equations, the four fundamental rules that govern classical electromagnetism. (Any undergraduate, calculus-based text on general physics will serve as an appropriate reference, if needed.)
Our first task, then, is to derive the new matrix elements, and incorporate them into the existing TMM approach. After that, we will apply our tools to the case of off-axis light falling on a coated lens. This will allow us to determine the field of view over which the coating will perform adequately, and explain why obliquely reflected light from an anti-reflection coating typically has a colored appearance.
The Fresnel Relations
In keeping with the previous analyses, we consider light incident from the left that is reflected and transmitted at a boundary. Because there is now a non-zero angle of incidence, however, the situation is a bit more involved, and we need to be clear with the nomenclature for the geometry. We must keep in mind that light consists of paired oscillations in the electric and magnetic field, each of which is perpendicular to the propagation direction, which we capture by specifying the vector k. This is to say that the vectors E, B, and k are each at 90 degrees to the other two, and they satisfy the right-hand rule, such that if your finger start by pointing along the E direction, then curl in towards B, your thumb will indicate the k direction.
In Figure 1 (a) we begin with the coordinate system and directional definitions. The directions of light are indicated by the arrows, with material “1” on the left and material “2” on the right. Incident light (blue) is reflected (red) and transmitted (green).

In diagram (b) we show the case of “s” polarization, in which the magnetic field B lies in the plane of propagation (that is, in the y-z plane). In that case the electric field E must lie in the x-z plane. In diagram (c) we show the “p” polarization scenario, where the electric field is now in the plane of propagation instead. These two cases must be treated independently and will result in different expressions for the reflection and transmission coefficients. Note that in both cases the incident and reflected angles will be the same, while the transmitted and incident angles will be related by Snell’s law. That is:
![]()
![]()
We will once again assume that the incident light has an electric field strength of 1.0, and that the reflected and transmitted amplitudes are given by r and t, respectively. Our goal is to find expressions for these coefficients that depend on the refractive indices and angles. We’ll start with the s-polarization case first. The boundary conditions for the fields here are quite simple: all of the components of B and E must be continuous. This comes from simply enforcing Maxwell’s equations at the boundary, and we are assuming that the materials are simple dielectrics with no difference in magnetic properties. We can therefore write for the electric field:
![]()
or
![]()
As for the y-component of the magnetic field, we can see from the diagram that
![]()
For an electromagnetic wave we must have
, so this can be written as
![]()
But since
we can eliminate t and solve for r, which gives, for this case of s-polarization:
![]()
And then the expression for t is immediately found to be:
![]()
For the case of p-polarization we take the same approach, but we now have:
![]()
And because
this is
![]()
All we did was enforce that the magnetic field be continuous across the boundary, as must be the y-component of electric field, so we have:
![]()
Or
![]()
It is trivial to solve for the coefficients as we did above, giving:
![]()
And
![]()
These expressions for the four coefficients are the famous Fresnel relations, which look similar but have important differences in the “mixing” of the indices and angle terms. All we needed to derive them was a clear accounting of the geometry, the requirement that all components of both fields that were in the plane of the boundary (that is, within the x-y plane) be continuous, and the relationship between the E and B field strengths for electromagnetic waves, namely,
. This important result, as well as the continuity of the fields in the x-y plane, are direct consequences of Maxwell’s equations and are treated in any text on electromagnetism.
Modifying the TMM
Let’s now see how we must modify the interface matrix which relates the electric fields on either side of a boundary. We worked this out in the previous post and we saw that the general relationship between fields on either side are related according to
![]()
This is a universal expression that captures the connection between fields and does not need to be modified beyond simply using the new expressions for r and t that we developed above. Obviously we’ll need to run through the TMM analysis twice if we want to do both s- and p-polarization cases.
With the propagation matrix we need to carefully reconsider the geometry because the light is no longer simply moving to the left or the right, along the z-direction, but will have a y-component as well. The situation is shown in Figure 2.

For the waves moving to the right, the field will vary throughout this space according to
![]()
The only difference between fields separated by a horizontal distance d is then:
![]()
While in the reverse direction
![]()
So the propagation matrix looks identical to the previous version, with the exception of the factor of the cosine:
![]()
We should keep in mind that in this expression, k depends upon the index for this region, according to
when referring to the wavelength in air (that is, essentially in a vacuum).
Note that within a given layer, which is what we are dealing with for the propagation matrix, all angles must be the same. As long as we have the case where the light comes initially from one side, the air side, at a particular incidence angle, then all the subsequent angles within a given layer only depends upon working out Snell’s law for the entire structure, which is very straightforward to do, and which will be the first step that we take in the code-based analysis of the situation. The Python code for working through the TMM is included below.
The Effect of Incidence Angle on Reflection from a Multilayer Coating
Now we can apply our modified TMM to a coated lens and look at how the reflected light will be affected as the angle of incidence grows. We will begin by sanity checking the results of our code (see below) by comparing them to published results. In this case, we will replicate Figure 4.38 on page 130 of Macleod [1], which show the reflectance versus wavelength for a three-layer coating over a range of incidence angles. Because we wish to consider the case of unpolarized light, we need merely take the average of the reflectances for the two polarization cases. The results are shown in Figure 3, which accurately reproduce the Macleod results. Here, each curve corresponds to a different angle, which is noted in degrees. The details for the indices and thicknesses can be found in the code below, which generates the curve for 50 degrees.

What should jump out at us immediately is that the generally flat response at 0 degrees does not change appreciably even out to angles of 20 degrees. This is very fortuitous indeed, when we consider that for coatings to be practical with our optical instruments, they must perform well over a range of incidence angles corresponding to the field of view. For binoculars and scopes, the incoming range of angles that will deliver light to the viewer will typically not exceed 9 degrees, and may be less, so even this simple coating recipe is fairly robust for this range of operation. Some camera lenses, of course, have much wider fields of view and will require more sophisticated coatings.
The next thing to note is that the reflection of light that impinges at a large angle, such as 50 degrees, gets a significantly altered spectral response. In this case, longer wavelengths are reflected more strongly, and so viewing the surface of a lens coated in this way will result in the light taking on a more reddish cast as the angle is increased. This has no practical effect on its use as an objective coating on a binocular, for example, as the corresponding bluish light that is transmitted is at too high of an angle to reach the viewer. On occasion, binocular owners will find that their objective lenses show different tints when reflecting oblique light, indicating that the manufacturer used different recipes or designs for the lenses, but this has no effect on the transmitted light or the images formed.
Python Code for TMM under Oblique Incidence
# TMM for 9-layers - MJ Hurben Dec 2024 Oblique Incidence
import numpy as np
import matplotlib.pyplot as plt
d2r = np.pi / 180 # Degrees to radians factor
na=1 #Index of air
ng=1.51 # Index of glass
ang=50 # Angle if incidence relative to normal, in degrees
# n-Matrix: If less than 9 layers, use na for index of 'missing' layers
# d-Matrix values are in nm; initial air layers are arbitrary, final glass layer arbitrary
n=np.array([na,na,na,na,na,na,1.38,2.2,1.7,ng])
d=np.array([1,1,1,1,1,1,90.6,113.6,73.5,1000])
def PS(nva,dva,wl): # Phase Shift calculation
def M(nA,nB,mode,ang): # Transfer matrix for interface
aRad=ang*d2r
g=1-nA**2*np.sin(aRad)**2/nB**2
if nA*np.sin(aRad)<nB:
cosT=np.sqrt(g)
else:
cosT=complex(0,np.sqrt(-g))
if mode<1: # S-Pol
r=(nA*np.cos(aRad)-nB*cosT)/(nA*np.cos(aRad)+nB*cosT)
t=1+r
else: # P-Pol
r=(nB*np.cos(aRad)-nA*cosT)/(nB*np.cos(aRad)+nA*cosT)
t=nA*(1+r)/nB
d=1/t
offd=r/t
m=np.array([[d,offd],[offd,d]])
return m
def P(L,n): # Transfer matrix for propagation
L=L*n*2*np.pi
v=complex(np.cos(L),-np.sin(L))
p=np.array([[v,0],[0,v.conjugate()]])
return p
angles = [ang]
next_angle = np.arcsin(na * np.sin(ang * d2r) / nva[0]) / d2r # Snell's law
angles.append(next_angle)
for i in range(0,len(nva)-1):
next_angle = np.arcsin(nva[i] * np.sin(angles[-1] * d2r) / nva[i+1]) / d2r
angles.append(next_angle)
angles = np.array(angles)
L = dva * np.cos(angles[1:]*d2r)
for md in range(0,2):
W=M(nva[8],nva[9],md,angles[9]) # Interface of last layer and glass
for i in range(8,-1,-1):
W=np.matmul(P(L[i]/wl,nva[i]),W)
if i>0:
W=np.matmul(M(nva[i-1],nva[i],md,angles[i]),W)
else:
W=np.matmul(M(na,nva[0],md,ang),W) # Interface of glass and first layer
if md==0:
rs=W[1,0]/W[0,0]
else:
rp=W[1,0]/W[0,0]
return rs,rp
wls=[] # Array of wavelengths
Rs=[] # Array of Rs values
Rp=[] # Array of Rs values
Ra=[] # Array of average R values
for wl in range(300,801,10):
rs,rp=PS(n,d,wl)
wls.append(wl)
Rs.append(abs(rs)**2)
Rp.append(abs(rp)**2)
Ra.append(0.5*(abs(rs)**2+abs(rp)**2))
plt.grid(True)
plt.plot(wls,Ra,color='orange')
plt.xlim(350, 800)
plt.ylim(0.0,0.1)
plt.xlabel('Wavelength (nm)')
plt.ylabel('Reflectance R')
1 Macleod, H.A. (2021) “Thin-Film Optical Filters: Fifth Edition (Series in Optics and Optoelectronics),” 5th Edition, CRC Press.
Image credit: Виктор DARTVENOM Горелов, CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0, via Wikimedia Commons
