c++transparentqt3dmaterials

Glass material in Qt3D C++ program?


I am writing a simulation program in C++ that renders a 3D scene in a QML Scene3D object from C++. It works well, but I would like to add almost transparent cone meshes to the scene.

I tried using Qt3DExtras::QDiffuseSpecularMaterial with low alpha values, but the result is not transparent enough. In fact using an alpha value of zero produces solid white objects.

    Qt3DExtras::QConeMesh *m_cone = new Qt3DExtras::QConeMesh(e);
    
    Qt3DExtras::QDiffuseSpecularMaterial *conemat = new Qt3DExtras::QDiffuseSpecularMaterial(e);
    QColor coneColor = QColor::fromRgbF(0,0.5,0,0);
    conemat->setDiffuse(coneColor);
    conemat->setAlphaBlendingEnabled(true);
 
    m_cone->setBottomRadius(1798444);
    m_cone->setTopRadius(0);
    m_cone->setLength(sat->orbitRadius()-EARTH_RADIUS);

What C++ material class and material parameters can I use to draw very faint transparent objects?

This seems easy in QML using shader fragments. How can one do this in C++?

        CustomMaterial {
            shadingMode: CustomMaterial.Shaded
            fragmentShader: "material_transparent.frag"
        }

Transparent.frag

void MAIN()
{
    vec2 size = vec2(textureSize(SCREEN_TEXTURE, 0));
    vec2 uv = FRAGCOORD.xy / size;

    vec3 view = normalize(VIEW_VECTOR);
    vec3 projection = view - view * normalize(NORMAL);
    vec3 refraction = projection * projection;
    uv += refraction.xy * 0.5;

    vec3 col = texture(SCREEN_TEXTURE, uv).rgb;
    col = col * 0.8 + vec3(0.2);

    BASE_COLOR = vec4(col, 1.0);
}

EDIT: karlphilip suggested I use a QEffect. I tried something based on the Qt documentation (I could not find any example of this). This is what I tried but the status of glShader is invariably "NotReady" at the end. I must be missing something. Any ideas?

    Qt3DRender::QEffect *effect = new Qt3DRender::QEffect();

    // Create technique, render pass and shader
    Qt3DRender::QTechnique *gl3Technique = new Qt3DRender::QTechnique();
    Qt3DRender::QRenderPass *gl3Pass = new Qt3DRender::QRenderPass();
    Qt3DRender::QShaderProgram *glShader = new Qt3DRender::QShaderProgram();

    // Set the shader on the render pass
    gl3Pass->setShaderProgram(glShader);

    // 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(1);
    gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile);

    // Add the technique to the effect
    effect->addTechnique(gl3Technique);

    QByteArray prog = glShader->loadSource(QUrl("qrc:/material_transparent.frag"));
    glShader->setFragmentShaderCode(prog);

Solution

  • When rendering QPhongAlphaMaterial with low alpha values in a QML Scene3D object, the documentation recommends setting the SourceAlphaArg and DestinationAlphaArg properties to specific values. Adding the following statements in the C++ program fixed the rendering issue:

    Qt3DExtras::QPhongAlphaMaterial *conemat = new Qt3DExtras::QPhongAlphaMaterial();
            
    mat->setSourceAlphaArg(Qt3DRender::QBlendEquationArguments::Zero);
    mat->setDestinationAlphaArg(Qt3DRender::QBlendEquationArguments::One);
    

    Now I'll need to figure out how to do this on a QDiffuseSpecularMaterial which doesn't have those properties.

    Cones of contant elevation angle rendered in a transparent material.