From 0d6360909793aab11c66f4b8f7001f71cbacfee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaj=20Gr=C3=B6nholm?= Date: Mon, 9 Sep 2019 11:09:02 +0300 Subject: Stereoscopic improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make left & right eye camera nodes pointers, fixing e.g. presentations with specular reflection. Use separate textures for fixing temporal AA. Don't allow eye separation become negative. Task-number: QT3DS-3899 Change-Id: Ide4d26d293c37b16048e2691ad51a32b8d4cc276 Reviewed-by: Janne Kangas Reviewed-by: Tomi Korpipää Reviewed-by: Mahmoud Badri --- .../Qt3DSRendererImplLayerRenderData.cpp | 28 ++++++---- .../Qt3DSRendererImplLayerRenderData.h | 4 +- .../Qt3DSRendererImplLayerRenderHelper.cpp | 61 ++++++++++++++++++---- .../Qt3DSRendererImplLayerRenderHelper.h | 5 +- tools/viewer/qml/main.qml | 6 ++- 5 files changed, 77 insertions(+), 27 deletions(-) diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp index 7b7043f..b99773b 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp @@ -76,7 +76,8 @@ namespace render { SLayerRenderData::SLayerRenderData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer) : SLayerRenderPreparationData(inLayer, inRenderer) , m_LayerTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_TemporalAATexture(inRenderer.GetQt3DSContext().GetResourceManager()) + , m_TemporalAATexture{inRenderer.GetQt3DSContext().GetResourceManager(), + inRenderer.GetQt3DSContext().GetResourceManager()} , m_LayerDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) , m_LayerPrepassDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) , m_LayerWidgetTexture(inRenderer.GetQt3DSContext().GetResourceManager()) @@ -96,6 +97,7 @@ namespace render { , mRefCount(0) , m_DepthBufferFormat(NVRenderTextureFormats::Unknown) { + } SLayerRenderData::~SLayerRenderData() @@ -163,7 +165,8 @@ namespace render { m_LayerSsaoTexture.ReleaseTexture(); m_LayerWidgetTexture.ReleaseTexture(); m_LayerPrepassDepthTexture.ReleaseTexture(); - m_TemporalAATexture.ReleaseTexture(); + m_TemporalAATexture[0].ReleaseTexture(); + m_TemporalAATexture[1].ReleaseTexture(); m_LayerMultisampleTexture.ReleaseTexture(); m_LayerMultisamplePrepassDepthTexture.ReleaseTexture(); m_LayerMultisampleWidgetTexture.ReleaseTexture(); @@ -1373,6 +1376,11 @@ namespace render { m_ProgressiveAAPassIndex && m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex; bool isTemporalAABlendPass = m_Layer.m_TemporalAAEnabled && m_ProgressiveAAPassIndex == 0; + // Select correct temporal AA texture + StereoViews::Enum stereoView = m_Renderer.GetQt3DSContext().GetStereoView(); + int temporalIndex = (stereoView == StereoViews::Right) ? 1 : 0; + CResourceTexture2D &temporalAATexture = m_TemporalAATexture[temporalIndex]; + if (isProgressiveAABlendPass || isTemporalAABlendPass) { theBlendShader = m_Renderer.GetLayerProgAABlendShader(); if (theBlendShader) { @@ -1385,13 +1393,11 @@ namespace render { aaFactorIndex = (m_ProgressiveAAPassIndex - 1); theVertexOffsets = s_VertexOffsets[aaFactorIndex]; } else { - if (m_TemporalAATexture.GetTexture()) - theLastLayerTexture.StealTexture(m_TemporalAATexture); - else { - if (hadLayerTexture) { - theLastLayerTexture.StealTexture(m_LayerTexture); - } - } + if (temporalAATexture.GetTexture()) + theLastLayerTexture.StealTexture(temporalAATexture); + else if (hadLayerTexture) + theLastLayerTexture.StealTexture(m_LayerTexture); + theVertexOffsets = s_TemporalVertexOffsets[m_TemporalAAPassIndex]; ++m_TemporalAAPassIndex; ++m_NonDirtyTemporalAAPassIndex; @@ -1454,7 +1460,7 @@ namespace render { sampleCount); if (!isTemporalAABlendPass) - m_TemporalAATexture.ReleaseTexture(); + temporalAATexture.ReleaseTexture(); // Allocating a frame buffer can cause it to be bound, so we need to save state before this // happens. @@ -1648,7 +1654,7 @@ namespace render { theFB->Attach(NVRenderFrameBufferAttachments::Color0, qt3ds::render::NVRenderTextureOrRenderBuffer()); if (isTemporalAABlendPass) - m_TemporalAATexture.StealTexture(m_LayerTexture); + temporalAATexture.StealTexture(m_LayerTexture); m_LayerTexture.StealTexture(targetTexture); } diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h index 4e237b0..8e5c694 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.h @@ -53,7 +53,9 @@ struct AdvancedBlendModes // or just because a flag forces it. If they are rendered offscreen we can then // cache the result so we don't render the layer again if it isn't dirty. CResourceTexture2D m_LayerTexture; - CResourceTexture2D m_TemporalAATexture; + // Multiple temporal AA textures for stereoscopic needs. + // First used for mono/left view, second for right view. + CResourceTexture2D m_TemporalAATexture[2]; // Sometimes we need to render our depth buffer to a depth texture. CResourceTexture2D m_LayerDepthTexture; CResourceTexture2D m_LayerPrepassDepthTexture; diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp index 9f0cc2d..79e2185 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp @@ -68,8 +68,10 @@ QT3DSVec2 ToRectRelativeCoords(const QT3DSVec2 &inCoords, const NVRenderRectF &i } SLayerRenderHelper::SLayerRenderHelper() - : m_Layer(NULL) - , m_Camera(NULL) + : m_Layer(nullptr) + , m_Camera(nullptr) + , m_CameraLeftEye(nullptr) + , m_CameraRightEye(nullptr) , m_Offscreen(false) { } @@ -87,6 +89,9 @@ SLayerRenderHelper::SLayerRenderHelper(const NVRenderRectF &inPresentationViewpo , m_PresentationScissor(inPresentationScissor) , m_PresentationDesignDimensions(inPresentationDesignDimensions) , m_Layer(&inLayer) + , m_Camera(nullptr) + , m_CameraLeftEye(nullptr) + , m_CameraRightEye(nullptr) , m_Offscreen(inOffscreen) , m_ScaleMode(inScaleMode) , m_StereoMode(inStereoMode) @@ -260,9 +265,9 @@ QSize SLayerRenderHelper::GetTextureDimensions() const SCamera *SLayerRenderHelper::GetCamera() { if (m_StereoView == StereoViews::Left) - return &m_CameraLeftEye; + return m_CameraLeftEye; if (m_StereoView == StereoViews::Right) - return &m_CameraRightEye; + return m_CameraRightEye; return m_Camera; } @@ -312,7 +317,7 @@ Option SLayerRenderHelper::GetPickRay(const QT3DSVec2 &inMouseCoords, bool inForceIntersect, bool sceneCameraView) const { - if (m_Camera == NULL) + if (!m_Camera) return Empty(); Option theCoords( GetLayerMouseCoords(inMouseCoords, inWindowDimensions, inForceIntersect)); @@ -336,11 +341,45 @@ bool SLayerRenderHelper::isStereoscopic() const return m_StereoMode != StereoModes::Mono; } +void SLayerRenderHelper::copyCameraProperties(SCamera *sourceCamera, + SCamera *destinationCamera) +{ + if (!sourceCamera || !destinationCamera) + return; + + destinationCamera->m_FOV = sourceCamera->m_FOV; + destinationCamera->m_ClipFar = sourceCamera->m_ClipFar; + destinationCamera->m_ClipNear = sourceCamera->m_ClipNear; + destinationCamera->m_ScaleMode = sourceCamera->m_ScaleMode; + destinationCamera->m_Projection = sourceCamera->m_Projection; + destinationCamera->m_ScaleAnchor = sourceCamera->m_ScaleAnchor; + destinationCamera->m_FrustumScale = sourceCamera->m_FrustumScale; + destinationCamera->m_FOVHorizontal = sourceCamera->m_FOVHorizontal; + destinationCamera->m_EnableFrustumCulling = sourceCamera->m_EnableFrustumCulling; + destinationCamera->m_Flags = sourceCamera->m_Flags; + destinationCamera->m_Pivot = sourceCamera->m_Pivot; + destinationCamera->m_Scale = sourceCamera->m_Scale; + destinationCamera->m_DFSIndex = sourceCamera->m_DFSIndex; + destinationCamera->m_Position = sourceCamera->m_Position; + destinationCamera->m_Rotation = sourceCamera->m_Rotation; + destinationCamera->m_UserData = sourceCamera->m_UserData; + destinationCamera->m_LocalOpacity = sourceCamera->m_LocalOpacity; + destinationCamera->m_GlobalOpacity = sourceCamera->m_GlobalOpacity; + destinationCamera->m_RotationOrder = sourceCamera->m_RotationOrder; + destinationCamera->m_LocalTransform = sourceCamera->m_LocalTransform; + destinationCamera->m_GlobalTransform = sourceCamera->m_GlobalTransform; +} + void SLayerRenderHelper::adjustCameraStereoSeparation() { + if (!m_CameraLeftEye) + m_CameraLeftEye = new SCamera(); + if (!m_CameraRightEye) + m_CameraRightEye = new SCamera(); + // Copy m_Camera properties into left & right cameras - m_CameraLeftEye = SCamera(*m_Camera); - m_CameraRightEye = SCamera(*m_Camera); + copyCameraProperties(m_Camera, m_CameraLeftEye); + copyCameraProperties(m_Camera, m_CameraRightEye); // Adjust left & right camera positions by eye separation QT3DSMat44 mat = QT3DSMat44::createIdentity(); @@ -349,12 +388,12 @@ void SLayerRenderHelper::adjustCameraStereoSeparation() camPos.x = m_Camera->m_Position.x - m_StereoEyeSeparation; mat.scale(QT3DSVec4(m_Camera->m_Scale, 1.0f)); mat.setPosition(camPos); - m_CameraLeftEye.SetLocalTransformFromMatrix(mat); + m_CameraLeftEye->SetLocalTransformFromMatrix(mat); camPos.x = m_Camera->m_Position.x + m_StereoEyeSeparation; mat.scale(QT3DSVec4(m_Camera->m_Scale, 1.0f)); mat.setPosition(camPos); - m_CameraRightEye.SetLocalTransformFromMatrix(mat); + m_CameraRightEye->SetLocalTransformFromMatrix(mat); - m_CameraLeftEye.MarkDirty(); - m_CameraRightEye.MarkDirty(); + m_CameraLeftEye->MarkDirty(); + m_CameraRightEye->MarkDirty(); } diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h index 3b29c7d..19fd3f5 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h @@ -60,8 +60,8 @@ namespace render { QT3DSVec2 m_PresentationDesignDimensions; SLayer *m_Layer; SCamera *m_Camera; - SCamera m_CameraLeftEye; - SCamera m_CameraRightEye; + SCamera *m_CameraLeftEye; + SCamera *m_CameraRightEye; bool m_Offscreen; NVRenderRectF m_Viewport; @@ -130,6 +130,7 @@ namespace render { // different than the layer to presentation viewport. NVRenderRectF GetLayerRenderViewport() const; + void copyCameraProperties(SCamera *sourceCamera, SCamera *destinationCamera); void adjustCameraStereoSeparation(); }; } diff --git a/tools/viewer/qml/main.qml b/tools/viewer/qml/main.qml index 58afb69..1a59739 100644 --- a/tools/viewer/qml/main.qml +++ b/tools/viewer/qml/main.qml @@ -625,8 +625,10 @@ ApplicationWindow { shortcut: "Ctrl+Shift+-" enabled: _viewerHelper.contentView === ViewerHelper.StudioView onTriggered: { - if (enabled) - window.stereoEyeSeparation -= 0.1; + if (enabled) { + window.stereoEyeSeparation + = Math.max(0, window.stereoEyeSeparation - 0.1); + } } } } -- cgit v1.2.3