Hiatus

Since July of last year, I’ve been working full-time in the VR industry, so my development for mobile VR is on hold, as is this blog. However, I’ve begun building a home machine and space for room-scale VR. Once that’s all up and running I hope to document my next forays in development.

In the meantime, if you have an interest in the state of VR, I recommend the Voices of VR podcast.

If you have an interest in Unity development, try the Debug Log podcast.

Google Cardboard View-Master Devkit Modification

I have found the Hasbro View-Master VR to be a very serviceable Cardboard device. The fact that it simply flips open without any velcro and that it’s not made of literal cardboard are big plusses, and the face-gasket is rubberized, which borders on actually being comfortable.

However, it does not feature any openings for earbud or data cables, understandably as it’s meant to be light-tight, and most users probably aren’t using it while hooked up to their computers. When developing on Cardboard with a dedicated test device, it’s nice to be able to test any VR apps as they are meant to be used, in a Cardboard device, so I decided to make a quick modification to not only allow a data cable to remain connected while it’s closed, but also add in a port for earbuds.

IMG_2380

I have set mine up for an iPhone 5. Naturally the placement of any cuts may differ for other mobile devices. Also note that depending on how closely your cuts conform to the shape of your cables, there may be a little light leakage from the new holes. However, I was pretty loose with my cuts and still find the leakage to be negligible, especially considering that one’s right hand is typically covering the holes when using it anyhow.

Tools you will need:

  • Phillips Screwdriver
  • Dremel
  • Safety Glasses
  • Marker

Optional:

  • Vise
  • Small File
  • Tissue/Paper Towel

First separate the halves of the View-Master by removing the four screws that hold the hinge in place. This will make operating on the device halves much easier.

IMG_2382

Plug in your cables while your mobile device is mounted in the View-Master if possible to see where the cuts will need to be made. If the cables cannot be plugged in while the mobile device is in the View-Master, lay the cables over the ports to eyeball it.

IMG_2378

Use a felt marker to indicate the size and location for the holes. You may notice at this point that the inner lip of the front half is made of rubber, while the rest of the device is plastic.

IMG_2381

Fit the two halves back together  and use the marks on the front half to see where to draw aligning marks on the outside of the back half, which should be roughly the size of a cross-section of the cables themselves.

IMG_2383

Separate the halves again. If you have a vise handy, use it to hold the View-Master. You may wish to also use a tissue or paper towel to cover the inside of the device to prevent bits of rubber or plastic from falling into it.

Using your Dremel and pretty much any cutting disc, carefully carve away the rubber lip where indicated by the marker. Try cutting it a bit smaller than the cable’s width at first, since the rubber can stretch to accommodate the cable. Do not cut into the white plastic unless necessary to accommodate your cable placement.

Do the same for the red plastic outer lip on the back half. This cut would benefit from being slightly larger than the cable to reduce the possibility of pinching it when closing the device. I also beveled the edges of mine a bit to further reduce the chance of pinching.

IMG_2385

You may want to use a small file to get rid of the hanging bits of plastic and smooth or shape the edges.

Repeat this process with the earbud hole (I had to simply carve away the side of the rubber lip a bit to fit this cable). Screw the two halves back together and you’re done! Your very own View-Master brand Google Cardboard dev kit!

Hope that helps anyone trying to come up with a decent Cardboard development solution. I’m finding that it’s saving me a fair amount of time on iterations the long run not having to open the device or fiddle with cables. I can also use it to view other VR apps with earbuds to boot.

UI for Recumbent VR

When a VR user is lying down (recumbent), their default orientation is orthogonal to the world’s, and a few challenges are introduced.  The one I am currently tackling is how to have an intuitive, but non-invasive menu.

In most Cardboard apps, the standard is to place the menu at the “feet” of the user, or directly downward from their head. Clearly, this will not work for someone who is lying on their back, as the menu would be beneath them. Placing the menu at their “feet” also doesn’t work, because one of the most necessary uses of the in-game menu is to recenter the world’s orientation to that of the user.

