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.的商标。所有其他商标均为其各自所有者的财产。