You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C++(非QML)在Qt3D中实现形状轮廓效果

纯C++实现Qt3D形状轮廓绘制

针对QCuboidMesh这类凸多边形网格,最轻量化的实现方式是双实体叠加渲染,不需要修改网格源码、不需要写自定义着色器,全程用Qt3D C++ API即可完成,效果完全匹配透明本体+外轮廓的需求。
长方体透明轮廓效果示意图

核心逻辑

  • 复用同一个长方体网格生成两个渲染实体,二者共用同一个位置变换组件,保证完全重合
  • 第一个实体渲染半透明本体,关闭深度写入避免遮挡轮廓线
  • 第二个实体开启线框模式+背面剔除,通过多边形偏移消除Z轴闪烁,只渲染外轮廓边线

完整实现代码

头文件引用

#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DRender/QRenderPass>
#include <Qt3DRender/QEffect>
#include <Qt3DRender/QTechnique>
#include <Qt3DRender/QCullFace>
#include <Qt3DRender/QPolygonOffset>
#include <Qt3DRender/QWireframe>
#include <Qt3DRender/QNoDepthMask>
#include <QColor>

核心构建代码

// 根实体为已创建的Qt3D场景根节点
Qt3DCore::QEntity* rootEntity = /* 对应场景根节点指针 */;

// 1. 创建共享的长方体网格,两个实体复用减少显存占用
Qt3DExtras::QCuboidMesh* cuboidMesh = new Qt3DExtras::QCuboidMesh();
cuboidMesh->setXExtents(2.0f);
cuboidMesh->setYExtents(2.0f);
cuboidMesh->setZExtents(2.0f);

// 共用变换组件,保证两个实体位置、旋转、缩放完全一致
Qt3DCore::QTransform* cuboidTransform = new Qt3DCore::QTransform();

// 2. 构建半透明本体
Qt3DCore::QEntity* solidCuboid = new Qt3DCore::QEntity(rootEntity);
Qt3DExtras::QDiffuseSpecularMaterial* transparentMat = new Qt3DExtras::QDiffuseSpecularMaterial();
// 设置本体颜色与透明度,alpha设为0就是完全透明仅显示轮廓
transparentMat->setDiffuse(QColor(80, 170, 255, 30));
transparentMat->setAlphaBlendingEnabled(true);
// 关闭本体深度写入,避免遮挡上层轮廓线
Qt3DRender::QNoDepthMask* noDepthMask = new Qt3DRender::QNoDepthMask();
auto solidEffect = const_cast<Qt3DRender::QEffect*>(transparentMat->effect());
auto solidTech = solidEffect->techniques().first();
solidTech->renderPasses().first()->addRenderState(noDepthMask);

solidCuboid->addComponent(cuboidMesh);
solidCuboid->addComponent(transparentMat);
solidCuboid->addComponent(cuboidTransform);

// 3. 构建轮廓线实体
Qt3DCore::QEntity* outlineCuboid = new Qt3DCore::QEntity(rootEntity);
Qt3DExtras::QPhongMaterial* outlineMat = new Qt3DExtras::QPhongMaterial();
// 轮廓线颜色
outlineMat->setAmbient(QColor(0, 120, 220));

// 配置轮廓渲染状态
Qt3DRender::QCullFace* cullBack = new Qt3DRender::QCullFace();
cullBack->setMode(Qt3DRender::QCullFace::Back); // 剔除背面,避免显示内部三角边
Qt3DRender::QWireframe* wireframeMode = new Qt3DRender::QWireframe(); // 开启线框渲染
Qt3DRender::QPolygonOffset* offset = new Qt3DRender::QPolygonOffset();
offset->setFactor(-1.0f);
offset->setUnits(-1.0f); // 轻微偏移轮廓位置,消除Z-fighting闪烁

auto outlineEffect = const_cast<Qt3DRender::QEffect*>(outlineMat->effect());
auto outlineTech = outlineEffect->techniques().first();
Qt3DRender::QRenderPass* outlinePass = outlineTech->renderPasses().first();
outlinePass->addRenderState(cullBack);
outlinePass->addRenderState(wireframeMode);
outlinePass->addRenderState(offset);

outlineCuboid->addComponent(cuboidMesh);
outlineCuboid->addComponent(outlineMat);
outlineCuboid->addComponent(cuboidTransform);

适配说明

  • 该方案对所有凸多边形网格(立方体、球体、圆锥、凸多面体)都生效,如果是凹多边形或复杂模型,背面剔除可能会漏出内部三角边,可替换为模板缓冲轮廓法:先渲染实体写入模板值,再将模型轻微放大渲染背面纯色,最后渲染本体即可得到干净的外轮廓,不需要线框模式。
  • 需要调整轮廓粗细时,可以加入Qt3DRender::QLineWidth组件设置线宽,注意部分OpenGL ES平台对大于1的线宽支持有限。
  • 如果需要完全隐藏本体,只需要把透明材质的diffuse alpha值设为0即可。

内容的提问来源于stack exchange,提问作者AverageQtCPPUser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:06:23