Qt3d: Artifacts of displaying when applied Qt3DRender::QLayerFilter
Asked Answered
S

2

4

I am trying to use layer filtering as shown in this answer. For this I wrote a simple test (see below). This is a continuation of the question.

At a certain position of the red sphere, an artifact appears, which looks like display from the another camera in coordinates (0.0, 0.0, 0.0).

See screen: enter image description here

In my example, the red sphere can be moved with the WSAD buttons. See (-7, 0, -14) red sphere position. How to remove these artifacts? The full test project can be viewed here.

main.cpp

int main(int argc, char *argv[])
{
    QGuiApplication application(argc, argv);
        My3DWindow window;

        auto sphere1 = new Qt3DCore::QEntity(window.Scene());
        auto sphere2 = new Qt3DCore::QEntity(window.Scene());

        // material, transform, mesh initialisation

        sphere1->addComponent(material1);
        sphere1->addComponent(spheremesh1);
        sphere1->addComponent(transform1);
        sphere1->addComponent(window.OpaqueLayer());

        sphere2->addComponent(material2);
        sphere2->addComponent(spheremesh2);
        sphere2->addComponent(transform2);
        sphere2->addComponent(window.TransparentLayer());

        window.show();
        return application.exec();
    }

My3DWindow class:

My3DWindow::My3DWindow(QScreen *screen):
    Qt3DExtras::Qt3DWindow(screen)
{
    m_Scene = new Qt3DCore::QEntity;
    setRootEntity(m_Scene);

    auto renderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector(m_Scene);
    renderSurfaceSelector->setSurface(this);
    auto clearBuffers = new Qt3DRender::QClearBuffers(renderSurfaceSelector);
    clearBuffers->setBuffers(Qt3DRender::QClearBuffers::AllBuffers);
    clearBuffers->setClearColor(Qt::gray);

    auto viewport = new Qt3DRender::QViewport(renderSurfaceSelector);
    auto cameraSelector = new Qt3DRender::QCameraSelector(viewport);

    m_Camera = new Qt3DRender::QCamera(cameraSelector);
    m_Camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
    m_Camera->setPosition(QVector3D(0.0f, 0.0f, 100.0f));
    m_Camera->setViewCenter(QVector3D(0.0f, 0.0f, 0.0f));

    cameraSelector->setCamera(m_Camera);

    auto cameraController = new Qt3DExtras::QFirstPersonCameraController(m_Scene);
    cameraController->setCamera(m_Camera);

    m_OpaqueLayer = new Qt3DRender::QLayer;
    auto opaqueFilter = new Qt3DRender::QLayerFilter(m_Camera);
    opaqueFilter->addLayer(m_OpaqueLayer);

    m_TransparentLayer = new Qt3DRender::QLayer;
    auto transparentFilter = new Qt3DRender::QLayerFilter(m_Camera);
    transparentFilter->addLayer(m_TransparentLayer);

    setActiveFrameGraph(renderSurfaceSelector);
}

Sommer answered 24/12, 2019 at 6:0 Comment(2)
I can't figure out if it's a bug or not. Created a bugreport, let's see.Sommer
Just a hint: you don't need to create a new camera and make it a child of cameraSelector. A QCamera is not a QFrameGraphNode, so it doesn't have to be part of the frame graph. You can use the default camera from your Qt3DWindow, and branch the filters directly from cameraSelector.Nathanaelnathanial
B
3

You can fix that by adding a QNoDraw node as a child of clearBuffers, as shown in this answer. The "artifact" is not caused by the layer filters, it is a problem of QClearBuffers itself.

Making clearBuffers a child of cameraSelector may seem to work on the surface, but what's actually happening is that everything is being rendered twice, so the transparent sphere will appear darker. You can verify this by commenting out either one of the filters: the objects in the corresponding layer will get rendered anyway.

By leaving clearBuffers as a child of renderSurfaceSelector and adding the QNoDraw, you don't get undesired stuff drawn on top of your viewport, and the filters behave as expected.

Benue answered 11/7, 2020 at 8:13 Comment(0)
S
0

Fixed. In the original example, an error found. I don't fully understand why it's the right thing to do:

auto clearBuffers = new Qt3DRender::QClearBuffers(cameraSelector);

insted

auto clearBuffers = new Qt3DRender::QClearBuffers(renderSurfaceSelector);
Sommer answered 1/1, 2020 at 16:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.