Opengl 如何在3D对象上使截面颜色不同

Opengl 如何在3D对象上使截面颜色不同,opengl,qt3d,Opengl,Qt3d,我有以下3D对象: 我的3D对象的材质使用Qt3D编码如下: void MyClass::addMaterial(Qt3DCore::QEntity *entity) { Qt3DExtras::QPhongMaterial * material = new Qt3DExtras::QPhongMaterial(); material->setAmbient(QColor(245-30, 245-15, 245)); material->setDiffuse

我有以下3D对象:

我的3D对象的材质使用Qt3D编码如下:

void MyClass::addMaterial(Qt3DCore::QEntity *entity)
{
    Qt3DExtras::QPhongMaterial * material = new Qt3DExtras::QPhongMaterial();
    material->setAmbient(QColor(245-30, 245-15, 245));
    material->setDiffuse(QColor(125-30, 125-15, 125));
    material->setSpecular(QColor(215-30, 255-15, 255));
    entity->addComponent(material);
}
上述代码为三维对象实体提供了相同的颜色。如何为实体的不同部分赋予不同的颜色?我想突出显示我的3D对象上的某个部分,有没有办法用Qt3D来实现这一点

如果无法使用Qt3D,那么使用OpenGL的最佳实践是什么


我找到了一个我觉得非常有用的方法



在做了一些研究之后,最好的方法可能是使用OpenGL着色语言或GLSL。我不确定。

在Qt中,我想象他们使用“材质”作为预定义着色器的抽象。创建要渲染实体的材质(如QPhongMaterial),并为该材质设置将作为参数传递给着色器(制服)的内容,如环境光、镜面反射和漫反射照明颜色

因此,您需要一个支持模型顶点颜色的着色器。因此,模型的每个顶点都有一个与之关联的颜色,这些值将传递到顶点着色器并转发到片段着色器。使用OpenGL实现这一点非常简单,但您使用的是Qt3D,因此使用已有的基础设施可能更容易

Qt3D已经有一些材质类,您可以使用这些材质类创建一些着色器以应用于实体。您可以尝试改用QServerTexColorMaterial

Qt3DExtras::QServerTexColorMaterial的默认实现 渲染每个顶点的颜色属性集

显然,您需要提供顶点颜色列表,以便为模型的各个部分添加不同的颜色。除此之外,您还需要为每个顶点提供顶点颜色,即使您希望将三角形的每个顶点的颜色都设置为相同的颜色(面颜色)

或者,您可以创建自己的着色器并将其交给Qt3D以绑定到管道: (来自论坛)

Qt3D不会在运行时生成着色器。对于其默认管道,它附带预定义的默认着色器。但是你可以随意改变管道(C++和QML),也可以使用自己的着色器。 对于自定义材质,以下示例看起来很有希望:

有关Qt3D着色器的信息,请参见:

ShaderProgram类封装了一个着色器程序。着色器程序由多个不同的着色器组成,例如顶点着色器和片段着色器。 如果在着色器透视阶段遇到一组默认制服,Qt3D将自动填充这些制服

如果您从未在GLSL中编写着色器并在OpenGL程序中编译过着色器,您可能希望首先了解如何完成,因为您需要了解顶点、几何体和片段着色器所扮演的角色以及属性和制服的角色。我想你仍然可以不做那件事就完成这项工作,但我想这会非常困难

着色器上有很多页面,但只是简单地

着色器通常由三部分组成;顶点着色器、几何体着色器和片段着色器使用GLSL编写,通常保存为三个文件。至少要编译着色器,您需要顶点着色器源和片段着色器源

一般来说,人们喜欢用各自的扩展名保存这些文件,如.frag、.vert或.vs/.fs,但最终它们只是文本文件。 要编译着色器并将其绑定到渲染管道,需要从相应的文件加载源,并将它们链接到创建着色器程序,然后通过将其绑定到渲染管道并渲染几何体来使用该着色器程序。Lazy Foo有一个很棒的教程,介绍如何在OpenGL中实现这一点:

如果您只是使用OpenGL,则首先编写顶点着色器,然后编写具有正确输入/输出的片段着色器,以使用顶点颜色渲染几何体,然后通过该过程创建着色器程序

至于着色器实现本身,下面是顶点和片段着色器的快速实现:

顶点着色器(Color.vs)

片段着色器(Color.fs)


在@AdaRaider的大力帮助下,我使用可修改的顶点着色器和片段着色器实现了自定义的效果。自定义效果可以像这样使用:

#include "customeffect.h"

static const QColor ambientColor("#576675");  // Shader input
static const QColor diffuseColor("#5F6E7D");  // Shader input
static const QColor SpecularColor("#61707F"); // Shader input
static const float shininess(0.0);            // Shader input

void MyClass::addMaterial(Qt3DCore::QEntity *entity)
{
    Qt3DRender::QMaterial * material = new Qt3DRender::QMaterial();
    material->setEffect(new CustomEffect());
    material->addParameter(new Qt3DRender::QParameter(QStringLiteral("ka"), ambientColor));
    material->addParameter(new Qt3DRender::QParameter(QStringLiteral("kd"), diffuseColor));
    material->addParameter(new Qt3DRender::QParameter(QStringLiteral("ks"), SpecularColor));
    material->addParameter(new Qt3DRender::QParameter(QStringLiteral("shininess"), shininess));
    entity->addComponent(material);
}
自定义效果标题为:

#ifndef CUSTOMEFFECT_H
#define CUSTOMEFFECT_H

#include <Qt3DRender/QEffect>

class CustomEffect : public Qt3DRender::QEffect
{
public:
    explicit CustomEffect(Qt3DCore::QNode *parent = nullptr);
};

#endif // CUSTOMEFFECT_H
\ifndef CUSTOMEFFECT\u H
#定义自定义效果
#包括
类CustomEffect:public Qt3DRender::QEffect
{
公众:
显式CustomEffect(Qt3DCore::QNode*parent=nullptr);
};
#endif//CUSTOMEFFECT\u H
自定义效果的实现考虑了OpenGL的两个版本,即OpenGL ES2.0和OpenGL3.1

#include "customeffect.h"

#include <Qt3DRender/QTechnique>
#include <Qt3DRender/QGraphicsApiFilter>
#include <QtCore/QUrl>

CustomEffect::CustomEffect(Qt3DCore::QNode *parent)
    : Qt3DRender::QEffect(parent)
{

    Qt3DRender::QTechnique *techniqueES20 = new Qt3DRender::QTechnique();
    techniqueES20->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile);
    techniqueES20->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGLES);
    techniqueES20->graphicsApiFilter()->setMajorVersion(2);
    techniqueES20->graphicsApiFilter()->setMinorVersion(0);

    Qt3DRender::QTechnique *techniqueGL31 = new Qt3DRender::QTechnique();
    techniqueGL31->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
    techniqueGL31->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL);
    techniqueGL31->graphicsApiFilter()->setMajorVersion(3);
    techniqueGL31->graphicsApiFilter()->setMinorVersion(1);

    Qt3DRender::QFilterKey *filterkey = new Qt3DRender::QFilterKey(this);
    filterkey->setName(QStringLiteral("renderingStyle"));
    filterkey->setValue(QStringLiteral("forward"));

    techniqueES20->addFilterKey(filterkey);
    techniqueGL31->addFilterKey(filterkey);

    Qt3DRender::QShaderProgram *shader2 = new Qt3DRender::QShaderProgram();
    shader2->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/qt3deditorlib/shaders/es2/custom-shader.vert"))));
    shader2->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/qt3deditorlib/shaders/es2/custom-shader.frag"))));

    Qt3DRender::QShaderProgram *shader3 = new Qt3DRender::QShaderProgram();
    shader3->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/qt3deditorlib/shaders/gl3/custom-shader.vert"))));
    shader3->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/qt3deditorlib/shaders/gl3/custom-shader.frag"))));

    Qt3DRender::QRenderPass *renderPass2 = new Qt3DRender::QRenderPass();
    renderPass2->setShaderProgram(shader2);

    Qt3DRender::QRenderPass *renderPass3 = new Qt3DRender::QRenderPass();
    renderPass3->setShaderProgram(shader3);

    techniqueES20->addRenderPass(renderPass2);
    techniqueGL31->addRenderPass(renderPass3);

    addTechnique(techniqueES20);
    addTechnique(techniqueGL31);
}
#包括“customeffect.h”
#包括
#包括
#包括
CustomEffect::CustomEffect(Qt3DCore::QNode*父级)
:Qt3DRender::QEffect(父级)
{
Qt3DRender::QTechnique*techniques20=新的Qt3DRender::QTechnique();
techniqueES20->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile);
techniqueES20->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGLES);
techniqueES20->graphicsApiFilter()->setMajorVersion(2);
techniqueES20->graphicsApiFilter()->setMinorVersion(0);
Qt3DRender::QTechnique*techniqueGL31=新的Qt3DRender::QTechnique();
techniqueGL31->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
techniqueGL31->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL);
techniqueGL31->graphicsApiFilter()->setMajorVersion(3);
techniqueGL31->graphicsApiFilter()->setMinorVersion(1);
Qt3DRender::QFilterKey*filterkey=新的Qt3DRender::QFilterK
#ifndef CUSTOMEFFECT_H
#define CUSTOMEFFECT_H