The gyroscopes of most mobile phones introduce drift to the user’s orientation, causing it to slowly change over time. The user needs to be able to set up the initial orientation of the virtual world to match their own, and to occasionally re-synchronize the two. To this end, I need to be able to have the user bring up the menu from any point around the world’s vertical axis.

Since the entirety of this VR experience’s action takes place in the sky, I consider the hemisphere above the user to be the “game space”. Firing fireworks into the ground, after all, does not produce a desirable effect (also it means I would need to add collision detection to the terrain). So, when the user looks down past a certain angle, the UI menu appears, and tracks their orientation around the vertical axis, allowing them to re-orient the world to their physical position with ease. Once the user looks back up into the sky, the menu slides underground again, out of view.

I find it fairly easy to use, although I’ll leave it to user testing to see if it’s an effective and intuitive method of presenting a menu to a prone user. The fact that the user is lying down looking the sky also means that synchronizing their orientation with their real self is not particularly important, but maybe I just like an interesting problem to solve.

Ambient Audio

Because the user should inhabit their virtual selves as much as possible, and their virtual self is also lying down, I thought to emulate the effect of muffling the sound in one ear when it is pressed down against the ground. Of course, the actual user is wearing earbuds or headphones, so the sound will not be muted, but since I can track the angle their head is positioned in, I can fake it by panning the ambience away from the ear that is pressed down.

Ideally, the master sound channel would be muted on the muffled side, but panning an audio mixer channel does not appear to be possible. Unless there’s something I’m missing, this is the first time I’ve run up against a limitation of Unity, rather than my own ability or budget.

Anyhow, individual 2D audio sources can be panned. So, I can at least control the ambient sound. First, to figure out how to determine if the user’s head is tiled to one side. I can read their output and determine the range of values that represent the user tilting their all the way to the right or left. Once I had those , I used Mathf.InverseLerp to turn the range of angles into a float from 0 to 1. The following is called form the Update() function:

void MuffleAmbience (){
    float panningAmount = 0.0f;

    if (Camera.main.transform.eulerAngles.z > 60 && Camera.main.transform.eulerAngles.z < 86 ) {
      //	The user's head is tilted to the left.
      panningAmount = Mathf.InverseLerp( 60, 86, Camera.main.transform.eulerAngles.z );
    } else if (Camera.main.transform.eulerAngles.z > 274 && Camera.main.transform.eulerAngles.z < 300) {
      //	The user's head is tilted to the right.
      panningAmount = Mathf.InverseLerp( 300, 274, Camera.main.transform.eulerAngles.z ) * -1;
    } 

    ambience.panStereo = panningAmount;
  }
}

Mathf.Lerp returns a value from 0 to 1.0 represented how far far between two numbers a third number is. For example, 8 is halfway between 6 and 10, so Mathf.InverseLerp (6,10,8) would return 0.5. I do two checks, one each for left and right, and then set the ambience’s stereo panning respectively. This only occurs at the edge of the range of movement, so the sounds are not muffled in either channel until the user’s head is just about resting on the pillow. I also cut off the range a bit so it doesn’t go fully silent in either channel.

Trying it out, it feels quite natural, and is the sort of feature that isn’t really noticed by the user unless it’s pointed out.The 3D audio of the fireworks playing their whistles, booms and cracks still plays in 3D space regardless of the user’s head orientation though. Perhaps I can come up with another hack for that.

Skyboxing

Using a Skybox in VR was easier than I imagined. I had concerns that the ability to perceive depth would allow the user to see the box as a cube, but it all appears infinitely distant, as far as I can tell.

As for the image, there are plenty of starry night skyboxes available on the asset store. First try was a free fantasy skybox with gorgeous clouds. The fantasy skybox looked great, but having static clouds on the skybox looks worse in VR than it usually does. Not only is it apparent that the clouds and stars at at the same distance, I can’t have static clouds if the user is going to be staring primarily at the sky!

I now have purchased a skybox starter pack with a variety of plain day and night skyboxes and went with a clear starry night with supermoon.. So, I must figure out a method for making dynamic clouds that works on mobile. Scrolling UVs should do the trick if I can get that to work with a transparent shader. I’ll cover it in another entry.