Qt 3D Render-Portierung auf RHI

Zur Erinnerung: In Qt 6 wird Qt 3D standardmäßig das RHI-Rendering-Backend verwenden.

Die Verwendung des älteren OpenGL-Backends aus der Qt 5-Serie ist weiterhin möglich. Dies kann durch Setzen der Umgebungsvariablen QT3D_RENDERER auf opengl aktiviert werden. Dies ist erforderlich, wenn Sie Ihre Anwendung nicht für die Unterstützung von RHI portieren möchten oder wenn Sie Funktionen benötigen, die derzeit im RHI-Backend nur eingeschränkt oder gar nicht verfügbar sind.

Die derzeit bekannten RHI-Einschränkungen sind:

  • Keine Möglichkeit, explizit zu blitten (Sie müssen manuell blitten, indem Sie ein Quad in einen Framebuffer rendern)
  • MemoryBarrier kann nicht explizit eingestellt werden
  • Nicht alle Texturformate sind verfügbar
  • Draw Indirect wird derzeit nicht unterstützt
  • Geometry Shader werden derzeit nicht unterstützt.
  • Verschiedene RHI Backends können unterschiedliche Features unterstützen.

Bitte verwechseln Sie nicht das Qt 3D OpenGL Rendering Backend mit dem Qt 3D RHI Rendering Backend, das auf OpenGL aufbaut.

RHI ist eine Abstraktion über verschiedene Grafik-APIs. Das bedeutet, dass auf einer bestimmten Plattform mehrere RHI mehrere Backends verwenden können.

Um RHI zu zwingen, ein bestimmtes Backend zu verwenden, sollte die Umgebungsvariable QSG_RHI_BACKEND auf einen der Werte opengl, vulkan, metal oder directx gesetzt werden.

Hinzufügen RHI-kompatibler Techniken

Um RHI-Unterstützung zu einem Qt 3D Material/Effekt hinzuzufügen, wird eine neue Technik benötigt, die auf RHI abzielt. Zum jetzigen Zeitpunkt ist die einzige gültige RHI Version 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);
}

Erstellen eines RHI kompatiblen Shaders

Unabhängig von dem Backend, auf dem RHI läuft, werden die Shader in GLSL 450 geschrieben.

Die Änderungen sind im Vergleich zu früheren GLSL-Versionen minimal, die wichtigsten Unterschiede liegen in der Art und Weise, wie Uniformen deklariert werden. Bitte beachten Sie auch, dass die Positionen von in- und out-Variablen definiert werden müssen und dass sie zwischen den Shader-Stufen konsistent sein sollten.

#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()
{
    ...
}

Weitere Details zu den Shader-Änderungen finden Sie unter Qt3DRender::QShaderProgram

Qt 3D Extras

Die Materialien in Qt 3D Extras wurden nach RHI portiert.

© 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.