Qt3d/C++ - 如何使用frameGraphe来实现大纲?

Qt3d/C++ - How to use frameGraphe to achive Outlines?

本文关键字:实现 frameGraphe 何使用 C++ Qt3d      更新时间:2023-10-16

我制作了简单的查看器,允许您导入.obj文件,我想要实现的是,当用户选择模型时,着色器将以不同的颜色绘制模型轮廓。

我用来表示.obj文件的是一个带有Custom QMaterial,Custom QPickerObject和QMesh的QEntity。

使用我的自定义QMaterial,我制作了简单的平面阴影(基于面部正常着色)

// My Custom QMaterial : 
explicit CustomizedMaterial(Qt3DCore::QNode *parent = nullptr) : QMaterial(parent)
{
// Create effect, technique, render pass and shader
Qt3DRender::QEffect *effect = new Qt3DRender::QEffect();
Qt3DRender::QTechnique *gl3Technique = new Qt3DRender::QTechnique();
Qt3DRender::QRenderPass *gl3Pass = new Qt3DRender::QRenderPass();
Qt3DRender::QShaderProgram *glShader = new Qt3DRender::QShaderProgram();
QByteArray ver(
"#version 330n"
"out vec3 vViewPos;n"
"in vec3 vertexPosition;n"
"in vec3 vertexNormal;n"
"uniform mat4 modelView;n"
"uniform mat3 modelViewNormal;n"
"uniform mat4 mvp;n"
"void main()n"
"{n"
"vec4 pos = vec4(vertexPosition, 1.0);n"
"vec4 mpos = modelView * pos;n"
"gl_Position = mvp * vec4(vertexPosition, 1.0);n"
"vViewPos = -mpos.xyz;n"
"}n");
QByteArray frag(
"#version 330n"
"vec3 normals(vec3 pos)n"
"{n"
"vec3 fdx = dFdx(pos);n"
"vec3 fdy = dFdy(pos);n"
"return normalize(cross(fdx, fdy));n"
"}n"
"in vec3 vViewPos;n"
"out vec4 fragColor;n"
"void main()n"
"{n"
"vec3 normal = normals(vViewPos);n"
"vec3 gray = vec3(0.9, 0.9, 0.9);n"
"float theta = dot(normal, vec3(0, 0, 1)) / length(normal);n"
"fragColor = vec4(gray * theta , 1.0);n"
"}n");
glShader->setVertexShaderCode(ver);
glShader->setFragmentShaderCode(frag);
// Set the shader on the render pass
gl3Pass->setShaderProgram(glShader);
// filter
Qt3DRender::QFilterKey *m_filterKey = new Qt3DRender::QFilterKey(this);
m_filterKey->setName(QStringLiteral("renderingStyle"));
m_filterKey->setValue(QStringLiteral("forward"));
// Add the pass to the technique
gl3Technique->addRenderPass(gl3Pass);
// Set the targeted GL version for the technique
gl3Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL);
gl3Technique->graphicsApiFilter()->setMajorVersion(3);
gl3Technique->graphicsApiFilter()->setMinorVersion(2);
gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
// Add filter
gl3Technique->addFilterKey(m_filterKey);
// Add the technique to the effect
effect->addTechnique(gl3Technique);
// Set the effect on the materials
setEffect(effect);
}

从我的搜索中,我认为最简单的方法是使用两种渲染传递技术,遗憾的是Qt3d/C++中没有文档或示例向我展示如何做到这一点,有人可以提供帮助吗?

提前谢谢。

是的,不幸的是,这方面的信息并不多。看起来Qt在QML上投入了更多的精力和资源,而不是C++/所有的例子都是5比1支持QML/。 好的,我设法使自定义着色器工作。我玩了你的代码,只改变了几个:

  1. 我在创建后立即移动了 QTechnique 的配置,并更改了技术的初始化顺序:

    gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);

    gl3Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL);

    gl3Technique->graphicsApiFilter()->setMajorVersion(3);

    gl3Technique->graphicsApiFilter()->setMinorVersion(1);

  2. 我把QFilterKey用于技术

    Qt3DRender::QFilterKey *filterkey = new Qt3DRender::QFilterKey(this);

    filterkey->setName(QStringLiteral("renderingStyle"));

    filterkey->setValue(QStringLiteral("forward"));

  3. 我从资源加载着色器的方式与示例 QML 代码所示相同:

    glShader->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/MyShader/simpleColor.vert"))));

    glShader->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/MyShader/simpleColor.frag"))));

我没有调查其中哪一个是主要原因,但正在起作用。

之后,我在这篇文章中找到了另一个确认 - 相同的处理方式

如何在 3D 对象上使截面的颜色不同 从@AdaRaider和@user3405291