Qt 3D渲染迁移到RHI
提醒一下,在Qt 6中,Qt 3D将默认使用其RHI渲染后端。
仍可以使用Qt 5系列中的较旧OpenGL后端。这可以通过设置环境变量QT3D_RENDERER为opengl来启用。如果不想将应用程序迁移到支持RHI,或者需要当前在RHI后端受限制或不可用的功能,则需要进行此设置。
目前,已知的RHI限制包括:
- 没有明确Blit的方法(必须通过将四边形渲染到帧缓冲区中手动进行Blit)
- MemoryBarrier不能明确设置
- 并非所有纹理格式都可用
- 目前不支持Draw Indirect
- 目前不支持几何着色器
- 不同的RHI后端可能支持不同的功能集。
请注意,不要将Qt 3D OpenGL渲染后端与在OpenGL上运行的Qt 3D的RHI渲染后端混淆。
RHI是不同图形API的抽象。这意味着在某个平台上,多个RHI可以使用多个后端。
要强制RHI使用指定的后端,应该将QSG_RHI_BACKEND环境变量设置为opengl、vulkan、metal、directx中的一个。
添加RHI兼容技术
为了将RHI支持添加到Qt 3D材质/效果,需要一个新的针对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版本相比,变化很小,主要可观察的差别在于uniforms的声明方式。请注意,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附加组件中的材质已迁移到RHI。
© 2024 Qt公司有限公司。本文件中包含的文档贡献是各自所有者的版权。本文件中提供的文档是根据自由软件基金会发布的GNU自由文档许可证版本1.3的条款提供的。Qt和相应的标志是芬兰和/或其他国家的The Qt Company Ltd.的商标。所有其他商标均为其各自所有者的财产。