Qt 3D レンダリングの RHI への移植

注意点として、Qt 6 では Qt 3D はデフォルトで RHI レンダリングバックエンドを使用します。

Qt 5 シリーズの古い OpenGL バックエンドを使用することは可能です。これは環境変数 QT3D_RENDERER を opengl に設定することで有効になります。これは、RHIをサポートするようにアプリケーションを移植したくない場合や、RHIバックエンドで現在制限されているか利用できない機能が必要な場合に必要です。

現在、知られているRHIの制限は以下の通りです:

  • 明示的にBlitする方法がない(四角形をフレームバッファにレンダリングすることによって手動でBlitする必要があります)。
  • MemoryBarrier 明示的に設定できない
  • すべてのテクスチャフォーマットが利用できるわけではありません。
  • 間接描画は現在サポートされていません。
  • ジオメトリシェーダは現在サポートされていません。
  • 異なるRHIバックエンドは異なる機能セットをサポートするかもしれません。

また、Qt 3DのOpenGLレンダーバックエンドと、OpenGL上で動作するQt 3DのRHIレンダーバックエンドを混同しないように注意してください。

RHIは異なるグラフィックスAPIを抽象化したものです。つまり、あるプラットフォームでは、複数の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に移植されました。

©2024 The Qt Company Ltd. ここに含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。