Отключите все источники света в Qt 3d

В моей компании происходит переход от старого 3D-движка к Qt3d. Одна из целей этого мероприятия - сравнить визуализированный вид старого 3D-движка с рендерингом Qt3d.

Для этого я написал небольшой пример приложения, в котором я могу сравнить старый и новый рендеринг. Есть еще много различий. Моей первой идеей было переключение всех источников света в обоих движках и сравнение силуэтов обоих изображений.

Теперь есть кое-что, чего я действительно не понимаю, и это связано с моделью освещения Qt3d.

В моем небольшом примере приложения я определяю простую сферическую сетку, камеру и флажок, который может отключить точечный источник света. Сфера освещается моделью отражения фонг.

Нет, если я выключу свет, я ожидаю простую черную сферу в моем зрителе, так как на самом деле нет света. Вместо этого все еще есть некоторое освещение (из другого источника). Я думаю, что есть какой-то другой источник света, который активирован по умолчанию.

Как я могу отключить все источники света в Qt3d? В качестве дополнительного вопроса мне также интересно, почему meshMaterial->setAmbient(QColor(255, 0, 0)); не оказывает видимого влияния на материал в конце концов. Это действительно не имеет значения, что вы введете здесь.

#include <QApplication>
#include <QWidget>
#include <QCheckBox>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DCore/QTransform.h>
#include <Qt3DRender/QCamera.h>
#include <Qt3DRender/QRenderSettings.h>
#include <Qt3DRender/QPointLight.h>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/qforwardrenderer.h>
#include <Qt3DExtras/Qt3DWindow.h>
#include <Qt3DExtras/QFirstPersonCameraController.h>

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);

    auto view = new Qt3DExtras::Qt3DWindow();
    view->defaultFrameGraph()->setClearColor(QColor(255,255,255));

    auto rootEntity = new Qt3DCore::QEntity();
    view->setRootEntity(rootEntity);

    auto cameraEntity = view->camera();
    cameraEntity->lens()->setPerspectiveProjection(45.0f, 1., 0.1f, 10000.0f);
    cameraEntity->setPosition(QVector3D(5, 5, 5));
    cameraEntity->setUpVector(QVector3D(0, 1, 0));
    cameraEntity->setViewCenter(QVector3D(0, 0, 0));

    auto lightEntity = new Qt3DCore::QEntity(rootEntity);

    auto light = new Qt3DRender::QPointLight(lightEntity);
    light->setColor("white");
    light->setIntensity(1);
    lightEntity->addComponent(light);

    auto lightTransform = new Qt3DCore::QTransform(lightEntity);
    lightTransform->setTranslation(cameraEntity->position());
    lightEntity->addComponent(lightTransform);

    lightEntity->setEnabled(false);

    // For camera controls
    auto camController = new Qt3DExtras::QFirstPersonCameraController(rootEntity);
    camController->setCamera(cameraEntity);

    auto mesh = new Qt3DExtras::QSphereMesh();
    mesh->setRadius(1.);

    auto meshMaterial = new Qt3DExtras::QPhongMaterial();
    meshMaterial->setDiffuse(QColor(0, 255, 0));
    meshMaterial->setAmbient(QColor(255, 0, 0));
    meshMaterial->setSpecular(QColor(0,0,255));
    meshMaterial->setShininess(23);

    auto meshEntity = new Qt3DCore::QEntity(rootEntity);
    meshEntity->addComponent(mesh);
    meshEntity->addComponent(meshMaterial);
    meshEntity->setEnabled(true);

    auto disableLight = new QCheckBox();
    auto container = QWidget::createWindowContainer(view);
    QFrame frame;
    frame.setLayout(new QVBoxLayout);
    frame.layout()->addWidget(container);
    frame.layout()->addWidget(disableLight);
    QObject::connect(disableLight, &QCheckBox::stateChanged, [lightEntity](auto state) {
        lightEntity->setEnabled(state == Qt::CheckState::Checked);
    });
    frame.setFixedSize(500, 500);
    frame.show();
    return a.exec();
}

1 ответ

Решение

Если в вашей сцене Qt3D не созданы легкие объекты, Qt3D добавит одну для вас. Это сделано для того, чтобы пользователи ничего не видели без света. После того, как вы добавите источник света, он по умолчанию будет опущен.

вы можете обойти это поведение по умолчанию, добавив источник света с интенсивностью, равной нулю:

DirectionalLight {
    worldDirection: Qt.vector3d(-1, 1, -1)
    intensity: 0.0
}

Это даст вам следующий эффект: тест с кубоидальной и сферической сеткой с PhongMaterial

Так что манипулирование свойством интенсивности света может дать то, что вы хотите.

Другие вопросы по тегам