This article is a case study of a human eye model, and provides demonstration of more advanced Sequential Mode modeling techniques. We will create a model of the human eye in OpticStudio using the Liou & Brennan 1997 eye model. After successfully generating this eye model in OpticStudio, we will use it to design a free-form progressive eyeglass lens.
Authored By Mike Tocci
Accurate simulation and modeling of the human eye can be tricky; it is a subject that continually spurs new developments. In this study, we will create a model of the human eye in OpticStudio using the Liou & Brennan 1997 model shown in the book Optics of the Human Eye.1 This is a fairly comprehensive model of the eye. It accounts for many realistic factors that other models do not, such as an offset pupil, a curved retina surface, an inward-pointing eyeball, and a crystalline lens with two different gradient refractive index profiles for the front and back half.
After successfully generating this eye model in OpticStudio, we will use it to design a free-form progressive eyeglass lens.
We’ll begin by setting up the human eye model. You can use the attached file “Human_Eye_Model.ZMX” to skip typing in all the surfaces by hand. The file is available within a ZIP archive file in the "Sample Files" section of this article.
If you’re going to type the file in by hand instead of loading the attached file, you’ll want to first put OpticStudio into Sequential Mode, and then set the System...General...Units...Lens Units to “Millimeters”. Next you’ll want to set the Wavelengths (found in the System section) to “F, d, C (Visible)” as shown below:
Next, go to System Explorer...Aperture and set the Aperture Type to Float By Stop Size, and then go to System Explorer...Glass Catalogs and add the catalog MISC to your Glass Catalogs. From the Field Data Editor, just set just one Field, of Type Angle(Deg) with an X-Field value of 5:
Now insert 3 surfaces before the STOP and insert another 3 surfaces after the STOP. Below is a step-by-step guide to setting up all the surfaces, one at a time. Adjust each of the parameters as follows; any omitted parameters should be left at their default values.
|Surface 0 OBJ|
Surface 1 is just a dummy plane, and we use it to make our layout drawings easier to understand. Becuase we only need this surface to visualize the rays passing through it, we can hide it by navigating to its Object Properties...Draw, and then checking Do Not Draw This Surface.
|Material||Model: 1.376, 50.23|
To set the these Material parameters you will need to right-click the Glass cell, select “Model” as the Solve Type from the drop down list, and then type in the values.
Next, we will insert the interface between the cornea and the aqueous humor at Surface 3.
|Material||Model: 1.376, 50.23|
Surface 4 represents the system's aperture stop, and it is labeled "STO" in the Lens Data Editor. This is our eye model’s pupil plane.
|Material||Model: 1.376, 50.23|
In order to model the offset pupil location, we’ll need to decenter this surface. Open the Surface Properties and then click the Tilt/Decenter tab. Set this surface to have a Decenter X value of -0.5mm and then for After Surface select Reverse This Surface, as shown below.
We will now model the anterior (front) and posterior (rear) portions of our model’s crystalline lens.
Next, we will model the interface between the rear of the crystalline lens and the vitreous body of the eye.
|Material||Model: 1.336, 50.23|
Finally, we will model the eye's retina at Surface 8. This is labeled “IMA” in the Lens Data Editor and represents the image surface.
A quick check of the system’s 3D Layout (where First Surface is set to Surface 2, instead of the default Surface 0) shows that something is not quite right:
In the layout drawing, the top and bottom marginal rays are getting cut off by the pupil. This can’t be right, especially since we’ve chosen our system’s Aperture Type to be Float By Stop Size: the top and bottom marginal rays should, by definition, successfully pass though the pupil. Something is amiss with our pupil. When our pupil is suspect, we always check the Pupil Aberration Fan (this is an analysis tool that can be found under Analyze Tab...Aberrations...Pupil Aberration). Our system’s pupil aberration fan looks like this:
The pupil aberration fan is telling us that there is 40% pupil aberration in the negative X-direction. This is caused by the fact that OpticStudio is aiming rays at the (undecentered) paraxial entrance pupil. Remember that we decentered the pupil 0.5mm – which is 40% of the pupil semi-diameter – in the negative x-direction.
Luckily, OpticStudio has an easy fix for this problem: Ray Aiming. Go to System Explorer...Ray Aiming, and set Ray Aiming to Paraxial, as shown below:
Click the OK button and now we see that the Pupil Aberrations are eliminated:
And the 3D Layout shows the top and bottom marginal rays successfully passing through the decentered pupil:
This is the Liou & Brennan (1997) eye model. At this point, your Lens Data Editor should look like this:
Change the Settings on the 3D Layout so that Rotation Z = 90, and set it so that the First Surface is Surface 1 (input beam) and you’ll see the top-down view of the model, complete with offset pupil and off-axis field (I’ve added some annotations to the drawing below to label the various parts of the model):
To analyze this lens, let’s first look at the spot diagram. Open the Standard Spot Diagram from the Analyze Tab...Rays and Spots drop-down:
Next we’ll check the FFT MTF:
Note that I’ve chosen a Max Frequency setting of 100 lp/mm. This corresponds to a single-spot resolution of 5 um, which corresponds closely to the resolution required for 20/20 Snellen Visual Acuity. You can see that this model should produce a well-resolved image up to 100 lp/mm, and therefore is a good model of a 20/20 human eye.
Finally, in order to get a good feel for how well this “patient” can see, we’ll check the Diffraction Image Analysis. The diffraction image analysis feature is similar to the geometric image analysis feature, except the complex system Optical Transfer Function (OTF) is used to compute the image appearance. This method accounts for the finite pass band and other diffraction related effects real optical systems have on image formation.
For this, let’s set it up to image the letter “F” at a size that corresponds with 20/20 Snellen Acuity. Go to Analyze Ribbon...Extended Scene Analysis...Extended Diffraction Image Analysis, and then click Settings and set the values as shown below:
Here is the resulting Diffraction Image Analysis diagram:
At this point, with a good human eye model set up in OpticStudio, it’s possible to add external elements to the design. For example, if you have a measured cornea-shape map, you could replace the cornea surface with a “Grid Sag” surface and import the data into OpticStudio. Or if you had a specially-designed intraocular lens (IOL) to model, you could replace the two gradient surfaces with the IOL prescription.
In this example, we will be designing a Progressive Addition Lens (PAL) and we’ll start by adding an eyeglass lens to the front of our model. We’ll optimize this PAL to provide good imaging for near, mid-range, and far objects.
To ensure a realistic modeling of the eye’s movement as the “patient” moves her eye up and down, we will want to keep the eyeglass in place, and have the eye model rotate about its center. That is, we’ll have to place a Coordinate Break at the center of the eyeball, and then have the entire eye model rotate about this point. To do this, we’ll first place the eyeglass lens into the Lens Data Editor, and then we’ll move forward an appropriate amount of Thickness to get to the center of the eye. Then we’ll put in a Coordinate Break surface, and then we’ll move backwards to the desired location of the eye model’s first surface, the cornea. This might seem a little confusing at first, but it’s really quite simple, as you’ll see.
First, insert three surfaces between the Input Beam (Surface 1) and the Cornea (Surface 2). These three surfaces will represent the front and rear surfaces of the eyeglass lens, and a coordinate break to tilt the eye. You’ll notice that I’ve chosen to place the eyeglass lens 15mm from the eye.
We’re going to place the Coordinate Break surface at the center of the eyeball (which I estimate to be approximately 13mm from the front cornea surface). This way, the eye will rotate about its center, in a way that mimics the actual motion of a human eye. Below is a guide to setting up these three new surfaces.
You’ll see below that the thickness from the back of the eyeglass lens to the coordinate break (at the eyeball’s center) is 28mm (that’s 15mm from eyeglass to cornea plus 13mm from cornea to center of eyeball). Then, after the coordinate break, there is a thickness of negative 13mm, to get back to the cornea surface. Surfaces 2 and 3 represent the front and back of the eyeglass lens, respectively.
Surface 4 represents the Coordinate Break located at the center of the eyeball.
|Comment||center of eye|
Now let’s add a couple of new configurations. Open the Multi-Configuration Editor (MCE), and hit Ctrl-Shift-Insert twice, or press the Insert Configuration button in the MCE toolbar. We’ll need two extra Multi-Configuration Operands, so now hit Insert twice. There should now be nine empty cells in the MCE.
We’re going to make the first configuration represent the eye looking straight ahead through the lens, at an object located far away. The second Configuration will represent the eye looking slightly down through the lens, at a mid-range object. Finally, the third Configuration will represent the eye looking far down, at a very near object. Changing the object distance is handled with a THIC operand (changing the thickness of Surface 0) and changing the eye’s up-down angle is handled by changing the Tilt About X (which is Parameter 3) of Surface 4 (the Coordinate Break surface). Below is a table showing how the MCE should be filled in:
We’ve now got an eyeglass lens and an eyeball, and we’ve set the eyeball so that it rotates in a realistic manner. There’s one more minor step that will help make our layout plots easier to understand: we need to set the Global Coordinate Reference Surface to one that is before the Coordinate Break in the Lens Data Editor (LDE). The idea here is that after our Coordinate Break (surface 4) the rest of the surfaces in the LDE will be tilted some amount, relative to the surfaces before the Coordinate Break.
When we make layout plots, we would like to have the plots showing the eyeglass lens staying in place, while the eyeball rotates (instead of having the eyeball stay in place while the eyeglass moves around the eye). To ensure that this happens, we go to System Explorer...Aperture tab, and set the Global Coordinate Reference Surface to any surface before 4 (i.e. surface 1).
A quick check of the 3D Layout (with First Surface set to a value of 1; Rotation X, Rotation Y, and Rotation Z values set to 0; Configuration set to All; and Offset Y set to -50) shows that something is not quite right:
The problem is that as our eye model rotates down, it’s not really “looking” downward. This is because the Field value is remaining the same as the eye rotates, and what we want is for the Field to change so that the focused beam always hits the exact same part of the retina (this focal point on the retina is called the fovea centralis). So what we really want to keep constant is the image height, not the field angle. To do this, we’re going to change our Field Type from Angle(Deg) to Real Image Height.
To convert to Real Image Height field definition, we could check the chief ray landing coordinate and manually enter that value into the Field Data Editor. However, we can alternatively just use the Field Conversion tool. To do this, open the Field Data Editor from System Explorer...Fields...Open Field Data Editor, and navigate to the Field Type tab in the Field Properties. Then, select Real Image Height in the Convert To dropdown:
This converts our field type, so that it is defined in terms of real image height. We can round off these values if desired. With our Field Data set up this way, we will be guaranteed that irrespective of which configuration we choose, the chief ray will intercept the image surface (that is, the retina) at X = 1.462mm, Y = 0.0. This is a good simulation of the fact that no matter where the human eye rotates, the center of vision is always in the same exact spot on the retina (the fovea centralis).
Here is a 3D Layout plot showing the system from a side view for the 3 configurations (Far, Mid, and Near object distances):
The MTF curves and Diffraction Images for our system’s three configurations are shown below in order from Far to Near:
Note that because our model does not include accommodation by the crystalline lens (to adapt to the change from far to near object distances) the system shows very poor performance for mid-range and near objects, as we would expect in a presbyopic patient, for example.
We’re going to be optimizing the eyeglass lens to take on a free-form shape, in an attempt to provide accommodation to the eye as it rotates downward. Our next step is to set variables in the Lens Data Editor (LDE). The only things we’re interested in varying are the shapes of the front and back surfaces of the eyeglass lens.
In the LDE, set the Radius, Conic, and 2nd Order Term through 12th Order Term of Surface 2 (glasses-front) to variables – there should be eight parameters total for this surface that are now allowed to vary. We will also set the Max Term # of Surface 3 (glasses-back) to 40 and the Norm Radius of the same surface to 20.0. Finally, set all forty polynomial coefficient terms for Surface 3 to be variables.
Before we can optimize the shape of the eyeglass lens, we need to set up a Merit Function. In the Merit Function Editor (MFE), go to the Optimize Tab...Optimization Wizard. Set the Optimization Function and Reference values to “RMS,” “Wavefront,” and “Centroid.” Set the Pupil Integration Method to “Gaussian Quadrature” and choose 6 Rings and 12 Arms; we require high sampling because we expect the wavefront shape to be highly complex, based on the number of degrees of freedom in the PAL surface profile. Note that the Assume Axial Symmetry box will already be un-checked and we will leave it that way:
Click “OK” and OpticStudio will automatically generate a several hundred optimization operands for us.
Before we start optimizing, we just need to add a couple of edge thickness operands, to keep the edges of the eyeglass lens from becoming too thick or too thin. The eyeglass lens comprises an Extended Polynomial surface type, and so it is not going to remain rotationally symmetric during optimization. Therefore, we must use operands that check the edge thickness at multiple points around the lens. XNEG and XXEG are just such operands. We will add these operands to the merit function to ensure that the edge thickness of the eyeglass lens is between 1 and 8mm thick.
Insert two new operands at the beginning of the Merit Function. Below are the settings to use for these two new operands:
First new operand
Second new operand
At this point, all the hard work of the design is complete. The attached file, “Human_Eye_Model.ZMX,” represents all the above work to this point.
The one thing left to do is to optimize the design by opening the optimize tool, by going to the Optimize Ribbon...Optimize! and then clicking the Start button.
After some time, OpticStudio will finish optimizing and you’ll be left with an interesting, free-form, Progressive Addition Lens (PAL). In this demonstration, we’ve done several hours of further optimization with the Hammer Optimization tool:
Based on just this layout, we can tell that our sag profile is quite extreme. We could also look at a surface sag analysis to investigate further. Note that in this example, we let the optimizer run rampant a bit. In designing systems that will be built, we must make considerations of cost and sag profile that were not made here. It is always good practice to carefully consider and select the variables which are exposed to the optimizer. In this example, we simply fed all 40 of the PAL’s polynomial terms as variables, but really we should determine which will be important factors by either:
- Using some basic considerations. For example, think about whether you will need X/Y symmetric terms or not, and choose which terms to set as variables based on this.
- Testing which variables “work”. A common technique is to feed the optimizer one variable at a time, and check if the variable helps or not. If the optimizer can’t find a much better solution using this variable, then it is probably reasonable to exclude it. Set it back to 0 and keep it fixed, and move on to the next one.
Proper choice of variables ensures that the final design is actually realistic and manufacturable, not overly expensive, and also greatly improves optimization performance. In this case, though, we will simply carry on, assuming that this system is manufacturable and meets our physical design specifications.
We can see that the optimizer has found a very nice solution for all three configurations. We can check our performance across all three configurations with our analysis tools. Note that this time, our system is diffraction limited in all three configurations (the RMS spot size is smaller than the Airy Radius), so we will check the Diffraction Limited option in the Extended Diffraction Image Analysis settings. The MTF curves and Diffraction Images for our newly-optimized system’s three configurations are shown below in order from Far to Near:
1. Atchison, D. A., & Smith, G. (2006). Optics of the human eye. Oxford: Butterworth-Heinemann.