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);
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.