Hello,
        Yes, in our case, the objects are rendered in same viewport and camera 
with only difference being layer filters. I also tried setting the parent after 
creating the entity, it didn't work. 

        In our application, each sub entity already has separate parent with 
root entity being the grandparent of all, and the layer component is added to 
the parent entity. I tried all combinations of adding layer to entities, only 
the first filtered layer is properly pickable in all scenarios.

        As you suggested, I created a small example and in it, I have 
successfully reproduced this bug. I have attached the project in QTBUG-128299, 
and assigned it to you. But I will paste the code here for reference:

//main.cpp

#include <QGuiApplication>

#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>

#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QHBoxLayout>
#include <QtGui/QScreen>

#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/qpointlight.h>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QObjectPicker>
#include <Qt3DRender/QNoDraw>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QRenderStateSet>
#include <Qt3DRender/QLayerFilter>
#include <Qt3DRender/QDepthTest>
#include <Qt3DRender/QCullFace>
#include <Qt3DRender/QLayer>
#include <Qt3DRender/qcamera.h>
#include <Qt3DRender/qcameralens.h>

#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/qforwardrenderer.h>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/qt3dwindow.h>
#include <Qt3DExtras/qfirstpersoncameracontroller.h>

#include <QApplication>

int main(int argc, char *argv[])
{
    // I exclusively use opengl in my app but it has the same issue with QRhi.
    /*
    bool envvar = qputenv("QT3D_RENDERER", "opengl");
    qDebug() << "Opengl Environment variable set:" << envvar;

    QSurfaceFormat format = QSurfaceFormat::defaultFormat();
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setSamples(4);
    format.setVersion(3, 3);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);
    */
    QApplication app(argc, argv);
    Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
    view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));
    QWidget *container = QWidget::createWindowContainer(view);
    QSize screenSize = view->screen()->size();
    container->setMinimumSize(QSize(200, 100));
    container->setMaximumSize(screenSize);

    QWidget *widget = new QWidget;
    QHBoxLayout *hLayout = new QHBoxLayout(widget);
    QVBoxLayout *vLayout = new QVBoxLayout();
    vLayout->setAlignment(Qt::AlignTop);
    hLayout->addWidget(container, 1);
    hLayout->addLayout(vLayout);

    widget->setWindowTitle(QStringLiteral("QObjectPicker bug"));

    // Root entity
    Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();

    Qt3DRender::QCamera *cameraEntity = view->camera();

    cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 
1000.0f);
    cameraEntity->setPosition(QVector3D(0, 0, 20.0f));
    cameraEntity->setUpVector(QVector3D(0, 1, 0));
    cameraEntity->setViewCenter(QVector3D(0, 0, 0));

    Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
    light->setColor("white");
    light->setIntensity(1);
    lightEntity->addComponent(light);
    Qt3DCore::QTransform *lightTransform = new 
Qt3DCore::QTransform(lightEntity);
    lightTransform->setTranslation(cameraEntity->position());
    lightEntity->addComponent(lightTransform);

    Qt3DExtras::QFirstPersonCameraController *camController = new 
Qt3DExtras::QFirstPersonCameraController(rootEntity);
    camController->setCamera(cameraEntity);

    Qt3DRender::QLayer* opaqueLayer = new Qt3DRender::QLayer;
    opaqueLayer->setRecursive(true);
    opaqueLayer->setObjectName("Opaque Layer");

    Qt3DRender::QLayer* transparentLayer = new Qt3DRender::QLayer;
    transparentLayer->setRecursive(true);
    transparentLayer->setObjectName("Transparent Layer");

    // Framegraph starts here
    auto renderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
    renderSurfaceSelector->setSurface(view);

    Qt3DRender::QClearBuffers* clearBuffers = new 
Qt3DRender::QClearBuffers(renderSurfaceSelector);
    clearBuffers->setBuffers(Qt3DRender::QClearBuffers::AllBuffers);
    clearBuffers->setClearColor(Qt::gray);
    Qt3DRender::QNoDraw* noDraw = new Qt3DRender::QNoDraw(clearBuffers);

    Qt3DRender::QViewport* mainViewport = new 
Qt3DRender::QViewport(renderSurfaceSelector);
    mainViewport->setNormalizedRect(QRectF(0, 0, 1.0, 1.0));

    Qt3DRender::QCameraSelector* cameraSelector = new 
Qt3DRender::QCameraSelector(mainViewport);
    cameraSelector->setCamera(view->camera());

    Qt3DRender::QRenderStateSet* renderStateSet = new 
