Eine Vulkan-App muss Shader anders verwalten als eine OpenGL ES-App: In OpenGL ES stellen Sie einen Shader als eine Reihe von Zeichenfolgen bereit, die den Quelltext eines GLSL-Shader-Programm. Im Gegensatz dazu müssen Sie für die Vulkan API einen Shader in hat die Form eines Einstiegspunkts in einem SPIR-V-Modul.
NDK Release 12 und höher enthält eine Laufzeitbibliothek zum Kompilieren von GLSL in SPIR-V.
Die Laufzeitbibliothek ist mit der im
das Open-Source-Projekt Shaderc,
Der Referenz-Compiler Glslang GLSL ist als
Back-End. Standardmäßig ist die Shaderc-Version des
Compiler geht davon aus, dass Sie für Vulkan kompilieren. Nachdem Sie überprüft haben, ob Ihr Code für
Vulkan aktiviert der Compiler automatisch die Erweiterung KHR_vulkan_glsl
. Shaderc
Version des Compilers generiert außerdem Vulkan-konformen SPIR-V-Code.
Du kannst während der Entwicklung SPIR-V-Module in deine Vulkan-App kompilieren. eine sogenannte Vorab-Kompilierung oder AOT-Kompilierung. Alternativ können Sie Du kannst sie in deiner App aus versendeten oder verfahrenstechnisch generierten Shader kompilieren lassen Quelle, wenn dies während der Laufzeit erforderlich ist. Diese Vorgehensweise wird als Laufzeitkompilierung bezeichnet. Android Studio bietet integrierte Unterstützung für die Erstellung von Vulkan-Shadern.
Im Folgenden werden die einzelnen Vorgehensweisen näher erläutert. wie du die Shader-Kompilierung in deine Vulkan-App einbindest.
AOT-Kompilierung
Es gibt zwei Möglichkeiten, eine Shader-AOT-Kompilierung zu erreichen, die in den folgenden Abschnitten beschrieben werden.
Android Studio verwenden
Android Studio fügt Shader in app/src/main/shaders/
ein und erkennt Shader folgendermaßen:
deren Dateiendung und führt die folgenden Aktionen aus:
- Kompilieren Sie alle Shader-Dateien rekursiv unter diesem Verzeichnis.
- Hängen Sie das Suffix „.spv“ an die kompilierten SPIR-V-Shaderdateien an.
- Packen Sie SPIRV-Shaders in das Verzeichnis
assets/shaders/
des APK.
Die Anwendung lädt die kompilierten Shader zur Laufzeit aus dem entsprechenden assets/shaders/
-Speicherort. Die Struktur der kompilierten spv-Shader-Datei ist mit der Struktur der GLSL-Shader-Datei der Anwendung unter app/src/main/shaders/
identisch:
AAsset* file = AAssetManager_open(assetManager, "shaders/tri.vert.spv", AASSET_MODE_BUFFER); size_t fileLength = AAsset_getLength(file); char* fileContent = new char[fileLength]; AAsset_read(file, fileContent, fileLength);
Kompilierungs-Flags von Shaderc können im Gradle-DSL-Block shaders
konfiguriert werden, wie im folgenden Beispiel gezeigt:
Cool
android { defaultConfig { shaders { glslcArgs.addAll(['-c', '-g']) scopedArgs.create('lights') { glslcArgs.addAll(['-DLIGHT1=1', '-DLIGHT2=0']) } } } }
Kotlin
android { defaultConfig { shaders { glslcArgs += listOf("-c", "-g") glslcScopedArgs("lights", "-DLIGHT1=1", "-DLIGHT2=0") } } }
glslcArgs
gelten für alle Shader-Kompilierungen. scopedArgs
gilt nur beim Kompilieren
für diesen Bereich. Im obigen Beispiel wird das Bereichsargument lights
erstellt, das nur auf
GLSL-Shader im Verzeichnis app/src/main/shaders/lights/
Weitere Informationen finden Sie unter
glslc für die vollständige Liste
der verfügbaren Kompilierungs-Flags. Shaderc innerhalb des NDK ist ein Snapshot aus diesem GitHub-Repository im
NDK-Veröffentlichungszeit; erhalten Sie die genauen unterstützten Flags für diese Version mit dem Befehl
glslc --help
, wie im nächsten Abschnitt beschrieben.
Offline-Kompilierung über die Befehlszeile
GLSL-Shader können unabhängig von der Hauptanwendung mit dem Befehlszeilen-Compiler glslc zu SPIR-V kompiliert werden. NDK Release 12 und höher enthält eine Version der vordefinierten Version von glslc und
zugehörige Tools im Verzeichnis <android-ndk-dir>/shader-tools/
, um dieses Nutzungsmodell zu unterstützen.
Der Compiler ist auch auf dem Shaderc verfügbar. Projekt respektieren; folgen Sie der Anleitung, um eine Binärversion zu erstellen.
glslc bietet zahlreiche Befehlszeilenoptionen für die Shader-Kompilierung, um verschiedene Anforderungen für eine Anwendung zu erfüllen.
Das glslc-Tool kompiliert eine einzelne Quelldatei in ein SPIR-V-Modul mit einem einzelnen Shader
Einstiegspunkts hinzufügen. Standardmäßig hat die Ausgabedatei denselben Namen wie die Quelldatei.
aber mit angehängter Erweiterung .spv
.
Sie teilen dem glslc-Tool mithilfe von Dateinamenerweiterungen mit, welche Grafik-Shader-Phase kompiliert werden soll. oder ob ein Compute-Shader kompiliert wird. Informationen zur Verwendung dieser Dateinamen Erweiterungen und Optionen, die Sie mit dem Tool verwenden können, finden Sie unter <ph type="x-smartling-placeholder"></ph> Spezifikation der Shader-Phase in der <ph type="x-smartling-placeholder"></ph> glslc-Anleitung.
Laufzeitkompilierung
Für die JIT-Kompilierung von Shadern während der Laufzeit stellt das NDK die libshaderc-Bibliothek bereit. die sowohl C als auch C++ APIs bietet.
C++-Anwendungen sollten die C++ API verwenden. Wir empfehlen, Apps in anderen Sprachen die C API verwenden, da das C ABI niedriger ist und wahrscheinlich eine bessere Stabilität bietet.
Das folgende Beispiel zeigt, wie die C++ API verwendet wird:
#include <iostream> #include <string> #include <vector> #include <shaderc/shaderc.hpp> std::vector<uint32_t> compile_file(const std::string& name, shaderc_shader_kind kind, const std::string& data) { shaderc::Compiler compiler; shaderc::CompileOptions options; // Like -DMY_DEFINE=1 options.AddMacroDefinition("MY_DEFINE", "1"); shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv( data.c_str(), data.size(), kind, name.c_str(), options); if (module.GetCompilationStatus() != shaderc_compilation_status_success) { std::cerr << module.GetErrorMessage(); } std::vector<uint32_t> result(module.cbegin(), module.cend()); return result; }
In Ihre Projekte einbinden
Sie können den Vulkan-Shader-Compiler entweder mit dem
Android.mk
-Datei oder Gradle-Plug-in verwenden.
Android.Mk
Führen Sie die folgenden Schritte aus, um den Android.mk
Ihres Projekts zu verwenden
-Datei zum Integrieren des Shader-Compilers.
-
Fügen Sie die folgenden Zeilen in die Datei „Android.mk“ ein:
include $(CLEAR_VARS) ... LOCAL_STATIC_LIBRARIES := shaderc ... include $(BUILD_SHARED_LIBRARY) $(call import-module, third_party/shaderc)
-
Legen Sie für APP_STL einen der folgenden Werte fest:
c++_static
,c++_shared
,gnustl_static
, odergnustl_shared
in Application.mk der App
CMake-Integration von Gradle
-
Wechseln Sie in einem Terminalfenster zu
ndk_root/sources/third_party/shaderc/
-
Führen Sie den folgenden Befehl aus, um den Shaderc von NDK zu erstellen. Sie müssen diesen Befehl für jede verwendete NDK-Version nur einmal ausführen:
$ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \ APP_STL:=<stl_version> APP_ABI=all libshaderc_combined
Mit diesem Befehl werden zwei Ordner in <ndk_root>/sources/third_party/shaderc/ abgelegt. Das Verzeichnis sieht wie folgt aus:
include/ shaderc/ shaderc.h shaderc.hpp libs/ <stl_version>/ {all of the abis} libshaderc.a
-
Fügen Sie die generierten Bundles und Bibliotheken mithilfe von hinzu.
target_include_directories
und <ph type="x-smartling-placeholder"></ph>target_link_libraries
, wie Sie es normalerweise bei ähnlichen extern Bibliotheken. Der STL-Typ deiner App muss einem derstl
-Typen entsprechen, die instl_version
. Das NDK empfiehlt die Verwendung vonc++_shared
oderc++_static
, obwohlgnustl_static
undgnustl_shared
werden ebenfalls unterstützt.
Das neueste Shaderc
Shaderc im NDK stammt aus dem Android Source Tree, einer Snapshot des vorgelagerten Shaderc-Repositorys. Wenn Sie das neueste Shaderc benötigen, finden Sie weitere Informationen in der Build-Anleitung. Die übergeordneten Schritte sind folgende:
- Laden Sie die neueste Shaderc-Version herunter:
git clone https://github.com/google/shaderc.git
- Aktualisieren Sie die Abhängigkeiten:
./utils/git-sync-deps
- Build Shaderc:
<ndk_dir>/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \ APP_STL:=c++_static APP_ABI=all libshaderc_combined -j16
- Konfigurieren Sie Ihr Projekt so, dass es Ihren eigenen Shaderc-Build in Ihrer Build-Skriptdatei verwendet.