如何在Qt Quick Item中展示适配场景宽高比的Scene3D
问题原因
你当前的实现存在两个核心问题:
- Scene3D的尺寸适配逻辑只做了撑满父容器高度的处理,没有考虑父容器宽度不足时会横向溢出的情况,缺少"模型等比例缩放且完全容纳在父Item内"的判断逻辑
- 正交投影相机只配置了aspectRatio,没有设置正确的正交裁剪范围,导致渲染时缩放比例和预期不符
解决步骤
1. 修正Scene3D的适配逻辑
新增适配判断:比较父Item的宽高比和3D模型的宽高比,决定Scene3D是撑满宽度还是撑满高度,同时始终居中显示。
2. 完善正交相机参数
给正交相机补充左/右/上/下裁剪面、视口缩放系数的绑定,保证渲染范围和模型尺寸匹配。
3. 完善属性绑定关系
让模型宽高比更新后,自动同步到Scene3D尺寸和相机参数。
修改后的代码示例
Item { id: item Layout.fillWidth: true Layout.fillHeight: true clip: true // 防止Scene3D超出边界时显示多余内容 Scene3D { id: scene // 适配核心逻辑:等比例缩放完全放入父Item,居中显示 property real itemAspect: item.width / item.height property real fitScale: itemAspect > myObject.aspectRatio ? (item.height / scene.implicitHeight) : (item.width / scene.implicitWidth) implicitWidth: myObject.aspectRatio * implicitHeight implicitHeight: 1 // 基准值,用于适配缩放 width: implicitWidth * fitScale height: implicitHeight * fitScale anchors.centerIn: parent aspects: ["input", "logic", "render"] cameraAspectRatioMode: Scene3D.UserAspectRatio Entity { id: mainEntity components: [ RenderSettings { activeFrameGraph: ForwardRenderer { clearColor: Qt.rgba(0, 0.5, 1, 1) camera: camera } }, InputSettings {} // 补全输入组件,避免交互异常 ] Camera { id: camera projectionType: CameraLens.OrthographicProjection aspectRatio: myObject.aspectRatio // 正交投影裁剪面设置,根据模型尺寸调整缩放系数 left: -aspectRatio * 0.5 * camera.orthoScale right: aspectRatio * 0.5 * camera.orthoScale bottom: -0.5 * camera.orthoScale top: 0.5 * camera.orthoScale nearPlane: 0.1 farPlane: 1000.0 orthoScale: 2.0 // 根据你的模型实际尺寸调整该值,保证模型完整显示 position: Qt.vector3d(0.0, 0.0, 5.0) viewCenter: Qt.vector3d(0.0, 0.0, 0.0) } Entity { id: myObject property real aspectRatio: 1.0 components: [ SceneLoader { id: sceneLoader source: "file:///xxx/myObject.obj" onStatusChanged: { if (status === SceneLoader.Ready) { myObject.aspectRatio = computeAspectRatio(); } } } ] function computeAspectRatio() { // 这里补充你的计算逻辑,获取模型的实际宽高比 // 示例:从SceneLoader的entity中获取 bounding 盒计算 let bounds = sceneLoader.entity.boundingVolume.boundingBox let width = bounds.max.x - bounds.min.x let height = bounds.max.y - bounds.min.y return width / height } } } } }
注意事项
- 代码中的
orthoScale需要根据你实际加载的模型尺寸调整,值越大模型显示越小 - 如果是透视投影,只需要保留aspectRatio的绑定即可,不需要设置正交裁剪面参数
- 父Item加
clip: true可以避免适配过程中Scene3D超出边界的内容被渲染出来
内容的提问来源于stack exchange,提问作者Horst
相关产品推荐
相关产品推荐

