首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >即使QFilterKey匹配,QRenderPassFilter也会隐藏平面网格

即使QFilterKey匹配,QRenderPassFilter也会隐藏平面网格
EN

Stack Overflow用户
提问于 2019-10-15 14:00:53
回答 1查看 99关注 0票数 2

我们的目标是用Qt3D取代以前的3D引擎。作为最后一个障碍,我们需要正确地实现像素正确的透明度。我们现在正在尝试实现深度剥离,作为一种可能的方法,使像素校正透明度可行。对于此算法,必须执行延迟(多通道)渲染,这可以在效果中使用QRenderPassFilterQFilterKey来实现。

现在,我已经遇到了很大的问题,使得QRenderPassFilterQFilterKey的组合以及material QDiffuseSpecularMaterial能够正常工作。即使只有一次传球。

这是我的源代码:

代码语言:javascript
复制
#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();
}

控制台将我的框架图输出为:

代码语言:javascript
复制
Qt3DRender::QViewport::
    Qt3DRender::QRenderSurfaceSelector::
        Qt3DRender::QRenderPassFilter::
            Qt3DRender::QFilterKey::
            Qt3DRender::QClearBuffers::
                Qt3DRender::QCameraSelector::

现在,如果我删除这行

代码语言:javascript
复制
renderPassFilter->addMatch(filterKey);

一切都像预期的一样,我看到了我的简单平面网格。

但是,添加不会过滤任何内容的直线平面网格将不再显示。

我真的没有想法了,我可能在这里做错了什么。如何让我的小程序与我的renderPassFilter一起工作,我的错误是什么?

我也不太明白,在QFilterKey中设置namevalue的目的是什么,哪两个是过滤某些效果所必需的?

EN

回答 1

Stack Overflow用户

发布于 2019-10-15 14:44:36

仔细研究了我的应用程序,特别是QDiffuseSpecularMaterial之后,我发现QDiffuseSpecularMaterial中的QFilterKey并没有添加到QRenderPass对象中,而是添加到了我觉得相当晦涩难懂的QTechnique中。

现在,添加QTechniqueFilter而不是QRenderPassFilter使程序按预期工作。将字符串forward更改为不同的值,例如xxx会按预期隐藏平面。

添加行

代码语言:javascript
复制
meshMaterial->dumpObjectTree();

确实给了我线索

代码语言:javascript
复制
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::

因此,在处理Qt3D和Qt时,dumpObjectTree()似乎是一个很好的工具。

代码语言:javascript
复制
#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();
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58388106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档