This project provides a complete, working solution for integrating an external Vulkan device with Unity's native rendering plugin. It supports two approaches:
- Device Interception - Provide your own VkDevice to Unity (similar to OpenXR)
- Resource Sharing - Share resources between your device and Unity's device
- ✅ Fully compilable and working code
- ✅ Device interception using
IUnityGraphicsVulkanV2 - ✅ Create your own Vulkan device before Unity initializes
- ✅ Provide external VkInstance, VkPhysicalDevice, VkDevice to Unity
- ✅ C# wrapper for easy Unity integration
- ✅ Cross-platform support (Windows, macOS, Linux, Android)
- ✅ Example usage scripts
unityexternalvulkan/
├── CMakeLists.txt # Build configuration
├── include/ # Header files
│ ├── IUnityInterface.h # Unity plugin interface
│ ├── IUnityGraphics.h # Unity graphics interface
│ ├── IUnityGraphicsVulkan.h # Unity Vulkan interface (V2)
│ ├── VulkanDeviceManager.h # Your external device manager
│ └── UnityVulkanPlugin.h # Plugin API
├── src/ # Implementation files
│ ├── VulkanDeviceManager.cpp # External device creation
│ └── UnityVulkanPlugin.cpp # Plugin implementation
└── UnityProject/Assets/Scripts/ # Unity C# scripts
├── VulkanInterop.cs # C# wrapper
└── VulkanInteropExample.cs # Example usage
- CMake 3.15 or higher
- Vulkan SDK installed
- C++17 compatible compiler
- macOS: Xcode command line tools
- Linux: GCC/Clang
- Windows: Visual Studio 2019+
# Install Vulkan SDK
# Download from https://vulkan.lunarg.com/sdk/home
# Build the plugin
mkdir build
cd build
cmake ..
make
# The plugin will be output to: UnityProject/Assets/Plugins/libUnityVulkanInterop.bundle# Install Vulkan SDK
sudo apt-get install vulkan-sdk
# Build the plugin
mkdir build
cd build
cmake ..
make
# The plugin will be output to: UnityProject/Assets/Plugins/libUnityVulkanInterop.so# Install Vulkan SDK from https://vulkan.lunarg.com/sdk/home
# Build the plugin
mkdir build
cd build
cmake ..
cmake --build . --config Release
# The plugin will be output to: UnityProject/Assets/Plugins/UnityVulkanInterop.dll-
Copy the built plugin to your Unity project:
- macOS:
libUnityVulkanInterop.bundle→Assets/Plugins/ - Linux:
libUnityVulkanInterop.so→Assets/Plugins/ - Windows:
UnityVulkanInterop.dll→Assets/Plugins/
- macOS:
-
Copy the C# scripts:
VulkanInterop.cs→Assets/Scripts/VulkanInteropExample.cs→Assets/Scripts/
- Go to Edit → Project Settings → Player
- Under Other Settings, set:
- Graphics APIs: Remove all except Vulkan
- Color Space: Linear (recommended)
- Click Apply
Add VulkanInteropExample.cs to a GameObject in your first scene. The script uses [RuntimeInitializeOnLoadMethod] to initialize before Unity creates its graphics device.
// This happens automatically via the RuntimeInitializeOnLoadMethod attribute
// No manual setup required!If you need more control, call the initialization manually:
using UnityEngine;
public class CustomVulkanSetup
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
static void Initialize()
{
// Enable device interception
VulkanInterop.EnableDeviceInterception(true);
// Initialize your external Vulkan device
bool success = VulkanInterop.InitializeExternalDevice();
if (success)
{
// Get device handles
IntPtr instance, device, physicalDevice;
VulkanInterop.GetDeviceInfo(out instance, out device, out physicalDevice);
Debug.Log($"External VkDevice: 0x{device.ToInt64():X}");
// Unity will now use your external device!
}
}
}1. Unity loads plugin → UnityPluginLoad() called
2. Plugin registers device event callback
3. Your code calls InitializeExternalVulkanDevice()
→ Creates VkInstance, VkPhysicalDevice, VkDevice
4. Unity initializes graphics
→ Plugin's OnVulkanInitializationCallback() is called
→ Plugin provides external device to Unity
5. Unity uses your external device for all rendering!
Creates and manages your external Vulkan device:
VulkanDeviceManager deviceMgr;
deviceMgr.InitializeExternalDevice();
// Now you have: VkInstance, VkPhysicalDevice, VkDevice, VkQueueThe plugin intercepts Unity's initialization:
void OnVulkanInitializationCallback(const UnityVulkanPluginEventConfig* config)
{
// Provide your external device to Unity
initData->instanceOverride = myVkInstance;
initData->deviceOverride = myVkDevice;
initData->physicalDeviceOverride = myVkPhysicalDevice;
// Unity will now use YOUR device!
}To use your own existing Vulkan device:
Replace the device creation in VulkanDeviceManager.cpp:
bool VulkanDeviceManager::InitializeExternalDevice()
{
// Instead of creating a new device:
// m_instance = YourLibrary::GetVkInstance();
// m_device = YourLibrary::GetVkDevice();
// m_physicalDevice = YourLibrary::GetVkPhysicalDevice();
// m_graphicsQueue = YourLibrary::GetVkQueue();
// m_queueFamilyIndex = YourLibrary::GetQueueFamilyIndex();
m_initialized = true;
return true;
}Update CMakeLists.txt:
# Add your library
find_library(YOUR_VULKAN_LIB YourVulkanLib PATHS /path/to/lib)
target_link_libraries(UnityVulkanInterop PRIVATE
${Vulkan_LIBRARIES}
${YOUR_VULKAN_LIB}
)cd build
cmake ..
makemkdir build && cd build
cmake ..
make- Open Unity project
- Ensure Vulkan is the graphics API
- Add
VulkanInteropExample.csto a GameObject - Click Play
You should see:
[VulkanInteropExample] BeforeSplashScreen - Setting up Vulkan device interception
[VulkanDeviceManager] Initializing external Vulkan device...
[VulkanDeviceManager] External Vulkan device initialized successfully
[UnityVulkanPlugin] Vulkan initialization intercept callback triggered!
[UnityVulkanPlugin] Providing external Vulkan device to Unity
[UnityVulkanPlugin] External device successfully provided to Unity
If you need to share resources between your device and Unity's device:
// Enable external memory extensions in VulkanDeviceManager.cpp
m_deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
m_deviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
#ifdef _WIN32
m_deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
#else
m_deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
#endifThen create shared images/buffers with external memory:
VkExternalMemoryImageCreateInfo externalInfo = {};
externalInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
externalInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
VkImageCreateInfo imageInfo = {};
imageInfo.pNext = &externalInfo;
// ... other image parameters- Check the plugin is in
Assets/Plugins/ - Verify Vulkan SDK is installed
- Check Unity console for error messages
- Ensure initialization happens BEFORE Unity graphics init
- Use
RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen) - Check that Vulkan is the selected graphics API
macOS:
# If Vulkan SDK not found
export VULKAN_SDK=/path/to/vulkansdkLinux:
# Install missing dependencies
sudo apt-get install libvulkan-dev vulkan-toolsWindows:
# Set Vulkan SDK path
set VULKAN_SDK=C:\VulkanSDK\1.x.xxx.x- Unity Native Plugin Interface
- Unity Graphics Native Plugin
- OpenXR Unity Plugin - Uses similar device interception
- Vulkan Specification
This is example code for educational purposes. Use it as a starting point for your own projects.
For issues or questions:
- Check the Unity console logs
- Verify plugin is loaded: Look for
[UnityVulkanPlugin] Plugin loaded - Check device interception: Look for
Providing external Vulkan device to Unity