QShaderBaker Class
GLSL/Vulkan 셰이더를 SPIR-V로 컴파일하고, 다른 셰이딩 언어로 번역하고, 리플렉션 메타데이터를 수집합니다. 더 보기...
Header: | #include <QShaderBaker> |
Since: | Qt 6.6 |
공용 유형
GeneratedShader | |
flags | SpirvOptions |
공용 함수
QShaderBaker() | |
~QShaderBaker() | |
QShader | bake() |
QString | errorMessage() const |
void | setBatchableVertexShaderExtraInputLocation(int location) |
void | setBreakOnShaderTranslationError(bool enable) |
void | setGeneratedShaderVariants(const QList<QShader::Variant> &v) |
void | setGeneratedShaders(const QList<QShaderBaker::GeneratedShader> &v) |
(since 6.7) void | setMultiViewCount(int count) |
void | setPerTargetCompilation(bool enable) |
void | setPreamble(const QByteArray &preamble) |
void | setSourceDevice(QIODevice *device, QShader::Stage stage, const QString &fileName = QString()) |
void | setSourceFileName(const QString &fileName) |
void | setSourceFileName(const QString &fileName, QShader::Stage stage) |
void | setSourceString(const QByteArray &sourceString, QShader::Stage stage, const QString &fileName = QString()) |
void | setTessellationMode(QShaderDescription::TessellationMode mode) |
void | setTessellationOutputVertexCount(int count) |
상세 설명
Warning: QShaderBaker는 QShader 및 QShaderDescription 를 포함한 Qt GUI 모듈의 QRhi 클래스 패밀리와 마찬가지로 제한된 호환성 보장을 제공합니다. 이러한 클래스에 대한 소스 또는 바이너리 호환성 보장은 없으므로 API는 애플리케이션이 개발된 Qt 버전에서만 작동하도록 보장됩니다. 그러나 소스와 호환되지 않는 변경은 최소한으로 유지하는 것을 목표로 하며 마이너 릴리스(6.7, 6.8 등)에서만 이루어질 것입니다. 애플리케이션에서 이 클래스를 사용하려면 Qt::ShaderToolsPrivate
(CMake를 사용하는 경우)에 링크하고 헤더에 rhi
접두사를 추가합니다(예: #include <rhi/qshaderbaker.h>
).
QShaderBaker는 그래픽(버텍스, 조각 등) 또는 계산 셰이더를 가져와 리플렉션 정보와 함께 소스 또는 바이트코드로 여러 개의 변형을 생성합니다. 결과는 QShader 인스턴스로 표시되며, 간단하고 빠른 직렬화 및 역직렬화 기능도 제공합니다.
참고: 애플리케이션과 라이브러리는 이 클래스를 직접 사용하지 않는 것이 좋습니다. 그 대신 모든 Qt 사용자는 빌드 시 CMake를 통해 qsb
명령줄 도구를 호출하여 오프라인 컴파일을 사용하는 것이 좋습니다. qsb
도구는 QShaderBaker를 사용하여 생성된 QShader 의 직렬화된 버전을 파일에 씁니다. 이 클래스의 사용은 사용자 제공 또는 동적으로 생성된 셰이더 소스 문자열로 작업할 때와 같이 런타임 컴파일을 피할 수 없는 경우에만 제한적으로 사용해야 합니다.
현재 입력 형식은 항상 Vulkan 맛 GLSL로 가정합니다. 개요는 GL_KHR_vulkan_glsl 사양을 참조하시고, Qt Shader Tools 모듈은 Qt 렌더링 하드웨어 인터페이스 모듈의 QRhi 클래스와 함께 사용하도록 되어 있으므로 현재 여러 개념과 구조체(푸시 상수, 스토리지 버퍼, 서브패스 등)가 적용되지 않는다는 점을 염두에 두시기 바랍니다. 향후 HLSL에서 SPIR-V로의 컴파일이 적합하다고 판단되면 소스 포맷으로 HLSL을 활성화하는 등의 추가 옵션이 도입될 수 있습니다.
리플렉션 메타데이터는 QShader::description()을 호출하여 결과물인 QShader 에서 검색할 수 있습니다. 이는 셰이더가 기대하는 버텍스 입력 및 셰이더 리소스 세트와 그 레이아웃을 파악해야 할 때 필수적인데, 많은 최신 그래픽 API에는 셰이더 리플렉션 기능이 내장되어 있지 않기 때문입니다.
일반적인 워크플로
애플리케이션에 다음과 같은 버텍스 및 프래그먼트 셰이더가 있다고 가정해 보겠습니다:
버텍스 셰이더:
#version 440 layout(location = 0) in vec4 position; layout(location = 1) in vec3 color; layout(location = 0) out vec3 v_color; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; }; void main() { v_color = color; gl_Position = mvp * position; }
프래그먼트 셰이더:
#version 440 layout(location = 0) in vec3 v_color; layout(location = 0) out vec4 fragColor; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; }; void main() { fragColor = vec4(v_color * opacity, opacity); }
QRhiGraphicsPipeline 에 그대로 전달할 수 있는 QShader 인스턴스를 얻으려면 셰이더 팩 생성을 오프라인으로 수행하거나 런타임에 수행하는 두 가지 옵션이 있습니다.
전자는 qsb
도구를 실행하는 것입니다:
qsb --glsl "100 es,120" --hlsl 50 --msl 12 color.vert -o color.vert.qsb qsb --glsl "100 es,120" --hlsl 50 --msl 12 color.frag -o color.frag.qsb
이 예제에서는 QRhi 에 적합한 번역 타깃을 사용합니다. 즉, GLSL/ES 100, GLSL 120, HLSL 셰이더 모델 5.0 및 금속 셰이딩 언어 1.2를 의미합니다.
명령줄 옵션이 setGeneratedShaders()를 통해 지정할 수 있는 것과 어떻게 일치하는지 참고하세요. 결과 파일을 사용할 수 있게 되면 애플리케이션과 함께 제공될 수 있으며(일반적으로 실행 파일에 포함됨), 런타임에 QShader::fromSerialized()로 로드하여 전달할 수 있습니다.
여기에는 표시되지 않았지만 qsb
는 더 많은 작업을 수행할 수 있습니다. Windows에서는 fxc
또는 macOS에서는 적절한 XCode 도구를 호출하여 생성된 HLSL 또는 Metal 셰이더 코드를 바이트코드로 컴파일하고 컴파일된 버전을 QShader 에 포함할 수 있습니다. 베이크된 셰이더 팩이 파일로 작성된 후에는 qsb -d
을 실행하여 그 내용을 검사할 수 있습니다. 자세한 내용은 --help
과 함께 qsb
을 실행하세요.
다른 방법은 런타임에 동일한 작업을 수행하는 것입니다. 여기에는 QShaderBaker 인스턴스를 생성하고 setSourceFileName()를 호출한 다음 setGeneratedShaders()를 통해 번역 대상을 설정하는 것이 포함됩니다:
baker.setGeneratedShaderVariants({ QShader::StandardShader }); QList<QShaderBaker::GeneratedShader> targets; targets.append({ QShader::SpirvShader, QShaderVersion(100) }); targets.append({ QShader::GlslShader, QShaderVersion(100, QShaderVersion::GlslEs) }); targets.append({ QShader::SpirvShader, QShaderVersion(120) }); targets.append({ QShader::HlslShader, QShaderVersion(50) }); targets.append({ QShader::MslShader, QShaderVersion(12) }); baker.setGeneratedShaders(targets); QShader shaders = baker.bake(); if (!shaders.isValid()) qWarning() << baker.errorMessage();
QShader 를참조하세요 .
멤버 함수 문서
QShaderBaker::QShaderBaker()
새로운 QShaderBaker를 생성합니다.
[noexcept]
QShaderBaker::~QShaderBaker()
파괴자.
QShader QShaderBaker::bake()
컴파일 및 번역 프로세스를 실행합니다.
QShader 인스턴스를 반환합니다. 프로세스가 성공했는지 확인하려면 QShader::isValid()를 호출합니다. false
로 표시되면 errorMessage()를 호출하여 로그를 검색합니다.
이 작업은 비용이 많이 드는 작업입니다. 애플리케이션에서 이 작업을 호출할 때는 별도의 스레드에서 수행하는 것이 좋습니다.
참고: QShaderBaker 인스턴스는 재사용이 가능합니다. bake() 호출 후 동일한 인스턴스를 다른 입력으로 다시 사용할 수 있습니다. 그러나 QShaderBaker 인스턴스는 수명 기간 동안 하나의 단일 스레드에서만 사용해야 합니다.
QString QShaderBaker::errorMessage() const
마지막 bake() 실행의 오류 메시지를 반환하거나 오류가 없는 경우 빈 문자열을 반환합니다.
참고: 오류에는 파일 읽기 오류, 컴파일 및 번역 실패가 포함됩니다. 결과 QShader 가 유효하지 않더라도 대상이나 변형을 요청하지 않은 것은 오류로 간주되지 않습니다.
void QShaderBaker::setBatchableVertexShaderExtraInputLocation(int location)
QShader::BatchableVertexShader 배리언트를 생성할 때 location 은 삽입된 버텍스 입력의 입력 위치를 지정합니다. 이 값은 기본적으로 7이며 버텍스 셰이더가 이미 입력 위치 7을 사용하는 경우에만 재정의해야 합니다.
void QShaderBaker::setBreakOnShaderTranslationError(bool enable)
셰이더 변환(SPIR-V에서 GLSL/HLSL/MSL로)이 실패할 때의 동작을 제어합니다. 기본적으로 이 설정은 true이며, 요청된 셰이더를 생성할 수 없는 경우 bake()가 오류와 함께 반환됩니다. 이를 원하지 않고 생성 가능한 것만 생성하고 나머지는 자동으로 건너뛰려는 의도라면 enable 을 false로 설정하세요.
여러 GLSL 버전을 타깃팅하면 특정 버전으로 번역할 수 없는 기능이 있을 때 오류가 발생할 수 있습니다. 예를 들어 textureSize()를 사용하여 셰이더를 GLSL ES 100으로 번역하려고 하면 "textureSize는 ESSL 100에서 지원되지 않습니다"라는 오류 메시지와 함께 전체 bake() 호출이 실패합니다. 요청되었음에도 불구하고 결과에 GLSL ES 100 셰이더가 없는 것이 허용되는 경우 이 플래그를 false로 설정하면 bake() 호출이 성공합니다.
void QShaderBaker::setGeneratedShaderVariants(const QList<QShader::Variant> &v)
어떤 셰이더 배리언트를 생성할지 지정합니다. 각 셰이더 버전은 결과물인 QShader 에 여러 개의 배리언트를 가질 수 있습니다.
대부분의 경우 v 에는 단일 항목인 QShader::StandardShader 이 포함됩니다.
참고: 배리언트가 설정되지 않은 경우 결과 QShader 는 비어 있으므로 유효하지 않습니다.
void QShaderBaker::setGeneratedShaders(const QList<QShaderBaker::GeneratedShader> &v)
컴파일 또는 번역할 셰이더의 종류를 지정합니다. 기본적으로 아무것도 생성되지 않으므로 bake() 앞에 이 함수를 호출해야 합니다.
참고: 이 함수가 호출되지 않거나 v 가 비어 있거나 유효하지 않은 항목만 포함된 경우, 결과 QShader 는 비어 있으므로 유효하지 않습니다.
예를 들어, 가능한 최소 베이킹 대상은 다른 언어에 대한 추가 번역 없이 SPIR-V입니다. 이를 요청하려면 이렇게 하세요:
baker.setGeneratedShaders({ QShader::SpirvShader, QShaderVersion(100) });
참고: QShaderBaker 은 SPIR-V 및 사람이 읽을 수 있는 소스 타깃만 처리합니다. QShader::DxbcShader 또는 QShader::MetalLibShader 같은 API별 중간 형식으로의 추가 컴파일은 qsb
명령줄 도구로 구현되며 QShaderBaker 런타임 API에 포함되지 않습니다.
[since 6.7]
void QShaderBaker::setMultiViewCount(int count)
멀티뷰를 사용하여 셰이더를 트랜스파일링할 때(예: GL_OVR_multiview2, VK_KHR_multiview 등에 의존하는 렌더러의 gl_ViewIndex를 사용하는 버텍스 셰이더) 일부 타깃의 경우 셰이더의 뷰 수를 선언해야 합니다. 이 작업은 Vulkan 스타일의 GLSL 코드에서는 수행되지 않으며, SPIR-V 또는 HLSL과 같은 타깃에는 관련이 없지만 OpenGL 및 GLSL에는 필요하므로 추가 메타데이터로 값을 제공해야 합니다.
기본값은 0으로, num_views
문 삽입을 비활성화합니다. 기본값은 num_views
이므로 1로 설정하는 것은 유용하지 않습니다. 따라서 count >= 2여야 효과를 발휘합니다. 예를 들어 2로 설정하면 생성된 GLSL 셰이더에 layout(num_views = 2) in;
문이 포함됩니다.
count 을 2 이상으로 설정하면 QSHADER_VIEW_COUNT
은 count 으로 설정되는 반면 GL_EXT_multiview
확장은 자동으로 활성화됩니다. 따라서 적절한 count 을 설정하는 것은 다른 유형의 셰이더와도 관련이 있습니다. 예를 들어 버텍스 셰이더와 프래그먼트 셰이더 간에 균일한 버퍼를 공유하고 두 셰이더가 #if QSHADER_VIEW_COUNT >= 2
과 같은 것을 작성할 수 있어야 하는 경우입니다.
이 함수는 Qt 6.7에 도입되었습니다.
void QShaderBaker::setPerTargetCompilation(bool enable)
타깃별 컴파일을 enable 으로 설정합니다. 기본적으로 이 옵션은 비활성화되어 있으므로 Vulkan/GLSL 소스는 배리언트당 한 번씩 SPIR-V로 컴파일됩니다. (따라서 기본적으로 한 번, 버텍스 셰이더인 경우 두 번, 요청에 따라 배치 가능 배리언트인 경우에도 두 번). 그런 다음 결과물인 SPIR-V는 다양한 타깃 언어(GLSL, HLSL, MSL)로 번역됩니다.
대상별 컴파일 모드에서는 각 대상, 즉 setGeneratedShaders()를 통해 요청된 각 GLSL/HLSL/MSL 버전에 대해 별도의 GLSL에서 SPIR-V로 컴파일하는 단계가 있습니다. 입력 소스는 동일하지만 타깃별 전처리기 정의가 삽입됩니다. 이 경우 시간이 훨씬 더 많이 걸리지만 애플리케이션이 단일 셰이더를 제공하고 #ifdef
블록을 사용하여 차별화할 수 있습니다. 이 모드를 비활성화하면 여러 버전의 셰이더 파일을 제공하고, 각각을 개별적으로 처리하고, 각각에 대해 {.qsb} 파일을 전송한 다음 런타임 로직에 따라 올바른 파일을 선택하는 방법밖에 없습니다.
이 모드에서는 다음 매크로가 자동으로 정의됩니다. 매크로는 항상 그래픽 API가 아닌 셰이딩 언어에 연결된다는 점에 유의하세요.
QSHADER_SPIRV
- SPIR-V를 타깃팅할 때 정의됩니다(일반적으로 Vulkan에서 사용됨).QSHADER_SPIRV_VERSION
- 예를 들어100
와 같이 타깃팅된 SPIR-V 버전 번호입니다.QSHADER_GLSL
- GLSL 또는 GLSL ES를 대상으로 할 때 정의됩니다(일반적으로 OpenGL 또는 OpenGL ES에서 사용됨).QSHADER_GLSL_VERSION
-100
,300
, 또는330
와 같이 타깃팅된 GLSL 또는 GLSL ES 버전 번호.QSHADER_GLSL_ES
- GLSL ES를 타깃팅할 때만 정의QSHADER_HLSL
- HLSL을 타깃팅할 때만 정의됩니다(일반적으로 Direct 3D에서 사용).QSHADER_HLSL_VERSION
- 타깃팅되는 HLSL 셰이더 모델 버전, 예를 들어50
QSHADER_MSL
- 메탈 셰이딩 언어 타깃팅 시 정의 (일반적으로 메탈에서 사용)QSHADER_MSL_VERSION
-12
또는20
과 같은 타깃 MSL 버전.
이를 통해 다음과 같은 셰이더 코드를 작성할 수 있습니다.
#if QSHADER_HLSL || QSHADER_MSL vec2 uv = vec2(uv_coord.x, 1.0 - uv_coord.y); #else vec2 uv = uv_coord; #endif
참고: 버전 번호는 GLSL에서 영감을 얻은 QShaderVersion 구문을 따르므로 항상 단일 정수입니다.
참고: 개별 타깃이 아무리 많아도 QShader 당 QShaderDescription 은 하나만 있습니다. 따라서 위에서 설명한 매크로를 사용하여 균일한 블록의 멤버, 버텍스 입력 등을 조건부로 만들어서는 안 됩니다.
경고: QShaderBaker 및 관련 도구는 셰이딩 언어의 개념으로만 작동하며, 이후 결과가 어떻게 소비되는지는 무시합니다. 따라서 언젠가 Qt 그래픽 스택의 상위 레이어가 벌칸이 아닌 다른 API에도 SPIR-V를 사용하기 시작하면 QSHADER_SPIRV가 벌칸을 의미한다는 가정은 더 이상 유지되지 않습니다.
void QShaderBaker::setPreamble(const QByteArray &preamble)
일반 셰이더 코드보다 먼저 처리되는 커스텀 preamble 을 지정합니다.
이는 단순히 소스 문자열 앞에 추가하는 것 이상의 의미를 갖습니다. 다른 모든 것 앞에 배치해야 하는 GLSL 버전 지시어의 유효성에는 영향을 미치지 않습니다. 보고된 오류 메시지의 줄 번호도 변경되지 않고 preamble 에 제공된 내용을 무시합니다.
프리앰블의 한 가지 사용 사례는 동적으로 생성된 #define
문을 투명하게 삽입하는 것입니다.
void QShaderBaker::setSourceDevice(QIODevice *device, QShader::Stage stage, const QString &fileName = QString())
소스를 설정합니다 device. QIODevice stage 은 셰이더 스테이지를 지정하고, fileName 은 오류 메시지에 사용되는 파일 이름을 포함하는 선택 사항입니다.
void QShaderBaker::setSourceFileName(const QString &fileName)
셰이더 소스 파일의 이름을 fileName 으로 설정합니다. bake()을 호출할 때 읽을 파일입니다. 셰이더 스테이지는 파일 확장자에서 자동으로 추론됩니다. 이를 원하지 않거나 불가능할 경우 대신 스테이지 인수와 함께 오버로드를 사용합니다.
지원되는 파일 확장자는 다음과 같습니다:
.vert
- 버텍스 셰이더.frag
- 프래그먼트(픽셀) 셰이더.tesc
- 테셀레이션 제어(헐) 셰이더.tese
- 테셀레이션 평가(도메인) 셰이더.geom
- 지오메트리 셰이더.comp
- 셰이더 계산
void QShaderBaker::setSourceFileName(const QString &fileName, QShader::Stage stage)
셰이더 소스 파일의 이름을 fileName 으로 설정합니다. 이 파일은 bake()을 호출할 때 읽을 파일입니다. 셰이더 스테이지는 stage 로 지정됩니다.
void QShaderBaker::setSourceString(const QByteArray &sourceString, QShader::Stage stage, const QString &fileName = QString())
입력 셰이더를 설정합니다 sourceString. stage 셰이더 스테이지를 지정하고, 선택 사항인 fileName 에는 오류 메시지에 사용되는 파일 이름이 포함됩니다.
void QShaderBaker::setTessellationMode(QShaderDescription::TessellationMode mode)
테셀레이션 제어 셰이더에 대한 MSL 셰이더 코드를 생성할 때 테셀레이션 mode (트라이앵글 또는 쿼드)을 미리 알고 있어야 합니다. GLSL에서는 일반적으로 테셀레이션 평가 셰이더에서 선언되지만 Metal의 경우 테셀레이션 제어 셰이더에서 계산 셰이더를 생성할 때도 이를 알아야 합니다.
설정하지 않으면 기본값은 트라이앵글입니다.
void QShaderBaker::setTessellationOutputVertexCount(int count)
테셀레이션 평가 셰이더에 대한 MSL 셰이더 코드를 생성할 때 테셀레이션 제어 셰이더의 출력 버텍스 count 를 미리 알아야 합니다. GLSL에서는 일반적으로 테셀레이션 제어 셰이더에서 선언되지만 Metal의 경우 테셀레이션 평가 셰이더에서 버텍스 셰이더를 생성할 때도 이 값을 알고 있어야 합니다.
설정하지 않으면 기본값은 3입니다.
© 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.