Visual Acuity, Final Post

Description:

The final outcome of this semester is the Landolt C Visual Acuity VR application, or Landolt VR.  This application allows a user to run the Landolt C visual acuity test in three configurations across all devices compatible with Unity’s mixed VR plugin. The goal of which is to better measure both individual visual acuity in a single device, and visual quality output by different devices.

The three configurations are a fixed head perspective standard 70 trial test, a free head perspective standard 70 trial test, and a custom test that can be run in either head position. The custom test allows the user to change the start distance of the C object, the number of trials before the test completes, and the linear movement distance.

The procedure is best explained in the context of the 70 trial standard test. When this option is selected, the subject will be asked to decide the direction the C object faces 5 times per 14 different distances, with the C distance increasing each time. Between each guess, there is a brief rest period where a blank screen is displayed. Upon completion of the test, a Snellen Letter score will be displayed on the screen, and the user can exit the test to the main screen. Also upon completion a log file is created that contains all information pertinent to the test, and includes a record of each individual trial.

Creating this project took several weeks of research prior to the start of coding. In those weeks I learned the founding principles of visual acuity testing, the standard optometry procedures for issuing a visual acuity test, analysis of visual acuity testing results, and finally, how to construct and validate new visual acuity tests using standard symbols. I also had to learn some basic physiology of the eye to familiarize myself with vocabulary ahead of conducting other research.

Project Feelings:

I’m quite happy with the results of this semester. Having been a relative novice in terms of developing VR applications, it was satisfying alone to create a fully functioning project on my own. On top of that, I was challenged to learn material outside of my field, and bring results from research into a new medium. While there was plenty of content regarding visual acuity testing, and the basics of optometry practice, there was little to nothing about administering such a test on screen, let alone in VR. While I initially found that frustrating, it became something I found enjoyment in, working on something that perhaps no one has done before.

This is only my second time developing a VR application, and the first time it’s been non-game related. I found that I was able to create something functional, and relatively easy / aesthetically pleasing to use. Unity is a complicated but rewarding tool to learn, after this semester I feel much more confident in my development skills using it. The final product, combined with the improvement of my research and Unity skills was, and is satisfying.

Project Challenges:

The biggest hurdle was the lack of information out there with any relation to what I was attempting to build. I had a good idea of what I was trying to accomplish fairly quickly, but without anything to reference I was pushed outside the comfort zone of feeling what I was doing was correct. I still wanted to produce something accurate, that performed as close to a standard as I could get. It took some realizing that things like these are never done perfectly the first time, and validation comes from experimentation in the case of doing something new.

The next considerable challenge was threading. It took a good few weeks to figure out how to time things for the periods of rest and the periods of trial. While the co-routine / invoke functions unity provides work perfectly fine, my lack of Unity knowledge pushed me towards my C# comfort zone. As someone who uses C# for .NET web development, I foolishly thought Unity would play nice with C# timers, and even went so far as trying to write my own multi threading setup using them. Guidance ultimately put me back on the right track. Asking for help is never bad.

More time:

Given more time I would have loved to see this through testing. I feel like this is something useful, and would have preferred to run more trials on people that I don’t know so well. Not only to verify the process, but to improve the design of the application.

The next thing I would’ve liked to focus on is design. While it’s pleasant enough to look at, I would’ve liked more time to learn more about certain alignment techniques for Unity UI’s. I think that would be a small improvement that could make this product better.

It would’ve also been nice to run this past an Optometrist. While I was confident enough in my own research regarding the basic principles, I’m sure there are inaccuracies in my procedure that someone with more experience could help iron out.

 

Visual Acuity, Week 7

Progress:

The application is done and ready for testing. I’ve run it on myself and a few friends thus far with consistent enough results to merit further tests. I’ve finished the UI finally, and the rest of the code needed to make the different components communicate. A user is now able to transition between tests, and return to the start screen / abort tests as desired.

While the application will calculate a Snellen letter score, and it seems to put out something close to physical tests, I’m not sure I’m sizing the letters right (which for me means adjusting the distance the C object moves each time).

Struggles:

The actual letter size still alludes me. Mostly because all of the information out there on sizing Snellen letters for a LogMAR test pertains to physical tests, where the actual size of the letter is first measured, then scaled to append 5 minutes of arc at different test distances.

