Origin
community.uwa4d.com
Tags
简悦
项目
收藏夹
创建时间
收藏类型
Cubox 深度链接
更新时间
原链接
描述
Lightmap 平台色差问题解决方案
[
UWA 西澳大学
](/u/1541678510228135937)
本期我们聚集了这些话题:Lightmap 平台色差问题解决方案、使用 Post Processing V1 出现曝光错误、Unreal 地形制作、Mono 堆内存占用定位…
这是第 136 篇 UWA 技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间 10 分钟,认真读完必有收获。
UWA 问答社区:answer.uwa4d.comUWA QQ 群 2:793972859(原群已满员)
渲染
Q:其实问题已经解决,为了大家不用再踩这个坑,所以写下来方便大家搜索。
问题描述
PC 上烘培,转到安卓平台即可复现,但非所有项目都会遇到这个问题。我使用的 Unity 版本是 2017.4.6f1,经过测试 2017.4.14f1 依然存在这个问题。色差具体表现有亮度降低和色相变化。
经过了一个通宵,排除了贴图格式、项目设置、烘培设置、灯光参数等,最终确定改了问题原因:
问题原因
Android 不支持完整的 exr(HDR)格式,在 Swith To Android 的时候,Unity 会把 Lightmap 自动转换成一种低精度格式(并且不给任何选项和提示)。重点是这个格式转换并不是完整映射,而是类似拷贝过去的形式,转换过程会有数据溢出的问题。
变暗很好理解,而色相问题可以这么理解:假设光照贴图是一个 (2000,255,0) 的近乎大红的橙色,经过一个有数据溢出的格式转换后,会变成 (255,255,0) 的纯橙色,这就是我们看到色差的原因。
解决方案探索
在解决问题的过程中搜索到了这两个链接:Unity 填坑笔记(二):移动设备上烘焙变暗问题
解决方案:测试出 Lightmap 数据 unity_Lightmap_HDR,然后使用这个参数直接调用源码中的 HDR 解码算法,并将贴图转成 ETC(2)_RGB4。
这个方案我持否认态度,首先 Alpha 通道是用于保存亮度倍数的,抛弃了必定是有损的;其次,unity_Lightmap_HDR 是根据不同烘培结果定的一个值,不是每个场景都固定的。就是说,即使要这个方案也不是这么做的,Alpha 通道不能丢弃,unity_Lightmap_HDR 还是得读原来的值,否则换个场景就又有色差了。
Lightmap 在 PC 上与 iOS 和 Android 上表现不同的问题 http://www.ceeger.com/forum/read.php?tid=24457&fid=2&page=1
Lightmap 在 PC 上与 iOS 和 Android 上表现不同的问题 http://www.ceeger.com/forum/read.php?tid=24457&fid=2&page=1
解决方案:拿原图重新编码,游戏中使用重新编码的贴图进行解析。这个方案比较靠谱,但是我这边测试做不出来。
问题的进一步分析
我这边已经基本上完全排除其他因素了,用新建的项目和同样的贴图、灯光对象,全部使用默认设置来烘培,这东西确实是引擎 Bug,但有些项目却不会遇到,这让我感到困惑,这一定是制作流程问题。
通过对比我发现,我们场景的贴图画得非常暗,而烘培使用了高亮度的烘培,而这个做法是不合理的,贴图那么暗(基本压到 0.4 以下),是一种严重的精度浪费,而光照强度也很不符合正常环境的亮度。
所以如果没特殊原因,应该所有出问题的项目都是因为低亮度贴图强行烘亮的操作引起的。
我个人认为最科学的解决方案
以正常亮度为标准来绘制贴图,以符合现实世界强度的灯光参数来烘培场景,就不会出现这个问题了。不需要重新编码,也不需要实时解码,就可以避开这个引擎问题。但是如果有高亮度烘培的硬性需求的话,就必须自行编码重新保存了。
贾伟昊:解释两句。
题主说的那个 Unity 填坑笔记后来整理了一份更加详细的文档:https://zhuanlan.zhihu.com/p/28728151
解释几点:
1)这个文章要 fix 的问题是 Unity 5.x 版本中对于线性空间烘焙处理的一个 Bug,这个 Bug 在 2017 版本中已经修复了,所以和题主遇到的问题并没有直接关系。所以文章的解决方法并不能解决题主的问题。
2)赞同 Alpha 通道抛弃掉必定有损,但是这是我们自己项目在观察美术烘焙好的 lm 贴图的 alpha 通道之后得出的结论——我们项目中 lm 贴图占用的内存尺寸和 Alpha 通道带来的效果提升相比,我们更倾向于损失后者,所以这是个取舍问题,建议各个项目根据自己的具体情况来定,所以并不赞同题主认为的不能丢弃的观点。
3)使用 unity_Lightmap_HDR 的确不正确,在我们项目中效果 “正确” 也只是看上去一样而已。我们也已经更改为 2017 fix 的正确答案:
另外,美术把贴图做得亮度偏低,然后通过打光来提高整体亮度,貌似很多美术喜欢这种做法… 我们美术在制定了线性空间下标准贴图亮度为 187 左右的情况下,还有部分场景故意使用较暗的贴图亮度。也可能是我们没给场景开 HDR 的原因。
感谢贾伟昊 @UWA 问答社区分享了该问答
欢迎大家转至社区交流: https://answer.uwa4d.com/question/5be90015a8b4ee66df69c250
渲染
Q:之前项目用 PPS V1 的 Tonemapping 时一直用的 Neutral 模式,最近感觉很多时候 ACES 调出的效果更好些。在 PC 端没问题,在手机上测试的时候发现 ACES 时在亮度很大的时候可能会出现奇怪的曝光效果。
试了骁龙 820,845 都出现这个问题,但是麒麟 970 反而没问题。类似下图:
Tonemaping 的设置:
Tonemaping 的设置:
反复查了很多遍,现在比较怀疑出问题的地方,是在 ACES 生成的 FP16 的 LUT 图,这个图的生成或者读取的数据似乎就出现了问题,在亮度最高的地方。但是就是查不到具体是哪块出的问题,Git 上下了最新版的 v1 也还是有这个问题,而且不管 HDR 设置成 FP16 还是 R11G11B10 都一样出现,不知道大家是否碰到类似的问题,怎么解决?
A:建议单独提取 ACES 而不是混在 LUT 里,ACES 库存在浮点数精度问题,进行 FilmicACES 的 RGB 通道值不要超过 100,一般 half 小数点后有 3 位有效精度,超过 100 很容易丢失小数精度出现问题。 如果同时使用 LUT 可能略有出入。总之相当于 color = clamp(color, 0.0, 100.0) 后再执行 TonemapFilmic(color, exposure)
感谢蒙占志 @UWA 问答社区回答了该问题
题主:的确是精度的问题,说下这个问题的定位思路:
先排除 bloom 的影响,反复调整 bloom 参数,在不用 tonmaping 前都不会出现这个问题。
使用 ColorGrading 流程:生成 HDR 的 LUT,采样 LUT 进行映射。采样代码很简单,测试下没发现问题。用 snapdragon 查看移动端 LUT,发现在高亮处出现了颜色缺失,怀疑是生成的 LUT 就有问题了,颜色越界或者 NaN?
再检查 ACES tonemapping 生成 LUT 的流程:sRGB 转 ACES –>ACES 中分别在 LogSpace 和 Linear Space 中进行颜色调整–>ACES 中进行 tonemapping –>ACES 转回 sRGB
分别注释几部分的代码观察问题变化,最后在第 3 部分 color = FilmicTonemap(aces) 前限制 ACES 的范围,aces =clamp(aces,0,4)(没错移动端安全范围就这么小…),这时候的 LUT 已经显示正常了,问题解决。
感谢题主分享了该经验
该回答来自 UWA 问答社区,欢迎大家转至社区交流:https://answer.uwa4d.com/question/5be544557b7ea841f3724a73
虚幻 & 渲染
Q:请问 Unreal 在手机上是直接用 Landscape 还是说把 Landscape 转成 StaticMesh 呢?如果用 Landscape,Section 选择 11 还是 22,顶点数有什么好工具可以优化吗?
UWA:建议直接使用 Landscape,我们之前在手机上做过测试,红米 2 这样的低端设备直接使用 landscape 也是没有问题,加上地表静态植被,配合动态场景加载,渲染效率可以到 30 多帧。landscape 的 Section 是 LOD 的变化单元,增加 Section 数量会增加 DrawCall,同时 LOD 变化计算开销也会增加。但是,更细粒度的 LOD 可以使得效果更好。如果从效率上考虑选择 1x1,如果从效果上考虑可以选择 2x2。顶点数量可以直接在做地形的时候进行设置,quad 的数量主要决定了一块地形里顶点数。最后总的顶点数是 componentCount x sectionPerComponent x quadPerSection + 1。默认情况下,顶点与顶点之间 x,y 轴上距离是 1m,因此顶点数量越多地形覆盖面积越大。不过也可以通过调整 Scale 来控制大小。
地形在内部存储的时候是使用的 Heightmap 的形式,也就是一张高度图。每个像素(32bit x 1)代表一个顶点,而 Staticmesh 则需要使用 x,y,z 三个坐标(32bit x 3),同时可能需要 Tangent,UV 坐标等,所以在存储方面地形会比 Staticmesh 要节省不少,这可能是使用地形的好处之一。再就是如果是用地形的 Foliage 刷地表物体,它默认是用了 ISM(Instanced Static Mesh)这样效率会高一些,当然如果用 StaticMesh 自己做也可以的,直接用地形的 Foliage 就稍微方便一点。LOD 的设置,我了解到的就是设置 Section 了,希望能对您有所帮助。
该回答由 UWA 提供,欢迎大家转至社区交流:https://answer.uwa4d.com/question/5be2b9c6f13b5823887f4ee3
堆内存
Q:关于 Unity 的 Mono 内存,我有两个问题:
1)堆内存占用突然上涨 30 多 MB,请问可能是由哪些因素引起的?
第一次测试
第二次测试
2)Mono 堆内存占用与逻辑代码堆内存分配有什么关系呢?UWA 提示都显示通过”Mono 详细堆内存分配报告 “来进行优化,但是为什么逻辑代码堆内存分配降低了,但是 Mono 堆内存占用反而上升了呢?
UWA:无论是测试一还是测试二,从一开始就 Reserverd Mono 较高(蓝色线条)且 Unused Mono(黄色线条)同样较高,这个是典型的游戏启动时大量堆内存分配且马上被 GC 掉所致。一般来说,这种情况常见于文件解压、配置文件加载所致。题主可以查看在游戏启动时是否确实存在如此操作。
Mono 堆内存的占用多少,其实就是你项目中逻辑代码的堆内存分配所致,只是有些会被 GC 回收,有些不会而已。对于第二次 Mono 从一开始就占据较高的堆内存,主要还是查看是否游戏启动时有大量文件的热更新、大量配置文件的加载。
由于你们的 Mono 堆内存是从一开始就升起的,建议题主可以直接通过 UWA GOT 工具的 Direct 模式来进行检测,该模式可以从游戏启动时进行记录,从而可以直接抓取到详细 Mono 堆内存是由哪些具体代码进行分配的,进而对其进行完善。
该回答由 UWA 提供,欢迎大家转至社区交流:https://answer.uwa4d.com/question/5be93221a8b4ee66df69c257
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在 UWA 问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之 “石”,也能攻你之 “玉”。
官网:www.uwa4d.com 官网: www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术 QQ 群:793972859(原群已满员)
0
0
0 / 200
发表评论
▎本文由 简悦 SimpRead 转码。