#include <Qt3DRender/QEffect>

class CustomEffect : public Qt3DRender::QEffect
{
public:
    explicit CustomEffect(Qt3DCore::QNode *parent = nullptr);
};

#endif // CUSTOMEFFECT_H
#include "customeffect.h"

#include <Qt3DRender/QTechnique>
#include <Qt3DRender/QGraphicsApiFilter>
#include <QtCore/QUrl>

CustomEffect::CustomEffect(Qt3DCore::QNode *parent)
    : Qt3DRender::QEffect(parent)
{

    Qt3DRender::QTechnique *techniqueES20 = new Qt3DRender::QTechnique();
    techniqueES20->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile);
    techniqueES20->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGLES);
    techniqueES20->graphicsApiFilter()->setMajorVersion(2);
    techniqueES20->graphicsApiFilter()->setMinorVersion(0);

    Qt3DRender::QTechnique *techniqueGL31 = new Qt3DRender::QTechnique();
    techniqueGL31->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);
    techniqueGL31->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL);
    techniqueGL31->graphicsApiFilter()->setMajorVersion(3);
    techniqueGL31->graphicsApiFilter()->setMinorVersion(1);

    Qt3DRender::QFilterKey *filterkey = new Qt3DRender::QFilterKey(this);
    filterkey->setName(QStringLiteral("renderingStyle"));
    filterkey->setValue(QStringLiteral("forward"));

    techniqueES20->addFilterKey(filterkey);
    techniqueGL31->addFilterKey(filterkey);

    Qt3DRender::QShaderProgram *shader2 = new Qt3DRender::QShaderProgram();
    shader2->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/qt3deditorlib/shaders/es2/custom-shader.vert"))));
    shader2->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/qt3deditorlib/shaders/es2/custom-shader.frag"))));

    Qt3DRender::QShaderProgram *shader3 = new Qt3DRender::QShaderProgram();
    shader3->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/qt3deditorlib/shaders/gl3/custom-shader.vert"))));
    shader3->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/qt3deditorlib/shaders/gl3/custom-shader.frag"))));

    Qt3DRender::QRenderPass *renderPass2 = new Qt3DRender::QRenderPass();
    renderPass2->setShaderProgram(shader2);

    Qt3DRender::QRenderPass *renderPass3 = new Qt3DRender::QRenderPass();
    renderPass3->setShaderProgram(shader3);

    techniqueES20->addRenderPass(renderPass2);
    techniqueGL31->addRenderPass(renderPass3);

    addTechnique(techniqueES20);
    addTechnique(techniqueGL31);
}