Qt3DRender::QRenderStateSet(cameraSelector);
    {
        Qt3DRender::QDepthTest* depthTest = new Qt3DRender::QDepthTest;
        depthTest->setDepthFunction(Qt3DRender::QDepthTest::LessOrEqual);
        renderStateSet->addRenderState(depthTest);

        Qt3DRender::QCullFace* cullFace = new 
Qt3DRender::QCullFace(renderStateSet);
        cullFace->setMode(Qt3DRender::QCullFace::NoCulling);
        renderStateSet->addRenderState(cullFace);
    }

    // Opaque branch - try reversing with layerFilterTransparent. Change order 
of both filters to reverse them.
    Qt3DRender::QLayerFilter* layerFilterOpaque = new 
Qt3DRender::QLayerFilter(renderStateSet);
    layerFilterOpaque->addLayer(opaqueLayer);

    // Transparent branch - try reversing with layerFilterOpaque
    Qt3DRender::QLayerFilter* layerFilterTransparent = new 
Qt3DRender::QLayerFilter(renderStateSet);
    layerFilterTransparent->addLayer(transparentLayer);

    view->setActiveFrameGraph(renderSurfaceSelector);
    view->setRootEntity(rootEntity);

    Qt3DCore::QEntity* redSphereEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QPhongMaterial* redSphereMaterial = new 
Qt3DExtras::QPhongMaterial();
    {
        Qt3DExtras::QSphereMesh* sphereMesh = new Qt3DExtras::QSphereMesh();
        sphereMesh->setRadius(3.0f);
        sphereMesh->setRings(10);
        Qt3DCore::QTransform* sphereTransform = new Qt3DCore::QTransform();
        sphereTransform->setTranslation(QVector3D(-10.0f, 0.0f, 0.0f));

        redSphereMaterial->setDiffuse(Qt::red);
        Qt3DRender::QObjectPicker* subEntitypicker = new 
Qt3DRender::QObjectPicker;
        QObject::connect(subEntitypicker, &Qt3DRender::QObjectPicker::clicked, 
[redSphereMaterial](){
            qDebug() << "Red Picked";
            if (redSphereMaterial->diffuse() == Qt::red)
            {
                redSphereMaterial->setDiffuse(Qt::yellow);
            }
            else
            {
                redSphereMaterial->setDiffuse(Qt::red);
            }
        });
        redSphereEntity->addComponent(sphereMesh);
        redSphereEntity->addComponent(sphereTransform);
        redSphereEntity->addComponent(subEntitypicker);
        redSphereEntity->addComponent(redSphereMaterial);
        redSphereEntity->addComponent(opaqueLayer);
    }

    Qt3DCore::QEntity* blueSphereEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QPhongMaterial* blueSphereMaterial = new 
Qt3DExtras::QPhongMaterial();
    {
        Qt3DExtras::QSphereMesh* sphereMesh = new Qt3DExtras::QSphereMesh();
        sphereMesh->setRadius(3.0f);
        sphereMesh->setRings(10);
        Qt3DCore::QTransform* sphereTransform = new Qt3DCore::QTransform();
        sphereTransform->setTranslation(QVector3D(10.0f, 0.0f, 0.0f));
        Qt3DRender::QObjectPicker* subEntitypicker = new 
Qt3DRender::QObjectPicker;
        blueSphereMaterial->setDiffuse(Qt::blue);
        QObject::connect(subEntitypicker, &Qt3DRender::QObjectPicker::clicked, 
[blueSphereMaterial](){
            qInfo() << "Blue Picked";
            if (blueSphereMaterial->diffuse() == Qt::blue)
            {
                blueSphereMaterial->setDiffuse(Qt::yellow);
            }
            else
            {
                blueSphereMaterial->setDiffuse(Qt::blue);
            }
        });
        blueSphereEntity->addComponent(sphereMesh);
        blueSphereEntity->addComponent(subEntitypicker);
        blueSphereEntity->addComponent(sphereTransform);
        blueSphereEntity->addComponent(blueSphereMaterial);
        blueSphereEntity->addComponent(transparentLayer);
    }

    qDebug() << "Try to click red and blue sphere. Red has first filtered layer 
as component and blue has second filtered layer as component";
    qDebug() << "When picked, spheres change color. You will notice blue cannot 
be picked as it has second filtered layer in framegraph";
    qDebug() << "You can try reversing the order of layer filter nodes in 
framegraph to see the other sphere picked";
    // Show window
    widget->show();
    widget->resize(1200, 800);

    return app.exec();
}

// End of main.cpp

#CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

project(sample_test LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS 3DCore 3DExtras 3DInput 3DRender Core Gui 
Widgets)


