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

在单个Qt3D Entity中使用多Transform:灯光位置异常问题

问题:Qt3D中灯光位置异常,Transform被应用到圆环体而非灯光上

编写带光照的圆环体(Torus)展示程序,程序可正常运行,但存在灯光位置异常问题:为灯光添加新Transform时,该Transform被应用到了圆环体的位置而非灯光本身。调整参数和addComponent顺序后问题仍未解决。

灯光位置异常截图

原代码

#include <QGuiApplication>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QPointLight>

Qt3DCore::QEntity *createScene();

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    Qt3DExtras::Qt3DWindow view;

    Qt3DCore::QEntity *rootEntity = createScene();

    Qt3DRender::QCamera *camera =view.camera();
    camera->lens()->setPerspectiveProjection(60,(float)view.width()/view.height(),0.1f,1000.0f);
    camera->setPosition(QVector3D(0.0f,0.0f,40.0f));
    camera->setViewCenter(QVector3D(0.0f,0.0f,0.0f));

    view.setRootEntity(rootEntity);
    view.show();
    return app.exec();
}

Qt3DCore::QEntity *createScene()
{
    Qt3DCore::QEntity *resultEntity = new Qt3DCore::QEntity;

    Qt3DExtras::QTorusMesh *torusMesh = new Qt3DExtras::QTorusMesh(resultEntity);
    torusMesh->setRadius(15.0f);
    torusMesh->setMinorRadius(6.0f);
    torusMesh->setSlices(16);
    torusMesh->setRings(32);

    Qt3DExtras::QPhongMaterial *torusMaterial = new Qt3DExtras::QPhongMaterial(resultEntity);

    Qt3DCore::QTransform *torusTransform = new Qt3DCore::QTransform(resultEntity);

    resultEntity->addComponent(torusMesh);
    resultEntity->addComponent(torusMaterial);
    resultEntity->addComponent(torusTransform);

    Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(resultEntity);

    Qt3DRender::QPointLight *pointLight = new Qt3DRender::QPointLight(lightEntity);

    Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(resultEntity);
    lightTransform->setTranslation(QVector3D(0.0f,0.0f,30.0f));

    resultEntity->addComponent(pointLight);
    resultEntity->addComponent(lightTransform);

    return resultEntity;
}

问题根源

  1. 错误地将灯光组件(pointLight、lightTransform)添加到了根实体resultEntity,而非专门承载灯光的lightEntity,导致灯光的Transform和圆环体的Transform同时作用在根实体上,灯光无法独立定位。
  2. lightTransform的父对象被设置为resultEntity,应该关联到lightEntity,确保Transform作用于灯光实体。

修正后的代码

#include <QGuiApplication>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QPointLight>

Qt3DCore::QEntity *createScene();

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    Qt3DExtras::Qt3DWindow view;

    Qt3DCore::QEntity *rootEntity = createScene();

    Qt3DRender::QCamera *camera =view.camera();
    camera->lens()->setPerspectiveProjection(60,(float)view.width()/view.height(),0.1f,1000.0f);
    camera->setPosition(QVector3D(0.0f,0.0f,40.0f));
    camera->setViewCenter(QVector3D(0.0f,0.0f,0.0f));

    view.setRootEntity(rootEntity);
    view.show();
    return app.exec();
}

Qt3DCore::QEntity *createScene()
{
    Qt3DCore::QEntity *resultEntity = new Qt3DCore::QEntity;

    Qt3DExtras::QTorusMesh *torusMesh = new Qt3DExtras::QTorusMesh(resultEntity);
    torusMesh->setRadius(15.0f);
    torusMesh->setMinorRadius(6.0f);
    torusMesh->setSlices(16);
    torusMesh->setRings(32);

    Qt3DExtras::QPhongMaterial *torusMaterial = new Qt3DExtras::QPhongMaterial(resultEntity);

    Qt3DCore::QTransform *torusTransform = new Qt3DCore::QTransform(resultEntity);

    resultEntity->addComponent(torusMesh);
    resultEntity->addComponent(torusMaterial);
    resultEntity->addComponent(torusTransform);

    Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(resultEntity);

    Qt3DRender::QPointLight *pointLight = new Qt3DRender::QPointLight(lightEntity);
    // 可选:调整灯光参数,让效果更明显
    pointLight->setColor(Qt::white);
    pointLight->setIntensity(1.0f);

    // 将lightTransform的父对象改为lightEntity
    Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
    lightTransform->setTranslation(QVector3D(0.0f,0.0f,30.0f));

    // 将灯光组件添加到lightEntity而非根实体
    lightEntity->addComponent(pointLight);
    lightEntity->addComponent(lightTransform);

    return resultEntity;
}

关键修改说明

  • 将lightTransform的构造父对象从resultEntity改为lightEntity,确保Transform属于灯光实体。
  • 把pointLight和lightTransform通过addComponent添加到lightEntity,让灯光拥有独立的位置控制,不再和圆环体共享根实体的Transform。
  • 可选:添加灯光颜色和强度设置,让光照效果更直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:30:51