2

We are aiming to replace our previous 3D Engine with Qt3D. As a last obstacle we need to correctly implement a pixel correct transparency. We are now trying to implement depth peeling as a possible approach to make pixel correct transparency workable. For this algorithm one has to do perform a deferred (multipass) rendering, which can be achieved with QRenderPassFilter and QFilterKey inside an effect.

Now, I already had big problems to make the combination of QRenderPassFilter and QFilterKey together with the material QDiffuseSpecularMaterial going to work correctly. Even if there is just one pass.

This is my source code:

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QSortPolicy>
#include <Qt3DRender/QRenderSettings>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QDirectionalLight>
#include <Qt3DRender/QTexture>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QFilterKey>
#include <Qt3DRender/QParameter>
#include <Qt3DRender/QRenderPass>
#include <Qt3DRender/QRenderPassFilter>
#include <Qt3DRender/QTechnique>
#include <QDebug>

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

    auto view = new Qt3DExtras::Qt3DWindow();
    auto mClearBuffers = new Qt3DRender::QClearBuffers;
    auto mMainCameraSelector = new Qt3DRender::QCameraSelector;
    mMainCameraSelector->setCamera(view->camera());
    auto mRenderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
    auto mMainViewport = new Qt3DRender::QViewport;

    auto renderPassFilter = new Qt3DRender::QRenderPassFilter;
    {
        auto filterKey = new Qt3DRender::QFilterKey(renderPassFilter);
        filterKey->setName(QStringLiteral("renderingStyle"));
        filterKey->setValue(QStringLiteral("forward"));
        // Adding the filterKey to the renderPassFilter hides the plane
        // Name and Value of filterKey matches the FilterKey inside the QDiffuseSpecularMaterial
        renderPassFilter->addMatch(filterKey); // Removing this lines shows the plane mesh

        mClearBuffers->setClearColor(Qt::lightGray);
        mClearBuffers->setBuffers(Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer);
        mMainCameraSelector->setParent(mClearBuffers);
        mClearBuffers->setParent(renderPassFilter);
    }
    renderPassFilter->setParent(mRenderSurfaceSelector);

    mRenderSurfaceSelector->setParent(mMainViewport);

    view->setActiveFrameGraph(mMainViewport);
    view->activeFrameGraph()->dumpObjectTree();

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

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

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

    auto meshMaterial = new Qt3DExtras::QDiffuseSpecularMaterial;
    meshMaterial->setDiffuse(QColor("#ff00ff"));
    planeEntity->addComponent(meshMaterial);

    auto mesh = new Qt3DExtras::QPlaneMesh;
    mesh->setWidth(0.3);
    mesh->setHeight(0.3);
    planeEntity->addComponent(mesh);

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

    frame.show();
    return a.exec();
}

The console outputs my framegraph as:

Qt3DRender::QViewport::
    Qt3DRender::QRenderSurfaceSelector::
        Qt3DRender::QRenderPassFilter::
            Qt3DRender::QFilterKey::
            Qt3DRender::QClearBuffers::
                Qt3DRender::QCameraSelector::

Now, if I remove the line

renderPassFilter->addMatch(filterKey);

everything works as expected and I see my simple plane mesh.

However, adding the line, which should not filter anything the plane mesh is no longer displayed.

I'm really running out of ideas, what I'm possibly doing wrong here. How, can I make my small program with my renderPassFilter going to work and what are my errors?

I also didn't really understood, what are purposes of the settings name and value in the QFilterKey, which of both is necessary to filter out certain effects?

Aleph0
  • 5,816
  • 4
  • 29
  • 80

1 Answers1

2

After carefully studying my application and particularly the QDiffuseSpecularMaterial I figured out, that the QFilterKey inside the QDiffuseSpecularMaterial is not added to the QRenderPass Object, but moreover added to the QTechnique, which I found rather obscure.

Now, adding a QTechniqueFilter instead of a QRenderPassFilter made the program working as expected. Changing the string forward to something different e.g. xxx hides the plane as expected.

Adding the line

meshMaterial->dumpObjectTree();

indeed gave me the clue

Qt3DExtras::QDiffuseSpecularMaterial::
    Qt3DRender::QShaderProgramBuilder::
        Qt3DRender::QShaderProgram::
    Qt3DRender::QShaderProgramBuilder::
        Qt3DRender::QShaderProgram::
    Qt3DRender::QFilterKey::
    Qt3DRender::QEffect::
        Qt3DRender::QTechnique::
            Qt3DRender::QRenderPass::
                Qt3DRender::QNoDepthMask::
                Qt3DRender::QBlendEquationArguments::
                Qt3DRender::QBlendEquation::
        Qt3DRender::QTechnique::
            Qt3DRender::QRenderPass::
        Qt3DRender::QTechnique::
            Qt3DRender::QRenderPass::
        Qt3DRender::QParameter::
        Qt3DRender::QParameter::
        Qt3DRender::QParameter::
        Qt3DRender::QParameter::
        Qt3DRender::QParameter::

So dumpObjectTree() seems to a good of the shelf debugging tool, when dealing with Qt3D and Qt in general.

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QSortPolicy>
#include <Qt3DRender/QRenderSettings>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QTechniqueFilter>
#include <Qt3DRender/QDirectionalLight>
#include <Qt3DRender/QTexture>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QFilterKey>
#include <Qt3DRender/QParameter>
#include <Qt3DRender/QRenderPass>
#include <Qt3DRender/QRenderPassFilter>
#include <Qt3DRender/QTechnique>
#include <QDebug>

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

    auto view = new Qt3DExtras::Qt3DWindow();
    auto mClearBuffers = new Qt3DRender::QClearBuffers;
    auto mMainCameraSelector = new Qt3DRender::QCameraSelector;
    mMainCameraSelector->setCamera(view->camera());
    auto mRenderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
    auto mMainViewport = new Qt3DRender::QViewport;
    auto renderPassFilter = new Qt3DRender::QTechniqueFilter;
    {
        auto filterKey = new Qt3DRender::QFilterKey(renderPassFilter);
        filterKey->setName(QStringLiteral("renderingStyle"));
        filterKey->setValue(QStringLiteral("forward"));
        // Adding the filterKey to the renderPassFilter hides the plane
        // Name and Value of filterKey matches the FilterKey inside the QDiffuseSpecularMaterial
        renderPassFilter->addMatch(filterKey); // Removing this lines shows the plane mesh

        mClearBuffers->setClearColor(Qt::lightGray);
        mClearBuffers->setBuffers(Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer);
        mMainCameraSelector->setParent(mClearBuffers);
        mClearBuffers->setParent(renderPassFilter);
    }
    renderPassFilter->setParent(mRenderSurfaceSelector);

    mRenderSurfaceSelector->setParent(mMainViewport);

    view->setActiveFrameGraph(mMainViewport);
    view->activeFrameGraph()->dumpObjectTree();

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

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

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

    auto meshMaterial = new Qt3DExtras::QDiffuseSpecularMaterial;
    meshMaterial->setDiffuse(QColor("#ff00ff"));
    planeEntity->addComponent(meshMaterial);

    auto mesh = new Qt3DExtras::QPlaneMesh;
    mesh->setWidth(0.3);
    mesh->setHeight(0.3);
    planeEntity->addComponent(mesh);

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

    frame.show();
    return a.exec();
}
Aleph0
  • 5,816
  • 4
  • 29
  • 80