add_executable(sample_test
  main.cpp
)
target_link_libraries(sample_test
    Qt6::3DCore
    Qt6::3DExtras
    Qt6::3DInput
    Qt6::3DRender
    Qt6::Core
    Qt6::Gui
    Qt6::Widgets
)

include(GNUInstallDirs)
install(TARGETS sample_test
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

# End of CMakeLists.txt

        In this simple example, picking doesn't work for the transparentLayer, 
but it works for opaqueLayer. Hope to find a solution for this as using 
multiple QLayerFilters seems to be the only way to handle transparency 
correctly. If there is an alternative way to achieve perfect transparency(which 
is not possible in QSortPolicy), please let me know. Thanks.

Regards,
Sakthi
sakth...@vjcs.com

-----Original Message-----
From: Mike Krus [mailto:mike.k...@kdab.com] 
Sent: 22 August 2024 20:49
To: sakth...@vjcs.com
Cc: interest@qt-project.org
Subject: Re: [Interest] Qt3D - QObjectPicker doesn't work with multiple QLayers 
and QLayerFilters

Hi

the frame affects picking in a couple of ways:
- the layer filter, entities should only be pickable if the filter accepts the 
entities, otherwise they would be ignored
- the camera and viewport that are active in the branch (this affect the 
picking ray that gets tested)

I’m assuming in your case the only difference is the layer filter?

If seems like there may be an issue with the dynamic nature of your scene graph 
and 
Qt3D’s backend not being updated properly.

A few things to try:
- when creating new entities, create them without a parent, add the components 
and children, then set the parent
- if possible with your scene graph, maybe have separate parents for opaque and 
transparent entities (rather than
  mixing them under the same parent), and add the layer component to the parent 
entities rather then each entity
  (making sure you mark it as recursive).

I don’t think these should change the issue but might be something worth trying.

If you have a small example I can use to reproduce the issue, please create a 
bug report and assign it to me.


Mike


> On 22 Aug 2024, at 14:19, Sakthi G <sakth...@vjcs.com> wrote:
> 
> Hello, We have a Qt3D application where we have multiple QLayers for 
> different types of meshes. We have found out that QObjectPicker doesn’t work 
> properly with multiple QLayers. It doesn’t get triggered consistently if the 
> entity has layer component which is not filtered at the top of the framegraph.
>  Consider the following simplified framegraph with two layer filter branches, 
> one for opaque and one for transparent objects:
>    Qt3DRender::QViewport* mainViewport = new 
> Qt3DRender::QViewport(renderSurfaceSelector);
>         mainViewport->setNormalizedRect(QRectF(0, 0, 1.0, 1.0));
>          Qt3DRender::QCameraSelector* cameraSelector = new 
> Qt3DRender::QCameraSelector(mainViewport);
>         cameraSelector->setCamera(view->camera());
>          Qt3DRender::QRenderStateSet* renderStateSet = new 
> Qt3DRender::QRenderStateSet(cameraSelector);
>         {
>         Qt3DRender::QDepthTest* depthTest = new Qt3DRender::QDepthTest;
>         depthTest->setDepthFunction(Qt3DRender::QDepthTest::LessOrEqual);
>         renderStateSet->addRenderState(depthTest);
>          Qt3DRender::QCullFace* cullFace = new 
> Qt3DRender::QCullFace(renderStateSet);
>         cullFace->setMode(Qt3DRender::QCullFace::NoCulling);
>         renderStateSet->addRenderState(cullFace);
>   }
>   // Opaque branch
>         Qt3DRender::QLayerFilter* layerFilterOpaque = new 
> Qt3DRender::QLayerFilter(renderStateSet);
>         layerFilterOpaque->addLayer(opaqueLayer);
>         // Transparent branch
>         Qt3DRender::QLayerFilter* layerFilterTransparent = new 
> Qt3DRender::QLayerFilter(renderStateSet);
>         layerFilterTransparent->addLayer(transparentLayer);
>  When we dynamically add meshes to the scene, we check if the default 
> material is transparent and assign the respective layers like this:
>   if (transparent)
>         {
>             entity->addComponent(transparentLayer);               
>         }
>         else
>         {
>             entity->addComponent(opaqueLayer);               
>         }
>  After this, when we click on the dynamically added mesh, only entities with 
> opaqueLayer get triggered 100% of time, entities with transparentLayer gets 
> triggered inconsistently, and sometimes, it gets triggered if we click the 
> backface of the mesh. The hit ratio is around 20%.
>  If we swap the order of layer filters in framegraph, the transparentLayer 
> entities get triggered 100% of time and the opaqueLayer entities get 
> triggered inconsistently. So we think that it is the framegraph which is 
> causing this problem.  But if we modify a material and change the layers of 
> an existing entity(with opaqueLayer), QObjectPicker gets triggered all the 
> time. The following code demonstrates how we do that:
>  pickedEntity->addComponent(transparentLayer);
> pickedEntity->removeComponent(opaqueLayer);
> pickedEntity->setEnabled(false);
> pickedEntity->setEnabled(true);
>  Additionally, we also found that if the same scene with the above mentioned 
> framegraph only contains dynamically created entities with transparentLayer 
> as a component, QObjectPicker is not triggered at all.  How to fix this 
> issue? Why does it work if we modify the layer after creating it with 
> opaqueLayer, but not when adding dynamically while creating? Does 
> QObjectPicker depend on how we setup the framegraph? We couldn’t find any 
> documentation/code/forum posts linking QLayer/QLayerFilter with 
> QObjectPicker. Your help is truly appreciated.
>  Regards,
> Sakthi
> sakth...@vjcs.com
>  
> ********************************************************************************************************************************************************************
> This e-mail is confidential and is used for VJCS official communication.
> It may also be legally privileged. If you have received this message in 
> error, please delete all copies of it from your system and
> notify the sender by return e-mail. If you are not intended recipient, you 
> may not copy, print, forward,
> disclose or use any part of it. This message has been scanned for viruses and 
> dangerous content by VJCS Mail Scanner,
> and is believed to be clean.
> 
> Visit us at 
> http://secure-web.cisco.com/1gKXHHqznXVDZtWHSNdeBcbzfRW3ws2Ig6-B4Y15r23jAbzQM-yN-zaiKcJejW4T5NUCb1IBRBDfD0f1frDnPAqJFJROoh9dujbh3P1OAJ4scri8qEC6kZqI37jBEh0GXaLy0eo7NGkY57Tw2tNATID1WL-7dw7uvHGvLPpcU0HjWMnB0fabAlDLm7JPWEugUxoPjLO0Jb_GsNa0MsHetCYSnKpg-S8g4FJZntKTY3dntnc-723tdxD-LCA_YnH5LAopjw25qBZqMJR3li-FFEMdOmt4aKotUks9WgJ9raQxcs3xlPA-DwOVR3VjIAQ7_EifbxSjEp10UY6nzOtQ76utS0b1aDyoyAba9zB0OHhgCN_CL8FxddEUuOSmC_wxRw7QNcR9rk68VacwOHiDA6TjWNjC0W_0HolbMMkGi9_1L2CogGB-8wXBJ8Ay3xjh96dbQN9OOdqsU6UOcOPr85A/http%3A%2F%2Fwww.vjcs.com
> ********************************************************************************************************************************************************************
>  _______________________________________________
> Interest mailing list
> Interest@qt-project.org
> https://secure-web.cisco.com/1DWWEgJDY2stMfXDAHtDgQRIBR8Of7DjVPbJ_ASBzARmvTciTCgVaISHUggLHRTDlNFJ2IB0GJeAKNuv0z2W4g7vXeI5oGMcIa0pHj2DePwYOvMCt2UUpNgwZs3L7hG4pZuV5swDU-nN12eZSc42pSW9jRMJ9cdR2yNCagPXYINI3HKum_SdNrjhQOxbVHXiddr7khguH-HUlPCIJucoilQA9HCg3pM-iFecyUgcizXY0Nr9JM5eCuVlKW8T8dtAtUB8hyFklmLXq12HQTcpw6YJf_voNrU_Isc9A4IJCiqBMnpxJC82WonpU_2WHhNUZnnNOWSdwymJCEeIE6aSGlQX-4n367sr1-Csh4e23QmHZ5ITWzjup6oFRsX0cPBDcJaBIMytADVPcYlgZQJZJibaSTVfOMxn81MSPK9YB_yPiJIBvM30U4TntxzTWSAtJle_avlLnXCZgvHwV3xa-Ug/https%3A%2F%2Flists.qt-project.org%2Flistinfo%2Finterest


—
Mike Krus | mike.k...@kdab.com | Senior Software Engineer & Teamlead
KDAB (UK) Ltd., a KDAB Group company
Tel: UK Office +44 1625 809908   Mobile +44 7833 491941
KDAB - The Qt Experts, C++, OpenGL Experts


********************************************************************************************************************************************************************
This e-mail is confidential and is used for VJCS official communication.
It may also be legally privileged. If you have received this message in error, 
please delete all copies of it from your system and
notify the sender by return e-mail. If you are not intended recipient, you may 
not copy, print, forward,
disclose or use any part of it. This message has been scanned for viruses and 
dangerous content by VJCS Mail Scanner,
and is believed to be clean.

Visit us at www.vjcs.com
********************************************************************************************************************************************************************
_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to