1

I have written a Three.js application using StereoEffect, using 3 scenes for overlaying purposes, by clearing renderer depth. (Using this approach Three.js - Geometry on top of another).

However, I now need to use VREffect, for better compatibility with headsets such as the Gear VR, using the WebVR Polyfill.

The following are snippets from the code, to show how it's set up:

const renderer = new THREE.WebGLRenderer({antialias: false})
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.autoClear = false;
document.body.appendChild(renderer.domElement)

effect = new THREE.VREffect(renderer)
effect.separation = 0
effect.setSize(window.innerWidth, window.innerHeight)

let vrDisplay
navigator.getVRDisplays().then(displays => {
    if (displays.length > 0) 
        vrDisplay = displays[0]
})

// Add button to enable the VR mode (display stereo)
const vrButton = VRSamplesUtil.addButton("Enter VR", "E", "/vr/cardboard64.png", () => {
    vrDisplay.requestPresent([{source: renderer.domElement}])
})

... The rest of the code ...

Inside my animation loop:

renderer.clear()
effect.render(scene, camera)
renderer.clearDepth()

effect.render(scene2, camera)
effect.render(scene3, camera)

However, this approach doesn't seem to work when using VREffect (only when entering VR mode - EG viewing it on my desktop works fine). I think the issue is that the renderer.clear() or renderer.clearDepth() is not taking effect, as the canvas is pitch black, apart from some elements in scene3.

Furthermore, when commenting out the rendering of scene2 and scene3, I can perfectly well see everything in the first scene, rendered correctly.

Looking through the code in VREffect, and StereoEffect, I couldn't figure out which part rendered my changes useless.

Any help/hints would be greatly appreciated.

Community
  • 1
  • 1
Dan Ruta
  • 11
  • 1
  • 6
  • just had a somewhat similar-problem which was caused by `VREffect`, `StereoEffect` etc all calling `renderer.clear()` as part of their `render()`-function. Can you test if setting `renderer.autoClear = false` might help in your case? (see https://github.com/mrdoob/three.js/blob/master/examples/js/effects/VREffect.js#L376) *EDIT: just noticed you already set that. Sorry.* – Martin Schuhfuß Sep 14 '16 at 21:58
  • While trying things, I put renderer.clear() before scene2 and scene3 and I managed to get the exact same output as I was getting on the phone, when activating VR mode (scene3 contents on black background), so my thoughts are that somewhere deeper, the renderer is being cleared. Although not in VREffect, I don't think, as there is nothing in the code (following the WebGLRenderer documentation) to indicate it is doing it. @MartinSchuhfuß renderer.autoClear is set to false (verified by console.log), so that shouldn't be triggering it. Tried even commenting it out from VREffect, where used. – Dan Ruta Sep 17 '16 at 17:41

1 Answers1

0

I never did find out how to fix that issue, but I got around it by using StereoEffect instead of VREffect for browsers other than the Gear VR's, as VREffect worked perfectly fine there, but not on a normal phone browser, where cardboard might be used. Here's what I did, if anyone else runs into this issue:

From the example above, I turned the vrButton bit into this:

const vrButton = VRSamplesUtil.addButton("Enter VR", "E", "/images/cardboard64.png", () => {

    if(navigator.userAgent.includes("Mobile VR")){
        vrDisplay.requestPresent([{source: renderer.domElement}])

    }else {
        effect = new THREE.StereoEffect(renderer)
        effect.separation = 0
        effect.setSize(window.innerWidth, window.innerHeight)
        document.getElementById("vr-sample-button-container").style.display = "none"
    } 
})

where I switched over from VREffect to StereoEffect when the 'View in VR' button is clicked.

With this approach, however, the content will not be fullscreen and the device will eventually go to sleep. To fix both issues, you can have the user tap the screen to manually turn on fullscreen with this:

renderer.domElement.addEventListener("click", () => {
    if(document.fullscreenEnabled && renderer.domElement.requestFullScreen() ||
       document.webkitFullscreenEnabled && renderer.domElement.webkitRequestFullScreen() ||
       document.mozFullScreenEnabled &&    renderer.domElement.mozRequestFullScreen() ||
       document.msFullScreenEnabled &&     renderer.domElement.msRequestFullScreen() ){}
})

Obviously, this is not as good of a user experience, and you don't get the nice UI, so if someone finds this and knows of an actual fix, please leave an answer/comment. I'll update this if I find anything myself.

Some final thoughts, afaik the Gear VR browser has some sort of native WebVR implementation whereas in other places, the polyfill was used, so that could be part of the issue.

Dan Ruta
  • 11
  • 1
  • 6