unreal engine 4 图形API选择逻辑
调试android的时候比较好奇,如何选择图形API是vulkan还是openGL ES,所以看了一下。其实RHI(Rendering Hardware Interface)初始化的逻辑非常简单,估计读过UE4源码的都清楚。我也就在这里给没有研究过的朋友简单叙述一下吧。
unreal engine 4 图形API选择逻辑(RHI初始化逻辑)
UE4引擎RHI初始化的阶段,在引擎的preInit阶段,执行RHIInit
函数。而RHIInit函数中真正与平台相关的是PlatformCreateDynimicRHI
函数。每个平台要实现对应自己的PlatformCreateDynimicRHI
函数。
HTML5
从最简单的HTML5平台开始讲起吧。
HTML5DynimicRHI的逻辑非常简单,因为只支持openGL ES API(es2,UE4暂时不支持webgl2),所以直接启用OpenGLDrv
RHI即可。
Windows
Windows平台RHI初始化逻辑最为复杂(windows平台支持图形API数量最多,featurelevel也最多)。
1. 判断命令行参数
- 使用的featurelevel:
sm4
,sm5
- 使用的图形API:
- vulkan:
vulkan
- openGL:
opengl
,opengl3
,opengl4
- directx:
d3d10
,dx10
,d3d11
,dx11
,d3d12
,dx12
- vulkan:
命令行参数中指定API的优先级最高,如果没有编译对应shader,会cache错误直接崩溃
2. 如果命令行参数中没有指定API
如果如果命令行参数中没有指定API,会在 DefaultEngine.ini 配置文件中寻找[/Script/WindowsTargetPlatform.WindowsTargetSetting]
中的TargetedRHIs
配置,从上往下第一个支持的API就是RHI实际使用的图形API,featurelevel会使用所支持最大的featurelevel。
Windows平台最后还要判断一下驱动支持情况,还有一种特殊情况,运行fraps的时候,dx11和dx12的RHI会初始化失败,原因不明,但是UE4源码中有提。
还有一个需要注意的地方,Windows上的DX和Xbox one上的DX并不完全相同
Android
Android平台RHI初始化逻辑就要简单的多,能用vulkan的就用vulkan,用不了的就用openGL ES。用vulkan时featurelevel也是es31。
运行PlatformCreateDynimicRHI
时会先执行FAndroidMisc::ShouldUseVulkan()
,为true就用vulkan,否则就openGL。
FAndroidMisc::ShouldUseVulkan()
首先会检查CVars r.Android.DisableVulkanSupport
,如果为1就强行不使用vulkan。
之后是在 DefaultEngine.ini 配置文件中寻找[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]
中的bSupportVulkan
配置,为0则不使用vulkan。
如果ShouldUseVulkan()
为true,会尝试启动VulkanRHI
,如果VulkanRHI
则后备启动OpenGLDrv
。
在支持vulkan的设备上vulkan初始化失败的情况我还真遇到过,在华为mate9(mali-G71 mp8)上开MGD的情况下失败
Apple(mac os & iOS)
mac os
mac os平台上现在初始化逻辑非常简单,因为UE4已经不在osx上支持openGL RHI,只支持metal,支持的命令行参数有metal
, metalsm5
, 但其实输不输已经无所谓了。
如果没有命令行参数就检查[/Script/MacTargetPlatform.MacTargetSetting]
中的TargetedRHIs
配置,接下来逻辑和Windows相同,不过考虑UE4在osx现在只支持metal。。。
iOS
iOS也会检查命令行参数。
使用的图形API:
- metal:
metal
,metalmrt
- openGL es2:
es2
之后是在 DefaultEngine.ini 配置文件中寻找[/Script/IOSRuntimeSettings.IOSRuntimeSettings]
中的bSupportMetalMRT
配置,为1则使用metal MRT。
之后是在 DefaultEngine.ini 配置文件中寻找[/Script/IOSRuntimeSettings.IOSRuntimeSettings]
中的bSupportMetalMRT
配置,为1则使用metal MRT。
在不使用metal MRT的情况下,在配置中寻找bSupportMetal
,为1则使用metal(无MRT)。
在不使用metal的情况下,在配置中寻找bSupportOpenGLES2
, 为1则使用openGL ES 2.0。(iOS不支持openGL ES 3.1)
不支持metal的iOS设备已经非常稀少,现阶段在iOS上可以完全no openGL,only metal
Linux
Linux上RHI初始化逻辑也比较简单,如果命令行参数中有vulkan
就使用VulkanRHI
,没有就使用OpenGLDrv
。
[/Script/LinuxTargetPlatform.LinuxTargetSetting]
中的TargetedRHIs
配置只和使用shader的格式相关(高版本的openGL也支持使用SPIR-V作为shader)。
Linux上featurelevel只支持SM5
小结
用张流程图简单总结一下。
Comments