王祢&李文磊-将桌面级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