QSB 매뉴얼
qsb
은 Qt Shader Tools 모듈에서 제공하는 명령줄 도구입니다. glslang 및 SPIRV-Cross와 같은 타사 라이브러리를 통합하고 fxc
또는 spirv-opt
과 같은 외부 도구를 선택적으로 호출하며 .qsb
파일을 생성합니다. 또한 .qsb
패키지의 내용을 검사하는 데 사용할 수도 있습니다.
Usage: qsb [options] file Qt Shader Baker (using QShader from Qt 6.8.0) Options: -?, -h, --help Displays help on commandline options. --help-all Displays help, including generic Qt options. -v, --version Displays version information. -b, --batchable Also generates rewritten vertex shader for Qt Quick scene graph batching. --zorder-loc <location> The extra vertex input location when rewriting for batching. Defaults to 7. --glsl <versions> Comma separated list of GLSL versions to generate. (for example, "100 es,120,330") --hlsl <versions> Comma separated list of HLSL (Shader Model) versions to generate. F.ex. 50 is 5.0, 51 is 5.1. --msl <versions> Comma separated list of Metal Shading Language versions to generate. F.ex. 12 is 1.2, 20 is 2.0. --qt6 Equivalent to --glsl "100 es,120,150" --hlsl 50 --msl 12. This set is commonly used with shaders for Qt Quick materials and effects. --msltess Indicates that a vertex shader is going to be used in a pipeline with tessellation. Mandatory for vertex shaders planned to be used with tessellation when targeting Metal (--msl). --tess-vertex-count <count> The output vertex count from the tessellation control stage. Mandatory for tessellation evaluation shaders planned to be used with Metal. The default value is 3. If it does not match the tess.control stage, the generated MSL code will not function as expected. --tess-mode <mode> The tessellation mode: triangles or quads. Mandatory for tessellation control shaders planned to be used with Metal. The default value is triangles. Isolines are not supported with Metal. If it does not match the tess.evaluation stage, the generated MSL code will not function as expected. --view-count <num_views> The number of views the shader is used with. num_views must be >= 2. Mandatory when multiview rendering is used (gl_ViewIndex). Set only for vertex shaders that really do rely on multiview (as the resulting asset is tied to num_views). Can be set for fragment shaders too, to get QSHADER_VIEW_COUNT auto-defined. (useful for ensuring uniform buffer layouts) -g Generate full debug info for SPIR-V and DXBC -O Invoke spirv-opt (external tool) to optimize SPIR-V for performance. -o, --output <filename> Output file for the shader pack. --qsbversion <version> QSB version to use for the output file. By default the latest version is automatically used, use only to bake compatibility versions. F.ex. 64 is Qt 6.4. -c, --fxc In combination with --hlsl invokes fxc (SM 5.0/5.1) or dxc (SM 6.0+) to store DXBC or DXIL instead of HLSL. -t, --metallib In combination with --msl builds a Metal library with xcrun metal(lib) and stores that instead of the source. Suitable only when targeting macOS, not iOS. -T, --metallib-ios In combination with --msl builds a Metal library with xcrun metal(lib) and stores that instead of the source. Suitable only when targeting iOS, not macOS. -D, --define <name[=value]> Define macro. This argument can be specified multiple times. -p, --per-target Enable per-target compilation. (instead of source->SPIRV->targets, do source->SPIRV->target separately for each target) -d, --dump Switches to dump mode. Input file is expected to be a shader pack. -x, --extract <what> Switches to extract mode. Input file is expected to be a shader pack. Result is written to the output specified by -o. Pass -b to choose the batchable variant. <what>=reflect|spirv,<version>|glsl,<version>|... -r, --replace <what> Switches to replace mode. Replaces the specified shader in the shader pack with the contents of a file. This argument can be specified multiple times. Pass -b to choose the batchable variant. Also supports adding a shader for a target/variant that was not present before. <what>=<target>,<filename> where <target>=spirv,<version>|glsl,<version>|... -e, --erase <what> Switches to erase mode. Removes the specified shader from the shader pack. Pass -b to choose the batchable variant. <what>=spirv,<version>|glsl,<version>|... -s, --silent Enables silent mode. Only fatal errors will be printed. --depfile <depfile> Enables generating the depfile for the input shaders, using the #include statements. Arguments: file Vulkan GLSL source file to compile. The file extension determines the shader stage, and can be one of .vert, .tesc, .tese, .frag, .comp. Note: Tessellation control/evaluation is not supported with HLSL, instead use -r to inject handcrafted hull/domain shaders. Some targets may need special arguments to be set, e.g. MSL tessellation will likely need --msltess, --tess-vertex-count, --tess-mode, depending on the stage.
작동 모드
작동 모드는 크게 다섯 가지입니다:
.qsb
파일 생성..qsb
파일 검사. 예를 들어qsb -d myshader.frag.qsb
은 리플렉션 메타데이터(JSON 형식)와 포함된 셰이더를 인쇄합니다.- 추출 모드. 기존
.qsb
파일에서 지정된 셰이더를 별도의 파일에 쓸 수 있습니다. 예를 들어qsb -x spirv,100 -o myshader.spv myshader.frag.qsb
은 SPIR-V 바이너리를myshader.spv
에 씁니다. - 바꾸기 모드.
.qsb
파일 내에 있는 하나 이상의 셰이더 콘텐츠를 지정된 파일에서 읽은 콘텐츠로 대체할 수 있습니다. 이렇게 하면 직접 만든 셰이더 코드를.qsb
패키지에 삽입할 수 있습니다. - 지우기 모드.
.qsb
파일에서 지정된 셰이더 배리언트를 제거합니다.
예제
다음 프래그먼트 셰이더를 예로 들어 보겠습니다:
#version 440 layout(location = 0) in vec2 v_texcoord; layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D tex; layout(std140, binding = 0) uniform buf { float uAlpha; }; void main() { vec4 c = texture(tex, v_texcoord); fragColor = vec4(c.rgb, uAlpha); }
qsb -o shader.frag.qsb shader.frag
을 실행하면 shader.frag.qsb
이 생성됩니다. qsb -d shader.frag.qsb
으로 이 파일을 검사하면 다음과 같습니다:
Stage: Fragment QSB_VERSION: 5 Has 1 shaders: Shader 0: SPIR-V 100 [Standard] Reflection info: { "combinedImageSamplers": [ { "binding": 1, "name": "tex", "set": 0, "type": "sampler2D" } ], "inputs": [ { "location": 0, "name": "v_texcoord", "type": "vec2" } ], "localSize": [ 0, 0, 0 ], "outputs": [ { "location": 0, "name": "fragColor", "type": "vec4" } ], "uniformBlocks": [ { "binding": 0, "blockName": "buf", "members": [ { "name": "uAlpha", "offset": 0, "size": 4, "type": "float" } ], "set": 0, "size": 4, "structName": "_27" } ] } Shader 0: SPIR-V 100 [Standard] Entry point: main Contents: Binary of 864 bytes
기본적으로 SPIR-V만 생성되므로 이 셰이더 패키지를 사용하는 애플리케이션은 Vulkan에서만 작동합니다. 더 유용하게 만들어 봅시다:
qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o shader.frag.qsb shader.frag
이 셰이더 패키지를 생성하면 OpenGL, Direct 3D 및 Metal에도 적합한 셰이더 패키지를 생성할 수 있습니다. 이 셰이더에 사용된 기능은 기본이며, 심지어 GLSL ES 100(OpenGL ES 2.0의 셰이딩 언어)도 적합합니다.
결과를 살펴보면 다음과 같습니다:
Stage: Fragment QSB_VERSION: 5 Has 6 shaders: Shader 0: GLSL 120 [Standard] Shader 1: HLSL 50 [Standard] Shader 2: GLSL 100 es [Standard] Shader 3: MSL 12 [Standard] Shader 4: SPIR-V 100 [Standard] Shader 5: GLSL 150 [Standard] Reflection info: { ... <same as above> } Shader 0: GLSL 120 [Standard] Entry point: main Contents: #version 120 struct buf { float uAlpha; }; uniform buf _27; uniform sampler2D tex; varying vec2 v_texcoord; void main() { vec4 c = texture2D(tex, v_texcoord); gl_FragData[0] = vec4(c.xyz, _27.uAlpha); } ************************************ Shader 1: HLSL 50 [Standard] Entry point: main Native resource binding map: 0 -> [0, -1] 1 -> [0, 0] Contents: cbuffer buf : register(b0) { float _27_uAlpha : packoffset(c0); }; Texture2D<float4> tex : register(t0); SamplerState _tex_sampler : register(s0); static float2 v_texcoord; static float4 fragColor; struct SPIRV_Cross_Input { float2 v_texcoord : TEXCOORD0; }; struct SPIRV_Cross_Output { float4 fragColor : SV_Target0; }; void frag_main() { float4 c = tex.Sample(_tex_sampler, v_texcoord); fragColor = float4(c.xyz, _27_uAlpha); } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { v_texcoord = stage_input.v_texcoord; frag_main(); SPIRV_Cross_Output stage_output; stage_output.fragColor = fragColor; return stage_output; } ************************************ ... Shader 3: MSL 12 [Standard] Entry point: main0 Native resource binding map: 0 -> [0, -1] 1 -> [0, 0] Contents: #include <metal_stdlib> #include <simd/simd.h> using namespace metal; struct buf { float uAlpha; }; struct main0_out { float4 fragColor [[color(0)]]; }; struct main0_in { float2 v_texcoord [[user(locn0)]]; }; fragment main0_out main0(main0_in in [[stage_in]], constant buf& _27 [[buffer(0)]], texture2d<float> tex [[texture(0)]], sampler texSmplr [[sampler(0)]]) { main0_out out = {}; float4 c = tex.sample(texSmplr, in.v_texcoord); out.fragColor = float4(c.xyz, _27.uAlpha); return out; } ************************************ ...
이 패키지는 이제 Qt Quick 에서 지원되는 모든 그래픽 API와 함께 사용할 수 있습니다: Vulkan, Direct 3D, Metal, OpenGL 및 OpenGL ES. 런타임에 적절한 셰이더는 Qt Quick 및 Qt Quick 3D 아래에 있는 Qt 렌더링 하드웨어 인터페이스에 의해 자동으로 선택됩니다.
이 시스템은 SPIR-V 바이트코드를 상위 레벨 소스 코드로 다시 변환하는 것 외에도 SPIR-V 바인딩 번호를 네이티브 리소스에 올바르게 매핑하는 등의 추가적인 문제도 처리합니다. 예를 들어 HLSL의 경우 위와 같은 섹션을 보았습니다:
Native resource binding map: 0 -> [0, -1] 1 -> [0, 0]
내부적으로 이를 통해 SPIR-V 스타일 바인딩 포인트 0
를 HLSL 등록 b0
에 매핑하고 1
를 t0
및 s0
에 바인딩할 수 있습니다. 이렇게 하면 렌더링 하드웨어 인터페이스 사용자에게 다양한 셰이딩 언어 간의 리소스 바인딩 차이를 투명하게 표시할 수 있으며, Qt의 모든 것이 원래 Vulkan 스타일 GLSL 소스 코드에 지정된 대로 Vulkan/SPIR-V 스타일 바인딩 포인트로 작동할 수 있습니다.
셰이더 유형
셰이더 유형은 입력 파일 확장자로부터 추론됩니다. 따라서 확장자는 다음 중 하나여야 합니다:
.vert
- 버텍스 셰이더의 경우.tesc
- 테셀레이션 제어 셰이더의 경우.tese
- 테셀레이션 평가 셰이더의 경우.frag
- 프래그먼트(픽셀) 셰이더의 경우.comp
- 컴퓨트 셰이더의 경우
참고: 테셀레이션 제어 및 평가 셰이더는 현재 Direct 3D(HLSL)에서 지원되지 않습니다.
셰이딩 언어 및 버전
SPIR-V 1.0은 항상 생성됩니다. 추가로 생성되는 것은 명령줄 인수 --glsl
, --hlsl
, --msl
에 따라 달라집니다.
이러한 매개변수 뒤에는 모두 쉼표로 구분된 목록이옵니다. 이 목록에는 선택적 접미사(es
, GLSL ES를 나타냄)와 함께 GLSL 스타일 버전 번호가 포함되어야 합니다. 접미사와 버전 사이의 공백은 선택 사항입니다(공백이 없으면 인용하지 않아도 됩니다).
예를 들어 Qt Quick 의 내장 머티리얼( Image, Text, Rectangle 과 같은 셰이더 지원 항목)은 모두 --glsl "100 es,120,150" --hlsl 50 --msl 12
로 셰이더를 준비합니다. 따라서 OpenGL ES 2.0 이상, OpenGL 2.1 이상 및 버전 3.2 이상의 OpenGL 코어 프로파일 컨텍스트와 호환됩니다.
셰이더가 지정된 대상에 해당하는 함수가 없는 함수나 구성을 사용하는 경우 qsb
은 실패합니다. 이 경우 타깃을 조정해야 하며, 이는 애플리케이션의 최소 시스템 요구 사항이 암시적으로 조정된다는 의미이기도 합니다. 예를 들어 OpenGL ES 3.0 이상(즉, GLSL ES 300 이상)에서만 사용할 수 있는 textureLod
GLSL 함수를 예로 들어 보겠습니다. 100 es
대신 300 es
을 요청하면 qsb
은 성공하지만, 해당 .qsb
파일을 사용하는 애플리케이션은 이제 OpenGL ES 3.0 이상이 필요하며 OpenGL ES 2.0 기반 시스템과 호환되지 않습니다.
또 다른 명백한 예는 컴퓨팅 셰이더입니다. .comp
셰이더는 OpenGL ES 3.1 이상 및 OpenGL 4.3 이상에서만 컴퓨팅 셰이더를 사용할 수 있으므로 --glsl 310es,430
을 지정해야 합니다.
셰이더 모델 버전 또는 메탈 셰이딩 언어 버전에 대한 셰이더 모델 버전 조정은 드물게 필요할 것으로 예상됩니다. 일반적으로 셰이더 모델 5.0(--hlsl 50
) 및 MSL 1.2(--msl 12
)로 충분합니다.
Qt Quick 씬 그래프 일괄 처리
Qt Quick 씬 그래프의 렌더러는 지오메트리 일괄 처리를 지원하여 드로 콜 횟수를 줄입니다. 자세한 내용은 씬 그래프 페이지를 참조하십시오. 이는 버텍스 셰이더의 main() 함수에 코드를 주입하는 데 의존합니다. Qt 5.x에서는 런타임에 제공된 GLSL 버텍스 셰이더 코드를 수정하여 이 작업을 수행했습니다. Qt 6에서는 이것이 옵션이 아닙니다. 대신 qsb
도구를 사용하여 버텍스 셰이더의 배치 가능한 변형을 빌드할 수 있습니다. 이는 -b
인수를 통해 요청됩니다. 입력이 .vert
확장자를 가진 버텍스 셰이더가 아닌 경우 아무런 영향을 미치지 않습니다. 그러나 버텍스 셰이더의 경우 각 대상에 대해 두 가지 버전을 생성하게 됩니다. Qt Quick 그러면 런타임에 적합한 변형(표준 또는 배치 가능)이 자동으로 선택됩니다.
참고: 애플리케이션은 일괄 처리의 세부 사항을 신경 쓸 필요가 없습니다. 버텍스 셰이더를 처리할 때 -b
(또는 CMake 통합을 사용하는 경우 동등한 BATCHABLE
키워드)가 지정되었는지 확인하기만 하면 됩니다. 이는 ShaderEffect 또는 QSGMaterialShader 와 함께 사용되는 Qt Quick 셰이더에만 해당됩니다.
다음 예제 버텍스 셰이더를 살펴보겠습니다:
#version 440 layout(location = 0) in vec4 position; layout(location = 1) in vec2 texcoord; layout(location = 0) out vec2 v_texcoord; layout(std140, binding = 0) uniform buf { mat4 mvp; } ubuf; void main() { v_texcoord = texcoord; gl_Position = ubuf.mvp * position; }
qsb -b --glsl 330 -o example.vert.qsb example.vert
을 실행하면 다음과 같이 연결됩니다:
Stage: Vertex QSB_VERSION: 5 Has 4 shaders: Shader 0: GLSL 330 [Standard] Shader 1: GLSL 330 [Batchable] Shader 2: SPIR-V 100 [Standard] Shader 3: SPIR-V 100 [Batchable] Reflection info: { ...
모든 대상 언어와 버전이 이제 두 가지 변형으로 존재한다는 점에 유의하세요: 표준과 약간 수정된 배치 가능.
외부 도구 호출
qsb
은 특정 외부 도구를 호출할 수 있습니다. 이러한 도구는 셰이더 바이트코드(SPIR-V)에서 최적화를 수행하는 도구와 소스에서 일부 중간 바이트코드 형식으로 셰이더 컴파일의 첫 번째 단계를 수행하는 플랫폼별 도구의 두 가지 범주로 나뉩니다.
이러한 기능은 다음 명령줄 옵션을 통해 활성화할 수 있습니다:
-O
- 는 SPIR-V 바이너리의 포스트 프로세싱 단계로spirv-opt
를 호출합니다..qsb
파일에는 최적화된 버전이 포함됩니다. 이는 시스템에서spirv-opt
을 사용할 수 있고(예: Vulkan SDK에서) 호출할 준비가 되어 있다고 가정합니다.-c
또는--fxc
- Direct 3D 셰이더 컴파일러인fxc.exe
을 호출합니다. 그 결과DXBC
(DirectX 바이트 코드) 데이터는 HLSL 대신.qsb
파일에 저장됩니다. Qt는 런타임에 이를 자동으로 선택하므로, 무엇을 포함할지, HLSL 소스 또는 중간 형식을 결정할지는.qsb
파일 작성자의 몫입니다. 가능하면 후자를 선호하면 런타임에 HLSL 소스를 파싱할 필요가 없으므로 그래픽 파이프라인 생성 시 잠재적으로 상당한 성능 향상을 가져올 수 있습니다. 단점은 이 인수는qsb
가 Windows에서 실행될 때만 사용할 수 있다는 것입니다.-t
또는--metallib
- 적절한 XCode Metal 툴을 호출하여 .metallib 파일을 생성하고 이를 MSL 소스 코드 대신.qsb
패키지에 포함합니다. 이 옵션은qsb
이 macOS에서 실행되는 경우에만 사용할 수 있습니다.
기타 옵션
-D
- 매크로를 정의합니다. 이를 통해 GLSL 소스 코드에서 #ifdef 등을 사용할 수 있습니다.-g
- SPIR-V에 대한 전체 디버그 정보를 생성하여 파이프라인을 검사하거나 버텍스 또는 프래그먼트 디버깅을 수행할 때 RenderDoc과 같은 툴이 전체 소스를 표시할 수 있도록 합니다.-c
을 지정하면fxc
이 생성된 중간 바이트코드에 디버그 정보를 포함하도록 지시하므로 Direct 3D 에도 효과가 있습니다.
테셀레이션
--msltess
- 버텍스 셰이더가 테셀레이션 스테이지가 포함된 파이프라인에서 사용됨을 나타냅니다. 다른 유형의 셰이더에는 영향을 미치지 않으며, MSL 셰이더 생성이 활성화되지 않은 경우에는 영향을 미치지 않습니다. 지정하지 않으면 버텍스 셰이더는 메탈에서 테셀레이션과 함께 작동하지 않습니다.--tess-vertex-count <count>
- 테셀레이션 제어 단계의 출력 버텍스 수를 지정합니다. Metal과 함께 사용되는 테셀레이션 평가 셰이더의 경우 이 옵션을 지정하는 것이 필수입니다. 기본값은 3입니다. 테셀레이션 제어 단계와 일치하지 않으면 생성된 MSL 코드가 예상대로 작동하지 않습니다.--tess-mode <mode>
- 이 옵션은 테셀레이션 모드를 지정합니다.triangles
또는quads
중 하나의 값을 사용할 수 있습니다. 기본값은triangles
입니다. Metal과 함께 사용되는 테셀레이션 제어 셰이더의 경우 이 옵션 지정은 필수입니다. 이 값은 테셀레이션 평가 단계와 일치해야 하며, 그렇지 않으면 생성된 MSL 코드가 예상대로 작동하지 않습니다.
멀티뷰
다음 버텍스 셰이더를 예로 들어 보겠습니다. 이 셰이더는 Vulkan 호환 GLSL로 작성되어 GL_EXT_multiview
확장을 사용하여 gl_ViewIndex
을 합법적으로 사용할 수 있습니다.
#version 440 #extension GL_EXT_multiview : require layout(location = 0) in vec4 pos; layout(std140, binding = 0) uniform buf { mat4 mvp[2]; }; void main() { gl_Position = mvp[gl_ViewIndex] * pos; }
참고: 실제로는 qsb
에 전달된 소스 코드에서 #extension GL_EXT_multiview 줄은 필요하지 않습니다. 아래에 설명된 --view-count
인수를 전달하면 SPIR-V로 컴파일하기 전에 셰이더 소스 코드에 해당 줄이 자동으로 삽입되기 때문입니다.
Vulkan의 경우 런타임에 Vulkan 1.1이 지원되는 한 이 방법은 그대로 작동합니다. 자세한 내용은 VK_KHR_multiview를 참조하십시오.
위의 Direct 3D 12용 HLSL 버텍스 셰이더를 생성하려면(자세한 내용은 뷰 인스턴싱 참조) 최소 셰이더 모델 버전은 6.1이며, 예를 들어 --hlsl 50
을 지정할 경우 qsb
은 실패합니다. 멀티뷰 버텍스 셰이더를 처리할 때는 --hlsl 61
이상을 사용하십시오. Direct 3D 11에서는 멀티뷰가 지원되지 않습니다.
OpenGL의 경우 추가 메타데이터가 필요합니다:
--view-count
- 위의 셰이더를 (SPIR-V로 컴파일한 후) OpenGL 호환 GLSL 소스 코드로 트랜스파일할 때gl_ViewIndex
을gl_ViewID_OVR
으로 매핑하는 것만으로는 충분하지 않으며 셰이더에 뷰 수 또한 선언해야 합니다.--view-count
인수에 2 값을 전달하면 생성된 GLSL 소스 코드에layout(num_views = 2) in;
문이 삽입되어 유효한 (OpenGL) GLSL 셰이더가 됩니다. 자세한 내용은 GL_OVR_multiview를 참조하고, 생성된 셰이더 소스 코드의#extension
지시문에 의해 요구되는 GL_OVR_multiview2도 런타임에 지원되어야 한다는 점에 유의하세요.
이러한 버텍스 셰이더로 OpenGL(ES)을 타겟팅하는 경우 생성된 GLSL 버전(--glsl
)이 330
또는 300 es
이상이어야 합니다. 전자는 qsb
또는 QShaderBaker 에서 강제하는 것은 아니지만, 실제로 OpenGL 구현은 GLSL 버전이 150 이하인 경우 이러한 셰이더를 거부하는 것으로 알려져 있습니다. 따라서 버텍스 셰이더를 컨디셔닝하여 GL_EXT_multiview를 활성화할 때는 --glsl 330,300es
을 전달하는 것이 좋습니다.
--view-count
을 지정하면 전처리기 정의( #define QSHADER_VIEW_COUNT n
)가 자동으로 생성되어 삽입되며, 여기서 n
은 뷰 수입니다. 뷰 수를 제공하지 않으면 정의가 전혀 설정되지 않습니다. 따라서 다음과 같은 코드를 작성할 수 있으며 모든 뷰 수별 셰이더 변형에 대해 동일한 소스 파일을 사용할 수 있습니다.
layout(std140, binding = 0) uniform buf { #if QSHADER_VIEW_COUNT >= 2 mat4 matrix[QSHADER_VIEW_COUNT]; #else mat4 matrix; #endif float opacity; };
또한 뷰 수가 2 이상으로 설정될 때마다 버텍스 셰이더에 #extension GL_EXT_multiview : require
줄이 자동으로 생성됩니다. 이렇게 하면 버텍스 셰이더에서 멀티뷰 지원을 위해 추가해야 하는 라인의 수가 줄어듭니다.
뷰 수를 설정하는 것은 다른 유형의 셰이더와도 관련이 있을 수 있습니다. 예를 들어 버텍스 셰이더와 프래그먼트 셰이더 간에 균일한 버퍼를 공유하고 두 셰이더 모두 동일한 버퍼 레이아웃을 보장해야 하는 경우 두 소스 파일에 #if QSHADER_VIEW_COUNT >= 2
을 작성할 수 있으면 유용할 수 있습니다. qsb
을 호출할 때 두 파일 모두에 --view-count
을 지정하면 이를 보장할 수 있습니다.
참고: 버텍스가 아닌 단계(예: 프래그먼트 셰이더)에서 gl_ViewIndex
키워드를 직접 사용하는 것은 현재로서는 이식성이 없으므로 피해야 합니다.
OpenGL 전용 GLSL 기능으로 작업하기
다른 셰이딩 언어, 중간 포맷 및 그래픽 API에는 적용되지 않는 OpenGL 및 GLSL 전용 셰이딩 언어 구성을 사용해야 할 때가 있습니다.
대표적인 예로 OpenGL ES의 외부 텍스처와 샘플러를 들 수 있습니다. 비디오 재생을 구현하거나 카메라 뷰파인더를 표시하려면 플랫폼에 따라 일반 2D 텍스처로 사용할 수 없는 OpenGL 텍스처 객체로 작업해야 할 수도 있지만, OpenGL API의 GL_TEXTURE_EXTERNAL_OES 바인딩 포인트와 셰이더의 samplerExternalOES
샘플러 유형을 통해 제한된 기능으로 사용할 수 있는 경우가 있습니다. 후자는 Qt의 SPIR-V 기반 셰이더 파이프라인을 사용할 때 잠재적인 쇼 스토퍼를 제공합니다. 이러한 셰이더를 qsb를 통해 실행하면 samplerExternalOES
이 SPIR-V 및 기타 타겟 셰이딩 언어에 매핑되지 않아 유효한 유형으로 인정되지 않기 때문에 실패하게 됩니다.
이 문제를 해결하기 위해 qsb는 .qsb 파일에 있는 특정 셰이더 변형의 내용을 파일에서 읽은 사용자 제공 데이터로 대체하여 원래 qsb에서 생성된 셰이더 소스 또는 바이트 코드를 완전히 대체하는 옵션을 제공합니다.
다음 조각 셰이더를 예로 들어 보겠습니다. tex
유형에 주목하세요. OpenGL ES로 실행할 때 samplerExternalOES
유형이 필요하다면 어떻게 해야 할까요?
#version 440 layout(location = 0) in vec2 texCoord; layout(location = 0) out vec4 fragColor; layout(std140, binding = 0) uniform buf { float opacity; } ubuf; layout(binding = 1) uniform sampler2D tex; void main() { fragColor = texture(tex, texCoord).rgba * ubuf.opacity; }
샘플러ExternalOES의 유형을 변경하는 것만으로는 불가능합니다. 그러면 바로 컴파일 오류가 발생합니다.
하지만 간단한 해결책이 있습니다. 별도의 순수 OpenGL ES 대상 셰이더 버전을 작성하여 .qsb 파일에 삽입하는 것입니다. 다음 셰이더는 GLGL ES와만 호환되며 qsb를 통해 실행할 수 없습니다. 그러나 런타임에 OpenGL ES에서 처리할 수 있다는 것을 알고 있습니다.
precision highp float; #extension GL_OES_EGL_image_external : require varying vec2 texCoord; struct buf { float opacity; }; uniform buf ubuf; uniform samplerExternalOES tex; void main() { gl_FragColor = texture2D(tex, texCoord).rgba * ubuf.opacity; }
이것을 shader_gles.frag
이라고 부르겠습니다. qsb --glsl 100es -o shader.frag.qsb shader.frag
이 완료되어 (반쯤 준비된) .qsb 파일을 제공하면 qsb -r glsl,100es,shader_gles.frag shader.frag.qsb
을 수행하여 지정된 파일(shader_gles.frag
)의 내용으로 GLSL 100 es용 셰이더를 대체하여 shader.frag.qsb
을 업데이트할 수 있습니다. 이제 shader.frag.qsb
은 런타임에 OpenGL ES와 함께 사용할 준비가 되었습니다.
참고: 셰이더와 애플리케이션 간의 인터페이스를 변경하지 않도록 주의하세요. -d
옵션을 통해 .qsb 파일 내용을 인쇄하거나 qsb -x glsl,100es -o gles_shader.frag shader.frag.qsb
을 실행하여 GLSL ES 100 셰이더를 추출하여 항상 qsb로 생성된 GLSL 코드를 먼저 검사합니다. 구조체, 구조체 멤버 및 유니폼 이름은 수동으로 주입한 버전과 다르지 않아야 합니다.
참고: 임의의 파일의 데이터를 .qsb 패키지에 배치하는 기능을 사용하여 직접 제작한 헐 및 도메인 HLSL 셰이더를 주입하여 테셀레이션 기반 그래픽스 파이프라인을 Direct 3D에서도 작동시킬 수 있습니다.
© 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.