Qt Shader Tools 빌드 시스템 통합
셰이더를 컴파일하여 Qt 리소스에 추가합니다.
소개
Qt Shader Tools 모듈은 응용 프로그램이 CMakeLists.txt
에서 사용할 수 있는 유용한 함수를 제공하는 CMake 매크로 파일을 제공합니다.
qt6_add_shaders
함수를 사용하면 빌드 시스템에서 qsb 도구가 자동으로 호출되고 그 결과 .qsb
파일이 리소스 시스템에 암시적으로 추가됩니다.
첫 번째 예
간단한 예를 살펴보겠습니다. ShaderEffect 을 통해 자체적인 워블 효과를 제공하려는 Qt Quick 애플리케이션이 있다고 가정해 보겠습니다. 조각 셰이더는 wobble.frag
에서 구현됩니다. ShaderEffect 항목의 fragmentShader 속성은 wobble.frag.qsb
을 참조합니다. 빌드 시 이 .qsb 파일이 생성되도록 하려면 어떻게 해야 할까요?
... project(exampleapp LANGUAGES CXX) ... find_package(Qt6 COMPONENTS ShaderTools) ... qt6_add_executable(exampleapp main.cpp ) ... qt6_add_resources(exampleapp "exampleapp" PREFIX "/" FILES "main.qml" ) qt6_add_shaders(exampleapp "exampleapp_shaders" PREFIX "/" FILES "wobble.frag" )
위의 방법으로 애플리케이션이 런타임에 :/wobble.frag.qsb
에 액세스할 수 있습니다. 원본 Vulkan 스타일 GLSL 소스 코드(wobble.frag)는 애플리케이션의 실행 파일에 포함되어 있지 않으므로 제공하지 않아도 됩니다. 셰이더 코드에 오류가 있는 경우 빌드 시 glslang
컴파일러 메시지가 출력되고 빌드가 실패합니다. 셰이더 소스 파일을 변경하면 C++ 및 기타 소스 파일과 마찬가지로 다음 빌드에서 변경 사항이 자동으로 적용됩니다.
핵심은 qt6_add_shaders
함수로, qt6_add_resources
과 유사합니다. 이 함수는 추가 파라미터를 지정하지 않아도 Vulkan, Metal, Direct 3D, OpenGL 또는 OpenGL ES를 대상으로 할 때 조각 셰이더에 적합한 합리적인 기본 인수 세트를 사용하여 qsb를 실행합니다.
참고: find_package
줄을 주의하세요. ShaderTools
의 경우 find_package
을 포함해야 하며, 그렇지 않으면 qt6_add_shaders
을 사용할 수 없습니다.
참고: qt6_add_shaders
함수의 첫 번째 인수로 전달되는 대상은 함수가 호출되기 전에 존재해야 합니다.
참고: 여러 개의 qt6_add_shaders
호출이 지원됩니다. 복잡한 애플리케이션에서는 셰이더 세트마다 다른 설정이 필요할 수 있습니다. 프로젝트 뒤의 이름(위 예시에서는"exampleapp_shaders"
)은 각 호출마다 고유해야 합니다.
구성
기본적으로 qt6_add_shaders
은 다음과 같이 qsb를 호출합니다:
qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o <output>.qsb <input>
즉, 결과 패키지에는 SPIR-V(Vulkan 1.0용), GLSL ES 100(OpenGL ES 2.0 이상용), GLSL 120(비코어 프로파일 OpenGL 컨텍스트용), GLSL 150(코어 프로파일 OpenGL 컨텍스트용), 셰이더 모델 5.0용 HLSL 소스(Direct3D 11.1용) 및 Metal Shading Language 1.2 소스(Metal용)가 포함됩니다.
이는 Qt Quick 에 대한 좋은 기본값 세트이며 다양한 시스템으로 이식성이 높은 애플리케이션을 생성합니다. 하지만 이러한 기본값이 항상 적합한 것은 아닙니다. 셰이더가 이러한 대상에 해당하는 함수가 없는 함수나 구성을 사용하는 경우 프로세스와 빌드가 실패합니다. 이 경우 타깃을 조정해야 하며, 이는 애플리케이션의 최소 시스템 요구 사항이 암시적으로 조정된다는 의미이기도 합니다. 예를 들어 OpenGL ES 3.0 이상(즉, GLSL ES 300 이상)에서만 사용할 수 있는 textureLod
GLSL 함수를 예로 들어 보겠습니다. 100 es
대신 300 es
을 요청하면 빌드는 성공하지만 결과 애플리케이션에는 이제 OpenGL ES 3.0 이상이 필요하며 OpenGL ES 2.0 기반 시스템과 호환되지 않습니다.
셰이더 유형
셰이더 유형은 파일 확장자로부터 추론됩니다. 따라서 확장자는 다음 중 하나여야 합니다:
.vert
- 버텍스 셰이더의 경우.tesc
- 테셀레이션 제어 셰이더의 경우.tese
- 테셀레이션 평가 셰이더의 경우.frag
- 프래그먼트(픽셀) 셰이더의 경우.comp
- 컴퓨트 셰이더의 경우
참고: 테셀레이션 제어 및 평가 셰이더는 현재 Direct 3D(HLSL)에서 지원되지 않습니다. 이에 대한 가능한 해결 방법은 헐 및 도메인 셰이더를 수동으로 생성하고 FILES
섹션의 파일 대체 구문을 통해 셰이더를 주입하는 것입니다.
타겟
다음 키워드를 사용할 수 있습니다:
GLSL
- 주어진 GLSL 버전 목록에 대한 소스 코드 생성을 요청합니다. 목록이 쉼표로 구분된qsb
구문을 따르는지 주의하세요. 예를 들어 컴퓨팅 셰이더의 경우 기본값이 적합하지 않으므로 여기에"310 es,430"
을 지정하는 것이 좋습니다.NOGLSL
- 인수가 없는 이 키워드는 GLSL 소스 생성을 비활성화합니다. OpenGL을 전혀 사용하지 않으려는 애플리케이션에 적합합니다.HLSL
- 주어진 HLSL(셰이더 모델) 버전 목록에 대한 소스 코드 생성을 요청합니다.qsb
도구는 GLSL 스타일 버전 번호를 따르므로50
은 셰이더 모델 5.0,51
은 5.1에 해당합니다.NOHLSL
- 인수가 없는 이 키워드는 HLSL 소스 생성을 비활성화합니다. 다이렉트 3D를 전혀 사용하지 않으려는 애플리케이션에 적합합니다.MSL
- 지정된 버전의 메탈 셰이딩 언어에 대한 소스 코드 생성을 요청합니다.12
은 1.2,20
은 2.0에 해당합니다.NOMSL
- 인수가 없는 이 키워드는 MSL 소스 생성을 비활성화합니다. Metal을 전혀 사용하지 않으려는 애플리케이션에 적합합니다.
가장 일반적으로 재정의되는 설정은 GLSL
입니다. 예를 들어 애플리케이션의 셰이더가 OpenGL 3.x 기능을 사용하는 경우 100 es
또는 120
보다 높은 값을 지정해야 할 것입니다:
qt_add_shaders(exampleapp "res_gl3shaders" GLSL "300es,330" PREFIX "/shaders" FILES shaders/ssao.vert shaders/ssao.frag shaders/skybox.vert shaders/skybox.frag )
참고: es
접미사 앞의 공백은 선택 사항입니다.
테셀레이션
TESSELLATION
- 인수가 없는 이 키워드는 셰이더가 테셀레이션을 사용하는 파이프라인에서 사용됨을 나타냅니다. 버텍스 셰이더가 나열되어 있고 메탈 셰이더 생성이 비활성화되지 않은 경우에만 해당됩니다. 예제는 이 스니펫을 참조하십시오.이 옵션은 Qt 6.5에 도입되었습니다.
TESSELLATION_VERTEX_COUNT
- 이 옵션은 테셀레이션 제어 단계에서 출력 버텍스 수를 나타내는 숫자를 받습니다. Metal과 함께 사용되는 테셀레이션 평가 셰이더의 경우 이 옵션을 지정하는 것이 필수입니다. 기본값은 3입니다. 테셀레이션 제어 단계와 일치하지 않으면 생성된 MSL 코드가 예상대로 작동하지 않습니다.이 옵션은 Qt 6.5에 도입되었습니다.
TESSELLATION_MODE
- 이 옵션은 테셀레이션 모드를 지정합니다."triangles"
또는"quads"
두 값 중 하나를 사용할 수 있습니다. 기본값은triangles
입니다. 이 옵션은 테셀레이션 제어 셰이더가FILES
목록에 있을 때 지정해야 합니다. 테셀레이션 평가 단계와 일치해야 합니다.이 옵션은 Qt 6.5에 도입되었습니다.
멀티뷰
VIEW_COUNT
- 이 옵션은 버텍스 셰이더가 사용되는 뷰 수를 지정합니다. 멀티뷰(GL_OVR_multiview2, VK_KHR_multiview, D3D12 뷰 인스턴싱 등)로 작업할 때는 항상 관련 셰이더에 대해 2 이상의 값으로 올바른 VIEW_COUNT를 지정해야 올바른 GLSL 셰이더 코드를 생성할 수 있습니다. 단, 멀티뷰에 의존하지 않는 버텍스 셰이더의 경우 이 값을 설정하면 생성된 GLSL 코드가 멀티뷰에 종속되므로 뷰 카운트를 설정하지 않도록 주의해야 합니다. 이를 극복하려면 버텍스 셰이더를 적절히 그룹화하여 여러 번의 qt_add_shaders() 호출로 그룹화하세요.VIEW_COUNT
을 설정하면 셰이더 소스 코드에 동일한 값을 가진 전처리기 정의QSHADER_VIEW_COUNT
가 자동으로 삽입됩니다. 또한 뷰 수가 2 이상으로 설정되면 버텍스 셰이더에#extension GL_EXT_multiview : require
줄이 자동으로 삽입됩니다. 멀티뷰의 경우 최소 GLSL 버전은330
및300 es
입니다. HLSL의 경우 최소 버전은61
입니다. 애플리케이션은 그에 따라 언어 대상을 설정하거나 최신 버전으로 설정하는 것이 좋습니다.이 옵션은 Qt 6.7에 도입되었습니다.
MULTIVIEW
- 멀티뷰가 아닌 셰이더와 뷰 카운트 2 셰이더 세트를 모두 생성하는 요청. 이 옵션은 적절한 GLSL/HLSL/MSL/VIEW_COUNT 인수를 사용하여 두 개의 qt_add_shaders() 호출을 수동으로 생성할 때 편리합니다. 이 옵션은 주로 Qt 자체에서 사용하기 위한 것이지만, 응용 프로그램의 셰이더에 대한 멀티뷰 변형에 대한 암시적 설정이 충분하다면 응용 프로그램에서도 사용할 수 있습니다(예: 다음과 같습니다): GLSL 330,300es HLSL 61 MSL 12. 멀티뷰 변형의 경우 VIEW_COUNT가 2로 설정됩니다. 멀티뷰 배리언트는.mv2qsb
접미사가 추가된 파일에 저장됩니다(.qsb
외에).이 옵션은 Qt 6.8에 도입되었습니다.
Qt Quick 세부 사항
BATCHABLE
- 이 인수가 없는 단일 키워드를 지정하는 것은 ShaderEffect 또는 QSGMaterialShader 에서 Qt Quick 와 함께 사용되는 버텍스 셰이더에 필수적입니다. 이 키워드는 조각 또는 계산 셰이더에는 영향을 미치지 않으며,.vert
파일에만 고려되므로 다른 유형도 같은 목록에 안전하게 포함될 수 있습니다. qsb의-b
인수와 동일합니다.ZORDER_LOC
-BATCHABLE
을 지정하면 기본적으로7
위치에 추가 버텍스 입력이 주입됩니다. 이 키워드는 이 위치를 다른 값으로 변경하는 데 사용됩니다. 버텍스 셰이더에 많은 입력이 있고 7이 사용 중이어서 충돌할 수 있는 경우 이 키워드가 유용합니다.
외부 도구 호출
PRECOMPILE
- 플랫폼에 따라 qsb의-c
또는-t
옵션과 동일합니다. Windows에서 빌드하는 경우, Windows SDK에서fxc
을 호출하여 런타임이 아닌 빌드 시점에 컴파일의 첫 번째 단계(HLSL 소스를 DXBC 바이트코드로 변환)를 수행하게 됩니다. 결과물인.qsb
파일에는 원본 셰이더 소스 코드가 아닌 컴파일 결과(중간 셰이더 형식)만 포함됩니다.OPTIMIZED
-spirv-opt
(Vulkan SDK 또는 다른 곳에서 사용할 수 있어야 함)를 호출하여 SPIR-V 바이트코드에 대한 최적화를 수행합니다. qsb의-O
인수와 동일합니다.
기타 설정
DEFINES
- 셰이더 컴파일 중에 활성화되는 매크로를 정의합니다. qsb의-D
인수에 해당합니다. 목록의 형식은"name1=value1;name2=value2"
입니다. 또는FILES
과 마찬가지로 목록을 개행으로 구분할 수 있습니다.OUTPUTS
- 예를 들어 하나의 셰이더 파일이DEFINES
를 통해 차별화되어 여러 .qsb 파일의 소스 역할을 하기 때문에 생성된 .qsb 파일의 이름이 소스와 달라야 하는 경우 이 목록에 각 항목에 대한 항목을FILES
에 포함시켜 일반적으로.qsb
로 끝나는 파일 이름을 지정할 수 있습니다. 그러면 지정된 이름이 소스 파일 이름에.qsb
을 추가하는 대신-o
인수를 통해 qsb로 전달됩니다.DEBUGINFO
- SPIR-V에 대한 전체 디버그 정보를 생성할 수 있으므로 파이프라인을 검사하거나 버텍스 또는 조각 디버깅을 수행할 때 RenderDoc과 같은 툴이 전체 소스를 표시할 수 있습니다. qsb의-g
인수와 동일합니다.PRECOMPILE
키워드가 지정된 경우fxc
이 생성된 중간 바이트코드에 디버그 정보를 포함하도록 지시하므로 Direct 3D에도 영향을 미칩니다.QUIET
- qsb에서 디버그 및 경고 출력을 억제합니다. 치명적인 에러만 출력됩니다.OUTPUT_TARGETS
- 정적 라이브러리와 함께 qt_add_shaders를 사용하면 하나 이상의 특수 타겟이 생성됩니다. 이러한 타겟에 대해 추가 처리를 수행하려면 OUTPUT_TARGETS 파라미터에 값을 전달하세요.
수작업 셰이더 대체하기
CMake 통합은 결과 .qsb 파일에서 특정 버전의 셰이더에 대한 대체를 지정하는 기능도 지원합니다. 이는 사실상 -r
명령줄 옵션으로 qsb를 실행하는 것과 동일합니다.
이 기능은 FILES 목록에서 다음과 같은 특수 구문을 사용하여 활성화할 수 있습니다:
FILES "shaders/externalsampler.frag@glsl,100es,shaders/externalsampler_gles.frag"
파일 이름 뒤에는 @로 구분된 대체 사양이 얼마든지 올 수 있습니다. 이 각각은 쉼표로 구분된 셰이딩 언어, 버전 및 데이터를 읽을 파일을 지정합니다. 자세한 내용은 QSB 매뉴얼을 참조하세요.
테셀레이션 예제
셰이더 vertex.vert
를 사용하는 버텍스 단계, 셰이더 tess.tesc
를 사용하는 테셀레이션 제어 단계, 셰이더 tess.tese
를 사용하는 테셀레이션 평가 단계, 셰이더 fragment.frag
를 사용하는 조각 단계의 네 단계로 구성된 그래픽 파이프라인을 예로 들어 보겠습니다.
Vulkan, OpenGL, Metal 및 Direct 3D에서 작동할 수 있는 완전히 이식 가능한 애플리케이션을 구축하려면 두 가지 주요 사항을 고려해야 합니다: 테셀레이션 셰이더의 HLSL 버전은 수동으로 생성한 다음 주입해야 합니다. 반면 Metal의 경우 적절한 키워드를 지정해야 합니다.
먼저 버텍스 셰이더와 프래그먼트 셰이더가 나열됩니다. Metal을 지원하기 위해 TESSELLATION
키워드가 추가됩니다. 이렇게 하면 Metal 셰이더 코드를 생성할 때 vertex.vert
에 대한 특수 처리 및 변환이 가능합니다. OpenGL의 경우 테셀레이션 지원은 최신 OpenGL 버전에서만 가능하므로 GLSL 언어 버전으로 제한합니다.
qt6_add_shaders(project "shaders_tessellation_part1" PREFIX "/shaders" GLSL "410,320es" TESSELLATION FILES "vertex.vert" "fragment.frag" )
둘째, 테셀레이션 셰이더는 별도의 qt6_add_shaders() 호출에 나열됩니다. 이는 NOHLSL
키워드 때문입니다. 버텍스 및 프래그먼트 셰이더는 여전히 평소처럼 HLSL로 변환되어야 하므로 네 가지 셰이더를 모두 하나의 qt6_add_shaders() 호출에 유지하는 것은 가능하지 않습니다. Metal의 경우 일부 테셀레이션 설정(출력 버텍스 수, 모드)이 지정되는데, 이는 Vulkan 및 OpenGL과 달리 미리 알고 있어야 하기 때문입니다.
qt6_add_shaders(project "shaders_tessellation_part2" PREFIX "/shaders" NOHLSL GLSL "410,320es" TESSELLATION_VERTEX_COUNT 3 TESSELLATION_MODE "triangles" FILES "tess.tesc@hlsl,50,tess_hull.hlsl" "tess.tese@hlsl,50,tess_domain.hlsl" )
참고: 헐 및 도메인 HLSL 셰이더를 수동으로 작성하는 것은 고급 사용자에게만 권장됩니다. 상수 버퍼와 같은 특정 구조의 경우 모든 리소스 인터페이스 및 레이아웃이 SPIR-V/GLSL/MSL 셰이더와 호환성을 유지하도록 특별한 주의가 필요합니다.
© 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.