王祢&李文磊-将桌面级VR通过Vulkan和UE4移植到移动平台
2020-02-27 252浏览
- 1.将桌面级VR通过Vulkan和UE4移植到移动平台
- 2.总概 • • • • • • • 项目目的 平台差距 准备工作 对比Vulkan和GLES 问题与分析 执行优化 遇到的困难
- 3.项目目的 • 探索移动平台VR效果的极限 • 探索UE4下移动端,Vulkan+VR流程/当前问题
- 4.THE “SHOWDOWN” DEMO
- 5.平台的差距 2160 x 1200 90 fps GTX 970 Instanced Stereo 2560x1440? (1920 x 1080) 60 fps Adreno 530 Multi-view? Deferred Renderer DX11 Mobile Forward Renderer Vulkan?
- 6.准备工作 • 硬件:Galaxy S7(latest rom), Nexus 6P(Android N)? • 桌面开发环境驱动: •Nvidia:Driver > 367.27 •AMD:Driver > 16.3 •UE:>= 4.13(4.14) 源码版本 • Vulkan SDK: • 最新(https://vulkan.lunarg.com/signin) • 确定环境变量中有VULKAN_SDK指向SDK目录
- 7.准备工作
- 8.准备工作 • 因为需要反复比较和迭代,所以需要提高迭代效率 • • • • 打开Shader分布式编译 设置好Swarm SharedDDC:DefaultEngine.ini中[DerivedDataBackendGraph]中加入Shared路径共享shader cache和cook数据 ResavePackagesCommendlet: • • GarbageCollectionFrequency=100 -StripEditorOnly –OnlySaveDirtyPacakges –IgnoreChangelist • Packaing和cooking设置 • • • • Cook only maps,指定入口地图 压缩pak(压缩解压的cpu时间比把更大的obb推到手机上要快很多) 去除EditorContent Build/Android/PakBlacklist.txt • • ../../../Engine/Content/EngineDebugMaterials/ etc
- 9.准备工作 先拿个测试场景做一下Vulkan和ES的比较吧
- 10.ES2/3.1 vs VulkanOpenGL:如果compile出错,在运行时会crash 做绘制调用的时候会有hitch,驱动只在第一次绘制时才真的编译Vulkan:可离线编译shader 在开发时可编译成SPIR-V二进制数据 所有shader的验证都在离线时完成 所有上层的shader优化都在离线时完成
- 11.ES2/3.1 vs VulkanOpenGL:Set vertex and pixel shaders Shader uniform parameters Bound textures Set blending states Set depth states Set rasterizer states Etc…Vulkan:把这些属性和状态都封装在一个对象中 切换不同的状态相当高效!
- 12.ES2/3.1 vs Vulkan Vulkan有显式的RenderPass vkBeginRenderPass(...) vkEndRenderPass(...) 每个render pass可以指定哪些数据需要load到tile memory里,哪些数据需要存回framebuffer
- 13.测试结果
- 14.问题与分析 当前数据: 800+ drawcall 120w+面 有部分复杂度一般的matinee和bp逻辑 有大量对移动平台来说过于复杂的材质 大量粒子的overdraw 静态光照为主,不投影
- 15.问题与分析 普通的优化策略: 查找瓶颈() { return max3(逻辑线程开销,渲染线程开销,gpu开销); } While( 测试帧数 < 目标帧数 ) { 瓶颈对象 =查找瓶颈(); 优化(瓶颈对象); }
- 16.问题与分析 那我们开始吧! 先定位瓶颈? 不,先要能跑起来。 Crash主要来自于: • 内存爆炸 • • • 一些不支持的shader没有fallback回default • • 最大的数据来源于贴图 – 强制在DeviceProfile中把所有的TextureGroup的LODBias先改成2 JVM出事堆内存过高 – 手动设置layout 手动删除导致crash的材质 vkAllocateMemory超过设备上限(S7上4096) • 暂时先用MergeActor工具强制合并了大量mesh和材质 以下省略1000字和各种琐碎的crash做斗争。。。
- 17.问题与分析 跑起来了(非VR)! 开始定位瓶颈: stat unit game 80ms render 80ms gpu 80ms 任何地方都是瓶颈! 怎么才能简单粗暴的找出合适的优化目标呢?
- 18.问题与分析 •GPU:• • • simplygon直接减面合并放到LOD中,强制所有meshactor使用LOD1 关闭MobileHDR MaterialQuality设置 • • r.MobileContentScaleFactor 0.5 • • Force Fully Rough, Force Non-metal, Disable Lightmap directionality, Force low quality reflections 为了能快速迭代,我稍微改了下引擎,让这个值可以实时生效 CPU: • 逻辑线程:为什么逻辑线程也会要那么久?不科学! • • • • • Stat startfile/stopfile, stat dumpave –ms=1 竟然没有启用渲染线程! ToggleRenderingThread NativizeBP – 8ms -> 2.5ms ! 渲染线程: • 同GPU的优化合并MeshActor和材质的时候一并降低了开销
- 19.问题与分析 • 非VR下能跑到60fps了! • 通过这些测试,能确定在这个复杂度的场景下,单屏渲 染线程瓶颈的阈值在差不多500 dc • 渲染分辨率在720p的时候,瓶颈在渲染线程(13ms) • 1080p后到gpu上(16ms) • 接下来就是细节优化和放大部分渲染参数来迭代了
- 20.问题与分析 • 最终没能做到在S7 GearVR上跑到60fps • 对于MultiView的支持还没有完成 • 目前只支持PS4,Mobile的版本可能在这两周会有一个内部的版 本 • DD的Scanline • GearVR和DD的Compositor还没有完好的支持vulkan的实现 • 在下个月应该就会有更新 • Vulkan还在进化中 • UE4对于Vulkan的支持还有很多改善空间 • 正在让更多上层逻辑变得更PSO-awareness • RHI的refactor
- 21.内容优化
- 22.• • • • • • 顶点数; Actor数量; 材质数量; 材质复杂度; 贴图尺寸; 渲染品质设置;
- 23.Statistics
- 24.
- 25.烘培合并材质
- 26.烘培合并材质
- 27.烘培合并材质
- 28.Simplygon 减面
- 29.Instancing Staticmeshes(Batch Staticmeshes)
- 30.选择需要合并的Actors
- 31.优化材质/大范围
- 32.优化材质/复杂
- 33.材质优化/透明
- 34.材质优化/粒子特效
- 35.优化材质/删除不必要的视觉元素
- 36.减少贴图sampler
- 37.去除后期材质和灯光function 使用简单方式替代
- 38.检查清理地图警告
- 39.设置合理目标平台Profile,记得保存! • 调整合理的渲染品质参数 • 合理的贴图大小 • 分辨率
- 40.三角面 Drawcall
- 41.Q&A