ue4联网游戏开发的正确姿势,怎么用ue4开发生存游戏

首页 > 实用技巧 > 作者:YD1662024-01-17 12:35:47

编者按 本文介绍了四个小主题,分别是UE4 Mobile端的Skylight和ReflectionCapture之间的关系,如何让ReflectionCapture采集天光,ReflectionCapture的亮度校正算法分析及在期在移动端可能的优化。值得一提的是ReflectionCapture IBL的压缩是UE4.26中已被实现。

文 | Jiff

(本文首发于知乎专栏“图形游戏和宅”,转载请征得同意。)

这篇文章是UE4 反射球系列文章的完结篇,内容包含以下几个部分:

1. SkyLight和Reflection Capture的Cubemap有何不同?

2. Reflection Capture为何采集不到天空球Mesh?

3. Reflection Capture的亮度是如何确定的?

4. 对移动端来说,Skylight/Reflection Capture有哪些可用的优化?

SkyLight和Reflectioin Capture

SkyLight所提供的是直接光照,同时包含漫反射和高光反射,而Relfection Capture提供的是环境反射,只有间接高光且不包含漫反射。严格来说,这两部分光照信息的频度定位不同,是叠加关系,不能放一起比较。

凡事都有意外,UE4在移动端的标准光照模型中SkyLight Cubemap和Reflection Capture Cubemap是互斥的——要么存在的是Skylight,要么存在的是Reflection Capture,且在选择时Relfection Capture的优先级高于Skylight。不光如此,移动端的Relfection Capture的范围也无效。因为两者的互斥关系移动端PBR渲染过程只需要采样一次cubemap,相比多次采样cubemap更廉价,能耗更低。

但同时这些做法也带来了一些问题:

1. 场景中同时存在Reflection Capture&Skylight时,因为Reflection Capture优先级高且范围无效,永远只可能Reflection Capture有效。

2. 相对于非移动端来说,移动端的场景中IBL所提供的光照往往会来得更暗一些。

3. 因为Reflection Capture的范围无效,物体在渲染时只取离它最近的那一个,也导致在场景制作过程中,需要区分室内室外,楼上楼下,多变的环境氛围时工作流几乎不可能实现,因为无法精确控制范围。这个问题对于想要制作高品质游戏场景来说,说致命并不为过。

Reflection Capture 为何采集不到天空球

在场景和TA的强烈要求下,我们在移动端修复了Reflection Capture的作用范围,想要在移动端让范围起作用,只需要在FScene::FindClosestReflectionCapture里查找和物体包围盒相交的的Reflection Capture并处理好Mobilebasepass的ShaderBinding参数设定即可。

这个问题修复之后,TA很快又发现两个新的问题:

1. 同样的一样IBL图,当它作为Skylight输入存在时比作为Reflection Capture输入时对亮度的贡献大很多。


2. 放在室外的Reflection Capture,上半部分是黑的,一查原来是采集不到Stationary的天空球。

第一个问题留到第三部分去说,第二个Reflection Capture采集不到天空球的问题,则是因为Skylight有一个选项用来控制天空球的Threshold。

ue4联网游戏开发的正确姿势,怎么用ue4开发生存游戏(1)

这个选项的直接意思是:距离原点多远之后的场景物体属于天空球,这个默认值是1500米,即1500米以外的所有物体,都属于天空。因为UE4在非移动端的实现中Skylight和Reflection Capture相互叠加,且当Reflection Capture和SkyLight同时可见时,优先选用的是Skylight的部分。这样的话,在存在Skylight的室外,采集ReflectionCapture时确实不需要采集和存储天空球。

这个设计初衷所带来的问题在于:你要是移动端的话,你就完蛋了——你室外的光滑物体和纯金属,上半球一片黑。黑夜给了你的黑色眼睛,是你看到了自己心理的阴影?

我们来看看UE4在采集Reflection Capture时,是如何丢掉天空球信息的。

1. 实现代码在ReflectionEnvironmentShader.usf 的CopySceneColorToCubeFaceColorPS函数中,代码如下所示:

ue4联网游戏开发的正确姿势,怎么用ue4开发生存游戏(2)

这段代码的解释为:当当前采样到的位置距离< 0.8 * threshold时,IBL的Alpha值为1,否则小于1,按1-Smoothstep曲线(似乎看到的实现,大多数SmoothStep都是三次曲线)方式趋向于0,当距离大于等于threshold时,Alpha必然为0,Alpha 值会被写入Cubemap的Alpha通道。

2. SkyLightParametersValue参数传递的入口在ReflectionEnvironmentCapture.cpp中的FCopySceneColorToCubeFacePS类的SetParameters函数中,代码如下:

ue4联网游戏开发的正确姿势,怎么用ue4开发生存游戏(3)

可以看到这儿的SkyLightParametersValue.x即为 Skylight上的SkyDistance Threshold值。

3. 在FilterReflectionEnvironment函数中一开始执行一次premultiply alpha,这时alpha值同会乘以rgb值,所以会造成最终的cubemap中alpha为0的值也变成了全黑色,代码如下:

ue4联网游戏开发的正确姿势,怎么用ue4开发生存游戏(4)

首页 1234下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.