Qt 3D RHI로 렌더링 포팅

다시 한 번 말씀드리지만, Qt 6에서 Qt 3D 은 기본적으로 RHI 렌더링 백엔드를 사용합니다.

Qt 5 시리즈의 이전 OpenGL 백엔드를 계속 사용할 수 있습니다. 이는 환경 변수 QT3D_RENDERER를 opengl로 설정하여 활성화할 수 있습니다. 이는 애플리케이션을 RHI를 지원하도록 포팅하지 않으려는 경우 또는 현재 RHI 백엔드에서 제한되거나 사용할 수 없는 기능이 필요한 경우에 필요합니다.

현재 알려진 RHI 제한 사항은 다음과 같습니다:

  • 명시적으로 블릿할 수 없음(쿼드를 프레임버퍼에 렌더링하여 수동으로 블릿해야 함)
  • MemoryBarrier 명시적으로 설정할 수 없음
  • 모든 텍스처 포맷을 사용할 수 없음
  • 간접 그리기는 현재 지원되지 않습니다.
  • 지오메트리 셰이더는 현재 지원되지 않습니다.
  • RHI 백엔드마다 다른 기능 세트를 지원할 수 있습니다.

또한 Qt 3D 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 버전에 비해 변경 사항은 미미하며, 가장 눈에 띄는 차이점은 유니폼이 선언되는 방식에 있습니다. 또한 인/아웃 변수의 위치가 정의되어야 하며 셰이더 단계 간에 일관성이 있어야 한다는 점에 유의하세요.

#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 Extras

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.