How to make color of a section be different on a 3D object

前端 未结 2 1262
时光取名叫无心
时光取名叫无心 2020-12-22 01:10

I have the following 3D object:

The material of my 3D object is coded like this with Qt3D:

void MyClass::addMaterial(Qt3DCore::QEntity *enti         


        
2条回答
  •  不知归路
    2020-12-22 01:27

    With the great help of @AdaRaider I managed to implement a custom effect with modifiable vertex shader and fragment shader. Custom effect can be used like this:

    #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);
    }
    

    Custom effect header is:

    #ifndef CUSTOMEFFECT_H
    #define CUSTOMEFFECT_H
    
    #include 
    
    class CustomEffect : public Qt3DRender::QEffect
    {
    public:
        explicit CustomEffect(Qt3DCore::QNode *parent = nullptr);
    };
    
    #endif // CUSTOMEFFECT_H
    

    The implementation of custom effect is with two versions of OpenGL in mind, OpenGL ES 2.0 and OpenGL 3.1:

    #include "customeffect.h"
    
    #include 
    #include 
    #include 
    
    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);
    }
    

    When I copy Phong shader default code inside my custom-shader.vert and custom-shader.frag files, it works exactly like Phong material, which shows the custom effect works fine.


    Now that the above custom effect is implemented, its shaders can be modified by the methods described by @AdaRaider to produce any desired effect.

提交回复
热议问题