Next Week

  • Talk with Alex and/or Kevin about further testing
  • Go over design, come up with features for custom tests
  • Try on other HMDs (not vive)

Visual Acuity, Week 6

Progress:

Per the suggestion of Kevin, I transitioned the way the timed test works to use the Invoke Repeating method. This method solved all my problems with multi-threading in Unity. The test itself will now run through the trials, displaying the C at different positions for X amount of time before recording a failure. There is a period of rest, where there is no C displayed, which I handle by placing a black plane in front of the C display. Using a simple transform it appears and disappears. The test will end when the participant either completes 5 trials at each of the 14 distances, or when the participant fails 4 or more trials on a given distance (as was done in Paisan).

I’ve also started fleshing out the UI more. The main menu scene is currently under construction, and I’m working on displays for the test results once the trial is complete.

Struggles:

Now my that my multi-threading woes are over, I’m making good progress.

Plan for Next Week:

  1. Finish functionality: Main menu, Basic UI
  2. Find calculation for correct logarithmic distance
  3. Program calculation for LogMAR score at end of test
  4. Start testing

Visual Acuity, Week 5

Accomplishments:

After looking into them, co-routines will work for accomplishing the timed component of the Landolt C test. I’ve been able to successfully write the rest of the code pertaining to running the actual test. The last thing I need to to do is figure out how to mathematically represent logMAR units, and produce the correct result.

Struggles:

Fixing the threading issues were a little slow, and I didn’t have as much time as I would’ve liked in the dev lab this week, but I’ll have more next week.

Next Week:

  1. Get the test to output logMAR composite score
  2. Build a basic UI for entering / completing / customizing the test
  3. Start administering it for a few different people to bug test before gathering people for trials

Visual Acuity, Post 4

Progress

This week I started to build the workings of the Landolt C test. The test needs to run a specific number of trials, a certain number of times, at specific distances, with rest between the trial attempts. The test also should record a failure and move onto the next trial if 3 seconds pass without a guess. All of the code for that functionality has been written, however it requires multi threading, which ended up taking up most of my time this week.

Struggles

In building the timed component of the test, I ran into an issue with multi-threading. Typically in C# (my experience with it pertains mostly to web development) one would use the System.Timer library to create a timer. However, I need to pass around a bunch of information every time that timer goes off. As that library is geared more towards calling object methods (like service classes for an MVC web application), it’s really not meant for passing info around within the object. The event handler method must be declared as static, so that rout ended there.

The next thing I tried, which took up most of my time, was trying to set up my own medieval multi-threading using Time.DeltaTime from unity itself. Needless to say trying to re-engineer multi-threading myself didn’t go well.

I ended up coming to unity’s co-routine functionality towards the end of my time for the week. I’ll need to learn how that works, and see how I can pass information / call other functions from the event handler for the co-routine call.

Next Week

Once I figure that multi-threading issue, the functionality of the Landolt C test will be complete. Then I’ll be moving onto building a functional UI. Part of why the threading is an issue is because I’m trying to make things as modular / customize-able as possible so that the test can be changed to meet any criteria.

  • Enabling choice of perspective
  • Main menu and test result display UI
  • Prompts for test customization

Visual Acuity, Post 3

Progress

This week I finished off the fixed head method of what i’m calling the Landolt V(virtual) test. Both test types are complete, and record data on the actual position of the C object plane (distance, and which direction the gap is pointed). I started to work on adding hand controls to the test, and building out the rest of the architecture so that this program can run in a standalone fashion outside of unity.

I also started to run tests on myself, and found a few interesting things. First, that the issue noticed in week one where the C began to render in an odd fashion doesn’t carry over into the fixed head position test. Furthermore, in that fixed head position, the C object can get much farther away from the viewer before becoming illegible (visually useless due to rendering). I’m curious to see how others interpret these findings, whether the C becomes illegible at shorter distances for others.

I’m also continuing research into validation. There’s a lot of ophthalmology stuff out there, but none of it directly translates to tests administered on screens, or really talks about validation of a Landolt C test.

Struggles

The vive setup in the dev lab was being particularly uncooperative this weekend, but aside from that and minor frustration as I continue to look for papers relevant to the topic of validating a Landolt C test, progress has been smooth.

Next Week

  • Talk with both Alex and Kevin, get some input on test and have others try it. Also discuss research and direction.
  • Make more progress and finishing out the structure of the application

