1
votes

Désactiver l'anticrénelage dans Qt3D

Nous migrons d'un ancien moteur 3D vers Qt 3D. Afin de comparer l'ancien moteur 3D avec Qt3D, j'écris une petite application, qui compare les deux rendus côte à côte.

Afin de rendre une comparaison automatique plus appropriée, j'ai besoin de désactiver l'anti-aliasing dans Qt3D.

Je pense que je dois modifier le frame graph, mais je n'ai aucune idée de ce qui est nécessaire pour le faire.

L'exemple d'application suivant montre une simple scène Qt3D avec un sphère. Quelqu'un sait-il comment effectuer les modifications nécessaires dans le frame graph par défaut?

#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();
}


4 commentaires

Êtes-vous sûr que l'anticrénelage est activé? En regardant ce post , il semble que vous deviez ajouter un Classe QMultiSampleAntiAliasing à votre framegraph.


@Florian Blume: Oui, il est activé. Vous pouvez confirmer en exécutant l'application. C'est peut-être un comportement par défaut.


C'est bizarre. Vous devriez avoir besoin d'un nœud multi-échantillons mais Qt3DWindow n'en ajoute pas. Essayez peut-être de définir votre propre format (voir le code de la fenêtre sur GitHub comment faire).


@FlorianBlume: Vous parlez de l'implémentation de QWindow ? En fait, j'ai essayé de définir le format, mais il n'y a eu aucun effet après tout. Mais le réglage de setStereo (true) a désactivé l'anti-aliasing. Je viens de publier cette solution de travail en guise de réponse.


3 Réponses :


2
votes

Consultez la documentation Qt pour multisampleantialiasing Il y a un exemple de code ici.

MODIFIER: addendum

QML Scene3D a la propriété suivante

multi-échantillon: booléen

true si un tampon de rendu multi-échantillons est demandé. Par défaut le multi-échantillonnage est activé. Si l'implémentation OpenGL n'a pas de support pour les tampons de rendu multi-échantillons ou les tampons de framebuffer, la demande d'utilisation le multi-échantillonnage est ignoré. Remarque: évitez de modifier la valeur fréquemment car cela implique des coûts coûteux et potentiellement lents initialisation des framebuffers et autres ressources OpenGL.

Mais il n'y a pas d'équivalent de Scene3D pour le monde C ++ ... La plupart des classes QML ont un équivalent pour C ++ en ajoutant un "Q" devant le nom. Mais il n'y a pas de QScene3D.

Remarque sur l'utilisation de Qt3DExtras :: Qt3DWindow

Qt3DWindow est dérivé de QWindow et a été créé pour avoir des solutions sans l'utilisation de QWidgets. Vous pouvez en savoir plus sur les détails dans cet article

Si vous souhaitez ajouter des boutons, des curseurs, ets ... dans une étape de test ultérieure, je vous conseillerais d'utiliser QML. Vous obtiendrez plus de flexibilité de Qt3D par rapport à l'utilisation de C ++ uniquement. Il est même possible de mélanger C ++ et QML: vous pouvez créer votre logique en C ++ et vous inscrire pour une utilisation en QML. Ainsi, vous obtenez le meilleur des deux mondes. C'est ce que je ferais si je voulais tester à fond les capacités de Qt3D.

Bon codage!


0 commentaires

1
votes

Le code suivant désactive l'anti-aliasing, mais ce n'est certainement pas la bonne façon de le faire. Mais, après tout, je suis arrivé à une solution de travail. Le réglage de setStereo (true) dans le QSurfaceFormat a désactivé l'anti-aliasing par magie.

#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();
}


0 commentaires

1
votes

Si quelqu'un tombe sur ceci, comment activer / désactiver l'antialisage dans Qt3D est de définir le nombre d'échantillons sur le format de surface:

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

Ceci doit se produire avant de configurer Qt3D.

NB: Ceci est lorsque vous souhaitez désactiver / activer l'anticrénelage dans une scène Qt3D par défaut, c'est-à-dire où vous ne rendez pas texture, puis utilisez-le dans un shader. Si vous voulez faire ce dernier, consultez QMultiSampleAntiAliasing.


0 commentaires