4
\$\begingroup\$

I was playing Star Trek Bridge Crew, and noticed that the starfield looks oddly close. The same goes for the sky in other games. I realized that this is because when rendering the skybox in a game, VR games render the skybox once for each eye. But because games use a large dome or sphere for the skybox, instead of the appearance of the skybox being located extremely far away (Which happens convincingly in non-vr games), the parallax is quite detectable to our eyes and we see the skybox for what it is, a relatively close wall of stars.

To fix this, I propose that when rendering for the right eye, the right eye camera be temporarily moved to the position of the left eye camera to render the skybox, then moved to the correct position before continuing to render the scene's foreground. Alternately, you could move the skybox model's position by a few pixels (as many as the distance between the cameras) to achieve the same effect.

This should make the appearance of the skybox appear at "infinite" distance since that's how we see stars ourselves, with both eyes seeing the photons arriving at almost parallel vectors.

The effect, in VR, should be convincing. Put simply, stars don't move their apparent position when you close one eye. That should be true in vr games too.

My question is whether, to the game devs of stack exchange, this would be possible using this method. I think the main challenge would be in changing the position of an object in the middle of a render pass.

\$\endgroup\$
  • 1
    \$\begingroup\$ Do you mean is this possible technically? (Trivially, yes.) Or do you mean is it possible in the sense that it will solve the visual issue you're describing and still look good? \$\endgroup\$ – Josh Jan 4 '18 at 18:19
  • \$\begingroup\$ Really I guess I'm asking both questions. I know that typically a render pass happens in a discrete step in a frame in most game engines, and in VR you perform a render pass first from the left eye's camera position, then another render pass from the right eye's camera position. This would require the below sequence of events: 1. Render the left eye 2. Move the Skybox over a few pixels 3. Render the right eye 4. Move the skybox back over a few pixels I also don't know if this would solve this problem. \$\endgroup\$ – NazzerDawk Jan 4 '18 at 18:27
  • \$\begingroup\$ Instead of moving the camera during the render cycle, why not have two skyboxes, one visible to each camera and only that camera? \$\endgroup\$ – Stephan Jan 4 '18 at 19:11
  • \$\begingroup\$ That might work better then, yeah. I like that idea. \$\endgroup\$ – NazzerDawk Jan 4 '18 at 19:15
  • 4
    \$\begingroup\$ Usually we just render skyboxes using the view vector as input to a cubemap. That means they're effectively at infinite distance, with no parallax at all between the eyes. Even without this trick though, parallax between the eyes is only noticeable out to a few meters, so it's unlikely to be parallax that's making the skybox appear close unless someone made a serious error. The scale of the texture detail, or perception of the screen itself as sitting at a finite distance, might be stronger contributors to this effect. \$\endgroup\$ – DMGregory Jan 4 '18 at 19:41
1
\$\begingroup\$

The skybox doesn't exist in world space so it never needs to have a position in world space. It should be rendered with a shader that takes into account its orientation and the camera's orientation and sets its camera space position to 0,0,0, so the camera is always at the center of the skybox. I've never tried it in VR, but if you draw the skybox this way once for each eye/camera, it should produce the proper infinite distance effect.

Also on a side note, there's no need for the skybox to be any particular size or sphere-shaped - it can be a small box, it just needs to be big enough not to clip with the camera's projection plane, and it needs to lose the depth test against other objects. You can set the depth in the fragment shader like this:gl_FragDepth = 0.9999999f;

\$\endgroup\$
0
\$\begingroup\$

This always bothered me and I've been searching for an answer to this for a few days, but it's a bug in at least Unity (and probably other engines). The VR skybox renders at a fixed distance, and I'm not sure why this hasn't been fixed (Subnautica has this problem where the moon looks closer than the crashed ship).

I found a work around: You setup a 3D skybox { https://www.youtube.com/watch?time_continue=5&v=9PJ6zJIHbqY OR http://www.mirzabeig.com/tutorials/3d-animated-skybox/ } and setting a parent empty object with 2 child cameras (one for each eye a tiny fraction apart) similar to the method you were mentioning and setting the parent scale to something very small. In theory, you would then skin the inside of a sphere with skybox texture. The added benefit is that you can animate these as gigantic features and even set up parameters to interact with them.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.