씬 그래프 - QML 기반 Vulkan
Qt Quick (QML) 장면 환경에서 Vulkan을 사용하여 직접 렌더링하는 방법을 보여줍니다.

참고: 이 예제를컴파일하려면 SDK가 필요합니다. 설치해야 할 항목에 대한 정보는 Vulkan 통합을 참조하십시오.
개요
이 예제는 QQuickWindow::beforeRendering() 및 QQuickWindow::beforeRenderPassRecording() 신호를 사용하여 Qt Quick 씬에서 사용자 정의 Vulkan 콘텐츠를 그립니다. QML을 사용하여 그 위에 텍스트 레이블을 렌더링합니다.
이 예제는 대부분의 측면에서 ‘QML 기반 OpenGL’, ‘QML 기반 Direct3D 11’ 및 ‘QML 기반 Metal’ 예제와 동일하며, 모두 서로 다른 네이티브 API를 통해 동일한 사용자 정의 콘텐츠를 렌더링합니다.
이 문서에서는 사용자 정의 Vulkan 렌더링의 세부 사항에 깊이 들어가지 않고, QML 활용 방법에 대해 다룰 것입니다.
QML에서 Vulkan 렌더링 제어하기
이 예제는 QML에 노출된 값을 사용하여 Vulkan 렌더링을 제어하는 방법을 보여줍니다.
임계값 t 을 QML에 노출하기 위해, ` VulkanSquircle`의 정의에서 다음과 같이 ` Q_OBJECT`, ` Q_PROPERTY` 및 ` QML_ELEMENT ` 매크로를 사용합니다.
class VulkanSquircle : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
QML_ELEMENT그런 다음 public 및 private 항목을 선언합니다:
public:
VulkanSquircle();
qreal t() const { return m_t; }
void setT(qreal t);
signals:
void tChanged();
public slots:
void sync();
void cleanup();
private slots:
void handleWindowChanged(QQuickWindow *win);
private:
void releaseResources() override;
qreal m_t = 0;
SquircleRenderer *m_renderer = nullptr;그런 다음 ` main.qml `에서 ` NumberAnimation`을 사용하여 임계값을 애니메이션 처리합니다.
VulkanSquircle {
SequentialAnimation on t {
NumberAnimation { to: 1; duration: 2500; easing.type: Easing.InQuad }
NumberAnimation { to: 0; duration: 2500; easing.type: Easing.OutQuad }
loops: Animation.Infinite이 t 변수는 궁극적으로 스퀴클을 그리는 SPIR-V 셰이더 프로그램에서 사용됩니다.
신호를 사용하여 사용자 정의 Vulkan 콘텐츠 렌더링하기
여기서는 QQuickWindow::beforeRendering() 및 QQuickWindow::beforeRenderPassRecording() 신호가 사용됩니다.
QQuickWindow::beforeRendering() 신호는 매 프레임의 시작 시점, 즉 씬 그래프가 렌더링을 시작하기 전에 발송됩니다. 이는 이 신호에 대한 응답으로 수행되는 모든 Vulkan 드로우 호출이 Qt Quick 항목 아래에 쌓인다는 것을 의미합니다. 사용자 정의 Vulkan 명령이 씬 그래프에서 사용하는 것과 동일한 명령 버퍼에 기록되기 때문에 두 개의 신호가 존재합니다.
beforeRendering() 함수만으로는 이 작업을 수행하기에 충분하지 않습니다. 이 함수는 프레임 시작 시, vkCmdBeginRenderPass를 사용하여 renderpass 인스턴스의 시작을 기록하기 전에 발생하기 때문입니다.
해결책: beforeRenderPassRecording()에 연결하면, 애플리케이션 자체의 명령과 씬 그래프의 보조 구조가 올바른 순서로 처리됩니다.
신호 연결은 ` sync() ` 함수를 통해 수행됩니다:
void VulkanSquircle::sync()
{
if (!m_renderer) {
m_renderer = new SquircleRenderer;
// Initializing resources is done before starting to record the
// renderpass, regardless of wanting an underlay or overlay.
connect(window(), &QQuickWindow::beforeRendering, m_renderer, &SquircleRenderer::frameStart, Qt::DirectConnection);
// Here we want an underlay and therefore connect to
// beforeRenderPassRecording. Changing to afterRenderPassRecording
// would render the squircle on top (overlay).
connect(window(), &QQuickWindow::beforeRenderPassRecording, m_renderer, &SquircleRenderer::mainPassRecordingStart, Qt::DirectConnection);
}
m_renderer->setViewportSize(window()->size() * window()->devicePixelRatio());
m_renderer->setT(m_t);Qt Quick 씬 위에 Vulkan 콘텐츠를 렌더링하는 또 다른 방법은 QQuickWindow::afterRendering() 및 QQuickWindow::afterRenderPassRecording() 신호에 연결하는 것입니다.
© 2026 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.