这是我在学习官方VR项目教程中的笔记和总结,以及一些思考,如果有不对的地方也谢谢指出
教程链接:
官方文档,最佳实践
在创建针对特定VR平台的新项目时,首先在 游戏(Games) 类别下选择 虚拟现实应用(VR Template),然后在 项目设置(Project Settings) 中选择以下选项:
-
可缩放3D或2D(Scalable 3D or 2D)
-
已禁用光线追踪(Raytracing Disabled)
-
移动设备/平板电脑(Mobile / Tablet)
-
不带初学者内容包(No Starter Content)
-
进入 编辑->项目设置->描述 ,并启用 以VR启动 。
在DefineEngine.ini中添加
[SystemSettings]
vr.PixelDensity=1
r.SeparateTranslucency=0
r.HZBOcclusion=0
r.MotionBlurQuality=0
r.PostProcessAAQuality=3
r.BloomQuality=1
r.EyeAdaptationQuality=0
r.AmbientOcclusionLevels=0
r.SSR.Quality=1
r.DepthOfFieldQuality=0
r.SceneColorFormat=2
r.TranslucencyVolumeBlur=0
r.TranslucencyLightingVolumeDim=4
r.MaxAnisotropy=8
r.LensFlareQuality=0
r.SceneColorFringeQuality=0
r.FastBlurThreshold=0
r.SSR.MaxRoughness=0.1
r.rhicmdbypass=0
sg.EffectsQuality=2
sg.PostProcessQuality=0
注:不知为何mobile multi-view 无法开启 答案:原来是是与mobile HDR冲突 4.27应该无这个问题
Why we chose forward rendering
Deferred rendering is the default type of rendering used in Unreal Engine. Instead of calculating lighting information of a scene while rendering it’s geometry – the software performs the lighting calculations after the scene’s geometry fragments have been culled. While this type of rendering is more efficient for projects with a large number of lights, deferred rendering takes up a lot more memory, since memory is so limited in real-time projects, it’s wasteful to have rendering take up a majority of it.
On the other hand, forward rendering generates faster render passes, which is optimal for VR platforms where quick renders are necessary to keep up with FPS requirements. Forward rendering also lets you enable MSAA (multisample anti-aliasing), where adjacent pixels are sampled together instead of rendering an entire scene in high resolution. Choosing forward rendering for our VR project helped us achieve realistic graphic quality for Oculus Quest without compromising frame rate. Here’s how we implemented forward rendering into our VR project to improve its performance.
为什么使用前向渲染:
几个原因:
-
由于是在移动端上,而延迟渲染使用GBuffer会大量占用内存,越高分辨率影响越大
-
前向渲染的渲染管线速度更快,更能满足vr场景的需求
-
前向渲染能够使用msaa
注意移动HDR有默认开启
官方教程步骤:
-
打开oculus VR插件 和 online subsystem oculus插件(无法开启就先关闭别的online插件)
-
打开前向渲染 forward Rendering(更快更高效)
-
关闭动态模糊(前向渲染不支持)
-
开启instance stereo(实例化立体),在VR场景中会有两个摄像头代表左眼和右眼,is可以让两个摄像头共享特定比例的渲染数据,缩短绘制线程花费的时间
-
开启MSAA,可以提供更好的平滑效果,注意会占用显存,可能会影响性能
-
支持平台选为安卓(看设备)
-
取消使用平滑帧率(fixed frame Rate),因为VR需要锁帧
-
关闭自定义时间步Custom TimeStep,因为VR项目并不需要
-
如果是在一体机设备上的项目,关闭mobile HDR,开启移动多视图mobile multi-view
-
在工程项目config中,DefaultEngine.ini加入如下代码【个人使用中未使用,说是不加appid构建会警告,如果是使用quest这种一体机设备,还要将这些代码配置到AndroidEngine.ini,在引擎文件夹Engine-config-android里】
[OnlineSubsystem]
DefaultPlatformService=Oculus
[OnlineSubsystemOculus]
bEnabled=true
OculuesAppId=
RiftAppId=
-
使用oculus的节点verify Entitlement 节点来验证应用权限,确保已与设备链接,用户有权使用该app
https://learn.unrealengine.com/course/3746907/module/7254773?moduletoken=UHxxnDLPW8Rp-7N-q4JkIjEQEsOt3snTmaKK-rCvMCbzh~y0iaykoFQik9vT6VYT&LPId=117565
渲染和光照优化建议:
-
增加一个光源,都会对前向渲染产生很多开销,要控制光源数量和半径
-
MSAA只能解决源锯齿的问题
-
纹理锯齿需要通过mipmap 和 高品质过滤解决【注意 虚幻里会禁用非二次幂纹理产生Mipmap,这不仅会导致锯齿,还是让渲染变慢】
-
MSAA无法解决镜面微光锯齿,使用复合纹理技术解决
-
在移动端需要关闭这些功能,因为可能造成长时间的编译和性能损耗,前向渲染会受到更大的影响
-
使用较少种类的材质并提高使用他们的频率
-
减少动态光源,使用时避免动态阴影,性能开销非常大
-
图像API(DX, opengl)也会影响耗能耗电
-
对于复杂场景Occlusion Culling可以进行很好的优化,但是对于VR应用建议关闭,作为替代,可以在场景中使用“预计算可视性体积pre computed visibility volume”,它会计算光照和可视性数据,会增加内存消耗和构建时间,体积越小剔除效率越高
PS指像素着色器
开启PSO缓存
由于OpenGL ES着色器流程的特性,推荐使用PSO缓存来避免着色器编译的运行时开销。
OpenGLES只会在绘制调用使用shader使才会进行编译,这导致许多移动端OpenGL ES应用在画面的第一帧有卡顿,从而不满足oculus一帧13.88ms的要求,因此诞生了OpenGL ES扩展项 "OES_get_program_binary"
开启PSO缓存步骤:
-
在Engine/Source中搜索ShaderPipelineCache.cpp,改成如下
bool FShaderPipelineCache::Open(FString const& Name, EShaderPlatform Platform)
{
......
if(bReady)
{
uint64 PreCompileMask = (uint64)CVarPSOFileCachePreCompileMask.GetValueOnAnyThread();
//FPipelineFileCache::SetGameUsageMaskWithComparison(PreCompileMask, PreCompileMaskComparison);
FShaderPipelineCache::SetGameUsageMaskWithComparison(PreCompileMask, PreCompileMaskComparison);
......
}
-
打开引擎,在Project Settings -> Packaging 中勾选 【共享着色器代码】Share Material Shader Code 和【共享材质原生库】 Shared Material Native Libraries
-
打开window->developer Tools->Device Profiles->Android->Rendering 加入 r.ShaderPipelineCache.Enabled 值设为1
-
关闭编辑器,打开引擎文件夹 Engine\Config\Android\AndroidEngine.ini 加入 如下内容后保存重启编辑器
[DevOptions.Shaders]
NeedsShaderStableKeys=true
-
淦,好复杂,后续需要再说,链接
https://learn.unrealengine.com/course/3746970/module/7254916?moduletoken=UHxxnDLPW8Rp-7N-q4JkIuBOIC4F1jL4A39qvRh5ceQMXjghbjAvwPyS~Pd5rj0G&LPId=117565
材质优化:
-
使用Opaque rendering,不透明效果渲染实心物体,这是性能最好的材质,进行深度计算避免被剔除像素的ps计算
-
使用Masked Rendering,遮罩渲染来生成完全透明和完全非透明的像素
-
Translucent Rendering,透明渲染会造成很大的性能开销,不推荐使用
-
Alpha Transparency, 更推荐实现透明效果的方法,additive使材质明亮,modulate使其暗淡
-
Distance Field fonts 距离场字体有着更好的抗锯齿高分辨率表现去渲染3d文本(Text Render) SDF(Signed Distance Fonts)字体,被编码到纹理表中以使用GPU的纹理采样去使边缘更平滑
VR相关:
-
传统的3D渲染会假设图像平面是一个2D矩形平面,为了给VR头显创建图像,需要扭曲图像,Oculus Quest支持固定凹陷渲染(Fixed Foveated Rendering FFR),可以节省头显视野外的ps计算和内存。这个节点在蓝图中调用Set Fixed Oculus Level,设置FFR水平,Level越高性能越好,但会牺牲设备的分辨率【注,今天发现好像4.27.1已经有支持了】
- 开启移动多视图优化mobile Multi-View,可以很好的节约CPU开销,在典型的立体渲染中,必须按顺序渲染每个眼睛缓冲区,从而使开销加倍。启用“多视图”时,对象将渲染一次到左眼缓冲区,然后自动复制到右眼缓冲区,并对顶点位置和视图相关变量进行适当修改。(要先确保关闭mobile HDR)
-
避免渲染靠近摄像机或者与摄像机相交的大型贴图,在3d空间中很容易就看出是贴图是平面的
-
使用更小的粒子
防止晕动症:
-
尽量不要去主动移动摄像头或重新设置其FOV等参数
-
是画面和灯光更加暗淡
-
垂直上下移动的话使用电梯而不是台阶
-
移动的加速是瞬时的
-
不要使用景深和后处理
VR中的移动方式ÿ