Visual Acuity, Post 2

Progress

This week starting Wednesday I worked toward getting the free head motion Landolt C test running in a virtual environment. For now I’m using the HTC vive, only because it’s what I’m most familiar with (also for convenience). Everything looks good so far, and it behaves as expected.

Before I spend time polishing that up, I wanted to spend time working on the other mode of the test, which is with the C in a fixed viewing position relative to the headset. Instead of trying to mess with the HMD viewing pipeline, I figured out it was easier to just make the plane object the C is displayed on a child of the HMD object in unity. With the background color of the unity scene being the same as the background of the C plane, it essentially accomplishes the same thing as subverting the viewing pipeline to paste an image directly onto it.

As it stands now, the test is additionally capable of the following

  • Presents two viewing modes of the Landolt C test (fixed, non-fixed)
  • (See previous posts for functionality added)

Struggles

I spent far too long trying to do goofy things to get the C plane to be fixed to the screen. Failed efforts include, but are not limited to: trying to use a HUD prefab, breaking the unity viewing pipeline, trying to directly use the HMD display as a monitor.

I also spent the obligatory hour fighting unity versions. The first time I tried to move to a system supporting an HMD I chose to ignore the warning that unity does not support loading projects from newer versions of unity.

I’m also trying to correct the way the C displays. As discussed in the last post, the C itself actually starts to render onto odd numbers of pixels as it gets quite small; changing the nature of the test entirely, I didn’t see the same problem persist into a virtual environment. Admittedly, my own vision just may not be good enough to see when that starts happening.

Next week

  • Get test controls working from the Vive controller
  • Get back to researching proving accuracy of this test
  • Figure out what distances to administer the C test

Visual Acuity, Week 1

Progress

This week I started building the unity project for the Landolt C test, as well as continuing to learn about optometry in an effort to better understand the underlying principles of what I’m doing. I started Tuesday by looking more into some of the studies mentioned in Varadharajan (which talks about how to asses and build a new logMAR chart). While it’s not directly pertinent to the Landolt C format, there are small details about assessing visual acuity tests that will prove useful for validation of the test once complete. Also I’m gaining a better sense of how to navigate the subject of optometry as I continue looking for things more related to Landolt C.
The progress on the test itself is going smoothly. Tuesday I used Photoshop to produce images for Landolt C. and E tests, then imported them into unity and got them pasted onto a viewing plane. For now the structure of the test in unity remains fairly simple. A single camera points at a viewing plane with the texture on it.

By the end of my time Friday, I completed the functionality of the test for the on screen viewing environment, essentially reproducing a basic version of the FrACT application. Unlike the FrACT application I’m using a light grey C on an all black background, as this theoretically eliminates the issue of lighting the scene.

As it stands now, the test does the following:

  • Presents a Landolt C to the user
  • Reads a directional input
  • Records the actual rotational position of the C
  • Records the user’s choice for rotational position of the C
  • Rotates, and Repositions the C for the next trial

Struggles

I spent a decent amount of time fighting with the low resolution C texture for the viewing plane. I was getting some strange pixels appearing around the edge of the C even after adjusting the usual suspects for fixing that (max texture size, bilinear -> point, shader type). The issue ended up being that the image I was using as the texture, being based on a 5 x 5 grid was a non power of two image. Changing the power of two texture setting to ‘none’ in unity fixed the pixel noise around the C.

Aside from some short code debugging the only other thing I’ve noticed is that at great distances, the C object starts to render in odd ways on a pixel by pixel basis. Without anti-aliasing, something in the rendering pipeline is just deciding to change the dimensions of the C. This will definitely affect testing results, as the C becomes easier to read in certain positions at great distance than others. For now I have no clue how to solve this, I’m hoping that the distances actually needed to measure visual acuity and the resolution of the HMD’s will make this a non issue.

 

Next Week

For the next week I first plan to get the test working in the virtual environment on some headset. I’m most comfortable with the HTC system so I’ll probably use that. Once I’ve gotten the code adjusted for input from the Vive controller, I’ll start on the next form of the test.

While the current test uses a plane to display the C object, and the user is able to move their head, we also wanted to try a version where the Landolt C is ‘pasted’ directly onto the HMD display itself. This eliminates head motion.