我们的目标是用Qt3D取代以前的3D引擎。最后一个障碍是我们需要正确实现像素正确的透明度。现在,我们正在尝试实现深度剥离,以使像素正确的透明度可行。对于此算法,必须执行延迟(多遍)渲染,这可以通过效果内的QRenderPassFilter
和QFilterKey
实现。
现在,我已经遇到了很大的问题,无法将QRenderPassFilter
和QFilterKey
与 Material QDiffuseSpecularMaterial
组合在一起才能正常工作。即使只有一关。
这是我的源代码:
#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();
}
控制台将我的框架图输出为:
Qt3DRender::QViewport::
Qt3DRender::QRenderSurfaceSelector::
Qt3DRender::QRenderPassFilter::
Qt3DRender::QFilterKey::
Qt3DRender::QClearBuffers::
Qt3DRender::QCameraSelector::
现在,如果我删除线
renderPassFilter->addMatch(filterKey);
一切都按预期工作,我看到了简单的平面网格。
但是,添加线后,该线不应过滤平面网格不再显示的任何内容。
我的想法真的耗尽了,我在这里可能做错了什么。如何使
renderPassFilter
正常运行我的小程序,我有什么错误?我也不太了解,在
name
中设置value
和QFilterKey
的目的是什么,为了滤除某些效果,这两者是必需的吗? 最佳答案
在仔细研究了我的应用程序之后,尤其是我发现的QDiffuseSpecularMaterial
,我发现QDiffuseSpecularMaterial
内部的QFilterKey没有添加到QRenderPass
对象中,而是添加到了QTechnique
中,我发现它相当晦涩。
现在,添加QTechniqueFilter
而不是QRenderPassFilter
使程序按预期运行。将字符串forward
更改为其他内容,例如xxx
按预期隐藏了飞机。
添加线
meshMaterial->dumpObjectTree();
确实给了我线索
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()
似乎是一种很好的架子调试工具。#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();
}