利用 RenderTexture 降低实际渲染分辨率以提升渲染性能
发表于2016-11-08
摘要
本篇文章介绍的方法可以有效提高20%~40%的渲染帧数。利用RenderTexture 降低摄像机对游戏场景的实际渲染分辨率,可以有效优化gpu的渲染消耗,在高、中、低端各机型的手机上均可以大幅的提升游戏FPS。对 3D游戏, 2.5D游戏 和复杂的多层卷轴类 2D游戏 等面临大量gpu渲染开销瓶颈的情况有显著提升。同时也可以用来降低ImageEffect(后期屏幕处理)的处理开销。
1、简介
对于场景比较复杂的 3D游戏, 2.5D游戏 和复杂的多层卷轴类 2D游戏 通常在手机上会遇到GPU渲染开销过高的瓶颈,导致游戏fps上不去,玩家觉得游戏卡顿。本片文章的思路就是在尽量保证视觉效果的情况下降低渲染分辨率,减少GPU开销。
(在同一屏幕分别率下主摄像机采用不同实际渲染分别率的画面)
手机屏幕并不大,而且大部分玩家玩的时候也不会拿到很近的地方看,只要分辨率降低的不明显,并不会对游戏体验有所影响,对视觉效果的降低也在可接受范围内。
虽然游戏场景画质降低了,但是UI以及第一人称持枪模型等近景模型和有高精度画质要求的部分依然可以通过第二摄像机获得高分辨率渲染。
降低分辨率对于低端和超高分辨率屏幕的手机有明显优势。低端手机配置很难跑起高画质的游戏,节省的GPU开销可以有效提升画面表现。对于超高分辨率屏幕的手机,除了对于静态画面比较多的益智类,ACG等类型以外,过高的分辨率对提升游戏表现几乎没有影响,反而造成大量的GPU开销。即使是静态的画面,对于不同分辨率的原图放在一起看或许会发现区别,但是单看一张的话通常也不会觉得低分辨率的图片影响体验。验证最低分辨率的话可以将同一张图片缩小不同的分辨率后跟原图一起放到手机图片预览器里比对,看缩小多少百分比是最可以接受的。对不同的手机降低的分别率与效果比不同。目前在项目中实际应用过的最大分辨率缩减是在 2560x1440的三星s6 手机上 缩小到 911x512,但是在正常使用距离几乎跟原始分辨率下的游戏画面看不出差别。限于项目还在开发中保密不能发图,大家可以自行验证效果。
(RenderTexture大小和FPS)
因为是在PC上测试,fps异常不稳定。实际在手机和pad上帧数会更准确一些,而且开销差异更大。
测试用的Quility设置和ImageEffect。为了凸显效果差异而去掉了抗锯齿。
2、设置RenderTexture ,摄像机和脚本
在Project里创建RenderTexture,然后将RenderTexture付给主摄像机的RenderTarget。
第二摄像机和RenderTexture图片可以藏到远离场景的地方。RenderTexture的mesh给一个特殊的层(Layer)RenderTex。
第二摄像机的Clear Flags调成SolidColor不渲染天空盒。摄像机的CullingMask调成RenderTex只渲染RenderTexture图片。
通过脚本可以在启动时根据手机调用合适的分辨率。对于iOS平台因为配置比较统一,可以直接读取手机型号作为性能评定指标。Android则一般只能根据分辨率来粗略判断。如果Android需要更匹配的平台配置,只能在打版本的时候打出对应不同厂家的设备的配置。
根据需要RenderTexture可以选择Bilinear 或者 Point模式。 Bilinear模式会比较模糊,但是锯齿不明显。Point模式更清晰,但是锯齿也会更明显。
(960x540 bilinear 模式)
(960x540 point 模式)
3、开发阶段测试分辨率
由于不同的项目面对的GPU压力不同,最好在设备上动态调试。通过下面的脚本代码可以实现在运行时调整主摄像机分辨率,然后根据实际fps和效果选择对应的渲染分辨率。
4、利用shader实现 ImageEffect
如果直接使用Unity自带的ImageEffect,在移动平台上开销很大。在使用RenderTexture的同时,也可以利用RenderTexture用Shader渲染的机会再进行一些ImageEffect处理。同时因为分辨率缩小,一些复杂的效果也可以得到很好的性能提升。这里可以使用一些第三方的ImageEffect插件,比如Glow,本身就对移动平台有优化支持的情况下可以得到进一步的提升。在项目实际运用中,用Glow插件不使用RenderTexture降低分辨率,FPS只有45帧左右。 使用RenderTexture降低分辨率到75%后,FPS提升到60帧满帧并且还有一定富裕。
Glow 一个支持移动平台的辉光插件。