private void setupVRScene(){
        if (environment != null){
            if (environment.getApplication() != null){
                // no special scene to set up if we are doing instancing
                if( environment.isInstanceRendering() ) {
                    // distortion has to be done with compositor here... we want only one pass on our end!
                    if( environment.getApplication().getContext().getSettings().isSwapBuffers() ) {
                        setupMirrorBuffers(environment.getCamera(), dualEyeTex, true);
                    }
                    return;
                }

                leftEyeTexture  = (Texture2D) getLeftViewPort().getOutputFrameBuffer().getColorBuffer().getTexture();
                rightEyeTexture = (Texture2D)getRightViewPort().getOutputFrameBuffer().getColorBuffer().getTexture();
                leftEyeDepth    = (Texture2D) getLeftViewPort().getOutputFrameBuffer().getDepthBuffer().getTexture();
                rightEyeDepth   = (Texture2D)getRightViewPort().getOutputFrameBuffer().getDepthBuffer().getTexture();

                // main viewport is either going to be a distortion scene or nothing
                // mirroring is handled by copying framebuffers
                Iterator<Spatial> spatialIter = environment.getApplication().getViewPort().getScenes().iterator();
                while(spatialIter.hasNext()){
                    environment.getApplication().getViewPort().detachScene(spatialIter.next());
                }

                spatialIter = environment.getApplication().getGuiViewPort().getScenes().iterator();
                while(spatialIter.hasNext()){
                    environment.getApplication().getGuiViewPort().detachScene(spatialIter.next());
                }

                // only setup distortion scene if compositor isn't running (or using custom mesh distortion option)
                if( environment.getVRHardware().getCompositor() == null ) {
                    Node distortionScene = new Node();
                    Material leftMat = new Material(environment.getApplication().getAssetManager(), "Common/MatDefs/VR/OpenVR.j3md");
                    leftMat.setTexture("Texture", leftEyeTexture);
                    Geometry leftEye = new Geometry("box", setupDistortionMesh(JOpenVRLibrary.EVREye.EVREye_Eye_Left, environment.getVRHardware()));
                    leftEye.setMaterial(leftMat);
                    distortionScene.attachChild(leftEye);

                    Material rightMat = new Material(environment.getApplication().getAssetManager(), "Common/MatDefs/VR/OpenVR.j3md");
                    rightMat.setTexture("Texture", rightEyeTexture);
                    Geometry rightEye = new Geometry("box", setupDistortionMesh(JOpenVRLibrary.EVREye.EVREye_Eye_Right, environment.getVRHardware()));
                    rightEye.setMaterial(rightMat);
                    distortionScene.attachChild(rightEye);

                    distortionScene.updateGeometricState();

                    environment.getApplication().getViewPort().attachScene(distortionScene);

                    //if( useCustomDistortion ) setupFinalFullTexture(app.getViewPort().getCamera());
                }

                if( environment.getApplication().getContext().getSettings().isSwapBuffers() ) {
                    setupMirrorBuffers(environment.getCamera(), leftEyeTexture, false);
                }
            } else {
                throw new IllegalStateException("This VR environment is not attached to any application.");
            }
        } else {
            throw new IllegalStateException("This VR view manager is not attached to any VR environment.");
        }
    }
Replaces rootNode with the distortion mesh as the main camera's scene.
jme3-vr/src/main/java/com/jme3/input/vr/openvr/OpenVRViewManager.java