Eye separation in Three.js stereo 3D scenes
Recently I was creating a large 3D scene where I was using coordinate units equivalent to metres, so my scene was around 2km by 2km. To make it more interesting I was also using effects for stereoscopic viewing including for 3D TVs and Google Cardboard. But in such big scenes things can be far away and so the 3D effect wasn’t as good as I’d have liked because Three.js uses an inter-pupil distance of 0.064 (in metre-world that’s 64mm, so very similar to a real-world human).
Obviously I could have got around that by scaling my scene so that’s it’s smaller, which would make things stand out better in stereoscopic vision by creating a disparity between the left and right eye views. But I wanted to keep it simple in coordinate terms so I had a look into the Three.js code. It turns out that the inter-pupil distance is hard-coded as half the distance between the eyes: i.e. it’s actually the left and right offset for the corresponding cameras. So, to allow me to vary the eye separation the first thing I did was change the Three.js file (around line 17400 in the version I used) to replace the hard-coded ‘var eyeSep = 0.064 / 2;’ line with:
if(typeof eyeseparation!='undefined') var eyeSep=eyeseparation; else var eyeSep = 0.064 / 2;
That change shouldn’t have any effect on Three.js use for anything else I use it with, but if I include something like ‘var eyeseparation=0.2;’ in my own JavaScript code (as the half-inter-pupil distance) then it’ll override the default value. That means I can now easily vary the inter-pupil distance when I need to and, because it’s the StereoCamera object that’s been changed, it should work with most stereoscopic effects in Three.js. And, if you’re wondering why that might be a good idea then here’s a few reasons:
In real-life anything past around 20m away doesn’t look any different to your left and right eyes, and the same concept applies to virtual world viewing. So when there aren’t any close-up objects to add 3D effect we can emphasise larger, more distant, objects this way.
If a scene doesn’t try to keep its’ dimensions similar to real-world ones (e.g. we’re using some sort of scaling factor) then we can use this to scale the eye separation too.
If you’re trying to replicate some sort of warped space-time dimensions, where axes have different scalings, then you may want to adjust eye separation as a way of simulating dimension-distortion (and it’s a cheaper and safer way of doing that than alcohol).
Allowing users control over the eye separation lets them adjust their 3D viewing preferences. So users who have difficulty viewing scenes can reduce the separation to ease viewing, and experienced 3D users can increase the separation to accentuate the stereoscopic effect. And for beginners, they can vary the separation over time as a way to get used to 3D viewing without too much eye straining.
It could be a good way of adding some dynamic visual effects and feedback, by varying eye separation as a function of time (with some more changes to the StereoCamera code). Of course, if you do that too much, or too quickly, best to have a non-virtual bucket close by!





