Qt 3D 渲染移植到 RHI
作为提醒,在 Qt 6 中,Qt 3D 将默认使用其 RHI 渲染后端。
但仍可使用 Qt 5 系列中的旧版 OpenGL 后端。这可以通过将环境变量 QT3D_RENDERER 设置为 opengl 来启用。如果您不想移植应用程序以支持 RHI,或者您需要 RHI 后端目前受限或不可用的功能,就需要这样做。
目前,已知的 RHI 限制包括
- 无法显式混合(必须通过将四边形渲染到帧缓冲区来手动混合)
- MemoryBarrier 无法显式设置
- 并非所有纹理格式都可用
- 目前不支持间接绘制
- 目前不支持几何着色器。
- 不同的 RHI 后端可能支持不同的功能集。
此外,请注意不要将Qt 3D OpenGL 渲染后端与Qt 3D 在 OpenGL 上运行的 RHI 渲染后端混淆。
RHI 是对不同图形应用程序接口的抽象。这意味着在特定平台上,多个 RHI 可以使用多个后端。
要强制 RHI 使用给定的后端,应将 QSG_RHI_BACKEND 环境变量设置为 opengl、vulkan、metal、directx 之一。
添加 RHI 兼容技术
要在Qt 3D 材质/效果中添加 RHI 支持,需要一个针对 RHI 的新技术。截至目前,唯一有效的 RHI 版本是 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->setEffect(effect); { QTechnique *gl3Technique = new QTechnique(); QRenderPass *gl3Pass = new QRenderPass(); QShaderProgram *glShader = new 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(QGraphicsApiFilter::OpenGL); gl3Technique->graphicsApiFilter()->setMajorVersion(3); gl3Technique->graphicsApiFilter()->setMinorVersion(1); gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); // Add the technique to the effect effect->addTechnique(gl3Technique); } { QTechnique *rhiTechnique = new QTechnique(); QRenderPass *rhiPass = new QRenderPass(); QShaderProgram *rhiShader = new QShaderProgram(); // Set the shader on the render pass rhiPass->setShaderProgram(glShader); // Add the pass to the technique rhiTechnique->addRenderPass(rhiPass); // Set the targeted RHI version for the technique rhiTechnique->graphicsApiFilter()->setApi(QGraphicsApiFilter::RHI); rhiTechnique->graphicsApiFilter()->setMajorVersion(1); rhiTechnique->graphicsApiFilter()->setMinorVersion(0); rhiTechnique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile); // Add the technique to the effect effect->addTechnique(rhiTechnique); }
创建 RHI 兼容着色器
无论 RHI 将在哪个后端之上运行,着色器都将使用 GLSL 450 编写。
与早期的 GLSL 版本相比,变化微乎其微,主要的明显区别在于制服的声明方式。还请注意,需要定义 in 和 out 变量的位置,而且它们在各着色器阶段之间应保持一致。
#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() { ... }
有关着色器变化的更多详情,请查看Qt3DRender::QShaderProgram
Qt 3D 额外内容
Qt 3D Extras 中的材质已移植到 RHI。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.