import QtQuick import QtQuick.Window import QtQuick3D Window { visible: true width: 800 height: 480 title: qsTr("Stereoscopic Rendering Example") color: "#404040" //visibility: Window.FullScreen Item { focus: true Keys.onPressed: { if (event.key === Qt.Key_0) { stereoCamera.stereoMode = 0; } if (event.key === Qt.Key_1) { stereoCamera.stereoMode = 1; } if (event.key === Qt.Key_2) { stereoCamera.stereoMode = 2; } if (event.key === Qt.Key_3) { stereoCamera.stereoMode = 3; } if (event.key === Qt.Key_4) { stereoCamera.stereoMode = 4; } if (event.key === Qt.Key_Plus) { stereoCamera.eyeSeparation += 1; } if (event.key === Qt.Key_Minus) { stereoCamera.eyeSeparation -= 1; } } } // Scene SceneNode { id: sceneRoot Node { id: stereoCamera property real convergence: 600.0 property real eyeSeparation: 35.0 property real fieldOfView: 60.0 property real nearPlane: 10.0 property real farPlane: 2000.0 property real aspectRatio: leftEyeView.width / leftEyeView.height property real _fov2: Math.tan(fieldOfView * Math.PI / 180 * 0.5) property real top: nearPlane * _fov2 property real a: aspectRatio * _fov2 * convergence // 0 = Mono, 1 = TopBottom, 2 = LeftRight, 3 = Anaglyp (red-cyan), 4 = Anaglyph (green-magenta) property int stereoMode: 1 // True when views are separate, false when they need to be combined with shader readonly property bool separateViews: (stereoMode == 1 || stereoMode == 2) readonly property bool isStereo: (stereoMode != 0) readonly property alias monoCamera: sceneRoot.mainCamera FrustumCamera { id: leftEyeCamera x: stereoCamera.monoCamera.x - stereoCamera.eyeSeparation * 0.5 y: stereoCamera.monoCamera.y z: stereoCamera.monoCamera.z clipNear: stereoCamera.nearPlane clipFar: stereoCamera.farPlane left: -(stereoCamera.a - stereoCamera.eyeSeparation * 0.5) * stereoCamera.nearPlane / stereoCamera.convergence right: (stereoCamera.a + stereoCamera.eyeSeparation * 0.5) * stereoCamera.nearPlane / stereoCamera.convergence top: stereoCamera.top bottom: -stereoCamera.top } FrustumCamera { id: rightEyeCamera x: stereoCamera.monoCamera.x + stereoCamera.eyeSeparation * 0.5 y: stereoCamera.monoCamera.y z: stereoCamera.monoCamera.z clipNear: stereoCamera.nearPlane clipFar: stereoCamera.farPlane left: -(stereoCamera.a + stereoCamera.eyeSeparation * 0.5) * stereoCamera.nearPlane / stereoCamera.convergence right: (stereoCamera.a - stereoCamera.eyeSeparation * 0.5) * stereoCamera.nearPlane / stereoCamera.convergence top: stereoCamera.top bottom: -stereoCamera.top } } } View3D { id: monoView width: parent.width height: parent.height importScene: sceneRoot camera: stereoCamera.monoCamera visible: !stereoCamera.isStereo environment: SceneEnvironment { antialiasingMode: SceneEnvironment.MSAA } } View3D { id: leftEyeView width: parent.width height: parent.height importScene: sceneRoot camera: leftEyeCamera layer.enabled: true layer.smooth: true layer.format: ShaderEffectSource.RGBA visible: stereoCamera.isStereo && stereoCamera.separateViews transform: Scale { xScale: (stereoCamera.stereoMode == 2) ? 0.5 : 1.0 yScale: (stereoCamera.stereoMode == 1) ? 0.5 : 1.0 } environment: SceneEnvironment { antialiasingMode: SceneEnvironment.MSAA } } View3D { id: rightEyeView width: parent.width height: parent.height x: (stereoCamera.stereoMode == 2) ? parent.width/2 : 0 y: (stereoCamera.stereoMode == 1) ? parent.height/2 : 0 importScene: sceneRoot camera: rightEyeCamera layer.enabled: true layer.smooth: true layer.format: ShaderEffectSource.RGBA visible: stereoCamera.isStereo && stereoCamera.separateViews transform: Scale { xScale: (stereoCamera.stereoMode == 2) ? 0.5 : 1.0 yScale: (stereoCamera.stereoMode == 1) ? 0.5 : 1.0 } environment: SceneEnvironment { antialiasingMode: SceneEnvironment.MSAA } } ShaderEffect { id: outputView anchors.fill: parent property variant leftEye: leftEyeView property variant rightEye: rightEyeView property alias stereoMode: stereoCamera.stereoMode blending: true visible: stereoCamera.isStereo && !stereoCamera.separateViews fragmentShader: "anaglyph.frag.qsb" } }