Qt 3D Render Porting to RHI▲
As a reminder, in Qt 6, Qt 3D will default to using it's RHI rendering backend.
Using the older OpenGL backend from the Qt 5 series remains possible. This can be enabled by setting environment variable QT3D_RENDERER to opengl. This is required in case you don't want to port your application to support RHI or in case you need features which are currently limited or not available on the RHI backend.
Currently, the known RHI limitations are:
-
No way to explicitly Blit (you have to blit manually by rendering a quad into a framebuffer)
-
MemoryBarrier cannot be set explicitly
-
Not all Texture Formats are available
-
Draw Indirect is currently not supported
-
Geometry Shaders are currently not supported.
-
Different RHI backends might support different feature set.
Please also take care not to confuse the Qt 3D OpenGL render backend with Qt 3D's RHI render backend running on top of OpenGL.
RHI is an abstraction over different graphics API. This means that on a given platform, several RHI could use several backends.
To force RHI to use a given backend, the QSG_RHI_BACKEND environment variable should be set to one of opengl, vulkan, metal, directx.
Add RHI Compatible Techniques▲
To add RHI support to a Qt 3D Material / Effect, a new Technique targeting RHI will be required. As of this writing, the only valid RHI version is 1.0.
Material {
Effect {
techniques
:
[
Technique {
id
:
gl3Technique
graphicsApiFilter {
api
:
GraphicsApiFilter.OpenGL
profile
:
GraphicsApiFilter.CoreProfile
majorVersion
:
3
minorVersion
:
1
}
renderPasses
:
RenderPass {
id
:
gl3Pass
shaderProgram
:
ShaderProgram {
...
}
}
}
,
Technique {
id
:
rhiTechnique
graphicsApiFilter {
api
:
GraphicsApiFilter.RHI
profile
:
GraphicsApiFilter.NoProfile
majorVersion
:
1
minorVersion
:
0
}
renderPasses
:
RenderPass {
id
:
rhiPass
shaderProgram
:
ShaderProgram {
...
}
}
}
]
}
}
QMaterial *
material =
new
QMaterial();
QEffect *
effect =
new
QEffect();
// Set the effect on the material
material-&
gt;setEffect(effect);
{
QTechnique *
gl3Technique =
new
QTechnique();
QRenderPass *
gl3Pass =
new
QRenderPass();
QShaderProgram *
glShader =
new
QShaderProgram();
// Set the shader on the render pass
gl3Pass-&
gt;setShaderProgram(glShader);
// Add the pass to the technique
gl3Technique-&
gt;addRenderPass(gl3Pass);
// Set the targeted GL version for the technique
gl3Technique-&
gt;graphicsApiFilter()-&
gt;setApi(QGraphicsApiFilter::
OpenGL);
gl3Technique-&
gt;graphicsApiFilter()-&
gt;setMajorVersion(3
);
gl3Technique-&
gt;graphicsApiFilter()-&
gt;setMinorVersion(1
);
gl3Technique-&
gt;graphicsApiFilter()-&
gt;setProfile(QGraphicsApiFilter::
CoreProfile);
// Add the technique to the effect
effect-&
gt;addTechnique(gl3Technique);
}
{
QTechnique *
rhiTechnique =
new
QTechnique();
QRenderPass *
rhiPass =
new
QRenderPass();
QShaderProgram *
rhiShader =
new
QShaderProgram();
// Set the shader on the render pass
rhiPass-&
gt;setShaderProgram(glShader);
// Add the pass to the technique
rhiTechnique-&
gt;addRenderPass(rhiPass);
// Set the targeted RHI version for the technique
rhiTechnique-&
gt;graphicsApiFilter()-&
gt;setApi(QGraphicsApiFilter::
RHI);
rhiTechnique-&
gt;graphicsApiFilter()-&
gt;setMajorVersion(1
);
rhiTechnique-&
gt;graphicsApiFilter()-&
gt;setMinorVersion(0
);
rhiTechnique-&
gt;graphicsApiFilter()-&
gt;setProfile(QGraphicsApiFilter::
NoProfile);
// Add the technique to the effect
effect-&
gt;addTechnique(rhiTechnique);
}
Creating a RHI compatible shader▲
Regardless on which backend RHI will be running on top of, the shaders will be written in GLSL 450.
Changes are minimal compared to earlier GLSL versions, the main noticeable differences are in the way uniforms are declared. Please also note that in and out variables need to have their locations defined and that they should be consistent between shader stages.
#version 450 core
layout(location =
0
) in vec3 vertexPosition;
layout(location =
0
) out vec3 worldPosition;
layout(std140, binding =
0
) uniform qt3d_render_view_uniforms {
mat4 viewMatrix;
mat4 projectionMatrix;
mat4 uncorrectedProjectionMatrix;
mat4 clipCorrectionMatrix;
mat4 viewProjectionMatrix;
mat4 inverseViewMatrix;
mat4 inverseProjectionMatrix;
mat4 inverseViewProjectionMatrix;
mat4 viewportMatrix;
mat4 inverseViewportMatrix;
vec4 textureTransformMatrix;
vec3 eyePosition;
float
aspectRatio;
float
gamma;
float
exposure;
float
time;
float
yUpInNDC;
float
yUpInFBO;
}
;
layout(std140, binding =
1
) uniform qt3d_command_uniforms {
mat4 modelMatrix;
mat4 inverseModelMatrix;
mat4 modelViewMatrix;
mat3 modelNormalMatrix;
mat4 inverseModelViewMatrix;
mat4 modelViewProjection;
mat4 inverseModelViewProjectionMatrix;
}
;
void
main()
{
...
}
For more details about shader changes, please checkout Qt3DRender::QShaderProgram
Qt 3D Extras▲
Materials in Qt 3D Extras have been ported to RHI.