Aleph0
Aleph0

Reputation: 6084

Disable Anti Aliasing in Qt3D

We are migrating from an older 3D engine to Qt 3D. In order to compare the older 3D engine with Qt3D I'm writing a small app, that compares both renderings side to side.

In order to make an automatic comparision more suitable I'm in need to deactive anti aliasing in Qt3D.

I think, that I have to modify the frame graph, but I have no idea, what is necessary to do this.

The following example app shows a simple Qt3D Scene with a sphere. Does anyone know how to perform the necessary changes in the default frame graph?

#include <QApplication>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DRender/QCamera.h>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/qforwardrenderer.h>
#include <Qt3DExtras/Qt3DWindow.h>

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

    auto view = new Qt3DExtras::Qt3DWindow();
    auto frameGraph = view->defaultFrameGraph();
    frameGraph->setClearColor(QColor(255,255,255));
    // Disable Anti-Aliasing
    // What is necessary here!
    // ---------------------

    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 mesh = new Qt3DExtras::QSphereMesh();
    mesh->setRadius(1.);

    auto meshMaterial = new Qt3DExtras::QDiffuseSpecularMaterial();
    meshMaterial->setAlphaBlendingEnabled(true);
    meshMaterial->setDiffuse(QColor(50, 50, 50));
    meshMaterial->setAmbient(QColor(255, 255, 255));
    meshMaterial->setSpecular(QColor(255,255,255));
    meshMaterial->setShininess(100);

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

    auto container = QWidget::createWindowContainer(view);
    QFrame frame;
    frame.setLayout(new QVBoxLayout);
    frame.layout()->addWidget(container);

    frame.setFixedSize(500, 500);
    frame.show();
    return a.exec();
}

Upvotes: 1

Views: 943

Answers (3)

Florian Blume
Florian Blume

Reputation: 3345

If anyone stumbles across this, how I can enable/disable antialising in Qt3D is by setting the number of samples on the surface format:

QSurfaceFormat format;
format.setSamples(0); // Disables anti-aliasing
QSurfaceFormat::setDefaultFormat(format);
QSurfaceFormat format;
format.setSamples(4); // Enables 4x anti-aliasing
QSurfaceFormat::setDefaultFormat(format);

This has to happen before setting up Qt3D.

NB: This is for when you want to disable/enable antialiasing in a default Qt3D scene, i.e. where you don't render to a texture and then use it in a shader. If you want to do the latter, check out QMultiSampleAntiAliasing.

Upvotes: 2

Aleph0
Aleph0

Reputation: 6084

The following code disables the anti-aliasing, but is definitely not the correct way to do it. But, after all I got to a working solution. Setting setStereo(true) in the QSurfaceFormat disabled the anti-aliasing magically.

#include <QApplication>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DRender/QCamera>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/qforwardrenderer>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QRenderSettings>

void depthFirstTraversal(const Qt3DRender::QFrameGraphNode* node, int depth) {
    auto pad = QString(depth, QChar('\t'));
    qDebug().noquote().nospace() <<  pad << node;
    for (auto iter : node->children()) {
        if (auto frameGraphNode = qobject_cast<Qt3DRender::QFrameGraphNode*>(iter)) {
            depthFirstTraversal(frameGraphNode, depth + 1);
        }       
    }
}

int main(int argc, char* argv[])
{
    QSurfaceFormat format;
    format.setStereo(true); // Disables anti-aliasing, but is definitely weird
    QSurfaceFormat::setDefaultFormat(format);

    QApplication a(argc, argv);

    auto view = new Qt3DExtras::Qt3DWindow();
    auto frameGraph = view->activeFrameGraph();
    depthFirstTraversal(frameGraph, 0);
    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(1, 1, 0));
    cameraEntity->setViewCenter(QVector3D(0, 0, 0));

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

    auto meshMaterial = new Qt3DExtras::QDiffuseSpecularMaterial();
    meshMaterial->setAlphaBlendingEnabled(true);
    meshMaterial->setDiffuse(QColor(50, 50, 50));
    meshMaterial->setAmbient(QColor(255, 255, 255));
    meshMaterial->setSpecular(QColor(255,255,255));
    meshMaterial->setShininess(100);

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

    auto container = QWidget::createWindowContainer(view);
    QFrame frame;
    frame.setLayout(new QVBoxLayout);
    frame.layout()->addWidget(container);

    frame.setFixedSize(500, 500);
    frame.show();
    return a.exec();
}

Upvotes: 1

Eddy Alleman
Eddy Alleman

Reputation: 1096

Have a look at the Qt Docs for multisampleantialiasing There is some example code there.

EDIT: addendum

QML Scene3D has the following property

multisample : bool

true if a multisample render buffer is requested. By default multisampling is enabled. If the OpenGL implementation has no support for multisample renderbuffers or framebuffer blits, the request to use multisampling is ignored. Note: Refrain from changing the value frequently as it involves expensive and potentially slow initialization of framebuffers and other OpenGL resources.

But there is no counterpart of Scene3D for the C++ world... Most QML classes have a counterpart for C++ by adding a "Q" in front of the name. But there is no QScene3D.

Remark about the usage of Qt3DExtras::Qt3DWindow

Qt3DWindow is derived from QWindow and was created to have solutions without the use of QWidgets. You can read more about the details in this post

If you want to add buttons, sliders, ets... in a later testing stage, I would advise using QML. You will get more flexibility from Qt3D compared to using C++ solely. It is even possible to mix C++ and QML: you can make your logic in C++ and register for usage in QML. So you get the best of both worlds. That is what I would do if I wanted to test the Qt3D capabilities thoroughly.

Happy coding!

Upvotes: 2

Related Questions