c++ - 给定具有两个输出变量的顶点着色器,如何在 Qt3D 中正确定义两个 QRenderTargets 以获得深度和颜色信息
问题描述
我的公司使用 Qt3D 来显示其 CAD 图形。对于这个应用程序,有必要实现像素正确的顺序无关透明度。作为实现这一目标的第一步,我尝试编写一个小应用程序,它将一个简单的平面渲染到深度纹理和一个 rgba 纹理。
这是我的“小”示例应用程序:
主文件
#include <QApplication>
#include <Qt3DRender/QTechniqueFilter>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QParameter>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QTextureImage>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QTexture>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DExtras/QTextureMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QParameter>
#include <Qt3DRender/QRenderTarget>
#include <Qt3DRender/QRenderTargetOutput>
#include <Qt3DRender/QRenderTargetSelector>
#include <QDebug>
#include "TextureMaterial.h"
namespace {
Qt3DCore::QEntity* createPlane()
{
auto entity = new Qt3DCore::QEntity;
auto mesh = new Qt3DExtras::QPlaneMesh;
mesh->setWidth(0.3);
mesh->setHeight(0.3);
entity->addComponent(mesh);
return entity;
}
}
void main(int argc, char** args) {
QApplication app(argc, args);
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;
mMainViewport->setNormalizedRect(QRectF(0, 0, 1, 1));
mClearBuffers->setClearColor(Qt::lightGray);
mClearBuffers->setBuffers(Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer);
mClearBuffers->setParent(mMainCameraSelector);
mRenderSurfaceSelector->setParent(mMainViewport);
mMainCameraSelector->setParent(mRenderSurfaceSelector);
auto renderTargetSelector = new Qt3DRender::QRenderTargetSelector(mMainCameraSelector);
auto renderTarget = new Qt3DRender::QRenderTarget(renderTargetSelector);
{ // Depth Texture Output
auto depthTexture = new Qt3DRender::QTexture2D;
depthTexture->setSize(400, 300);
depthTexture->setFormat(Qt3DRender::QAbstractTexture::TextureFormat::DepthFormat);
auto renderTargetOutput = new Qt3DRender::QRenderTargetOutput;
renderTargetOutput->setAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint::Depth);
renderTargetOutput->setTexture(depthTexture);
renderTarget->addOutput(renderTargetOutput);
}
{// Image Texture Output
auto imageTexture = new Qt3DRender::QTexture2D;
imageTexture->setSize(400, 300);
imageTexture->setFormat(Qt3DRender::QAbstractTexture::TextureFormat::RGBA32F);
auto renderTargetOutput = new Qt3DRender::QRenderTargetOutput;
renderTargetOutput->setAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color1);
renderTargetOutput->setTexture(imageTexture);
renderTarget->addOutput(renderTargetOutput);
}
view->setActiveFrameGraph(mMainViewport);
view->activeFrameGraph()->dumpObjectTree();
auto rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
auto cameraEntity = view->camera();
cameraEntity->lens()->setPerspectiveProjection(45.0f, 1., 0.1f, 10000.0f);
cameraEntity->setPosition(QVector3D(0, 0.3, 0));
cameraEntity->setUpVector(QVector3D(0, 1, 0));
cameraEntity->setViewCenter(QVector3D(0, 0, 0));
{
auto mat = new TextureMaterial;
auto plane = createPlane();
plane->setParent(rootEntity);
auto trans = new Qt3DCore::QTransform;
//trans->setTranslation(QVector3D(0, -2, 0));
trans->setRotation(QQuaternion::fromAxisAndAngle({ 1,0,0 }, 80));
plane->addComponent(trans);
plane->addComponent(mat);
}
view->setWidth(400);
view->setHeight(300);
view->show();
app.exec();
}
纹理材料.h
#pragma once
#include <Qt3DRender/QMaterial>
namespace Qt3DRender {
class QTechnique;
class QRenderPass;
class QShaderProgram;
}
class TextureMaterial : public Qt3DRender::QMaterial
{
Q_OBJECT
public:
explicit TextureMaterial(Qt3DCore::QNode* parent = nullptr);
~TextureMaterial();
};
纹理材料.cpp
#include "TextureMaterial.h"
#include <Qt3DRender/QMaterial>
#include <Qt3DRender/QEffect>
#include <Qt3DRender/QTechnique>
#include <Qt3DRender/QShaderProgram>
#include <Qt3DRender/QParameter>
#include <Qt3DRender/QGraphicsApiFilter>
#include <Qt3DRender/QAbstractTexture>
#include <QUrl>
TextureMaterial::TextureMaterial(Qt3DCore::QNode* parent) : QMaterial(parent)
{
auto colorParm = new Qt3DRender::QParameter(QStringLiteral("diffuseColor"), QColor::fromRgbF(0.0,1.0,0.1,0.8)); // Green!!!
auto shaderProgram = new Qt3DRender::QShaderProgram;
shaderProgram->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shader.vert"))));
shaderProgram->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shader.frag"))));
auto technique = new Qt3DRender::QTechnique;
technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL);
technique->graphicsApiFilter()->setMajorVersion(3);
technique->graphicsApiFilter()->setMinorVersion(1);
technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
auto renderPass = new Qt3DRender::QRenderPass;
renderPass->setShaderProgram(shaderProgram);
technique->addRenderPass(renderPass);
auto effect = new Qt3DRender::QEffect;
effect->addTechnique(technique);
effect->addParameter(colorParm);
setEffect(effect);
}
TextureMaterial::~TextureMaterial()
{
}
着色器.frag
#version 150 core
uniform vec4 diffuseColor;
in vec3 position;
out vec4 blendedColor;
out float depth;
void main()
{
depth=gl_FragCoord.z;
blendedColor=diffuseColor;
}
着色器.vert
#version 150 core
in vec3 vertexPosition;
out vec3 position;
uniform mat4 modelView;
uniform mat4 mvp;
void main()
{
gl_Position = mvp * vec4( vertexPosition, 1.0 );
}
文件.qrc
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>shader.frag</file>
<file>shader.vert</file>
</qresource>
</RCC>
因为,片段着色器的所有输出都应该渲染到这两个纹理,我希望在我的Qt3dWindow
.
令人惊讶的是,有一些输出取决于我的片段着色器blendedColor
和depth
在我的片段着色器中的定义顺序。
如果首先定义深度,我会看到深度缓冲区,如果blendedColor
先定义,我会看到diffuseColor
.
这是我将看到的:
基本上,我有两个问题:
- 如果我的渲染目标是纹理,为什么我可以在查看器中看到
depth
and ?blendedColor
- 我如何检查纹理中渲染的内容
depthTexture
和imageTexture
?- 例如,有没有办法将这些纹理保存为图像?
解决方案
推荐阅读
- javascript - 用JS改变一个div的多个属性
- scala - 有没有合并两个 n 元组的好方法?
- tensorflow - 在导入 tensorflow 时需要帮助
- html - 如何隐藏标签外的“/”栏
- spring-boot - 如何在反应式、功能性(未注释)的 webflux 服务中实现 @RequestPart?
- google-app-engine - 对数据存储和云任务的初始请求具有更高的延迟,这正常吗?
- swift - iOS 13 今天扩展中的标签颜色
- javascript - 如何在特定 Div 上添加固定位置,然后在滚动时删除该类
- salesforce-lightning - 销售人员闪电 this.template.querySelector 不工作
- oracle-apex-19.1 - 应用程序 105 对话框页面 11 无法成功呈现