内容简介:这是第136篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。问题描述PC上烘培,转到安卓平台即可复现,但非所有项目都会遇到这个问题。我使用的Unity版本是2017.4.6f1,经过测试2017.4.14f1依然存在这个问题。色差具体表现有亮度降低和色相变化。
这是第136篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。
UWA 问答社区:answer.uwa4d.com UWA 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)的纯橙色,这就是我们看到色差的原因。
解决方案探索
在解决问题的过程中搜索到了这两个链接:
解决方案:测试出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
解决方案:拿原图重新编码,游戏中使用重新编码的贴图进行解析。这个方案比较靠谱,但是我这边测试做不出来。
问题的进一步分析
我这边已经基本上完全排除其他因素了,用新建的项目和同样的贴图、灯光对象,全部使用默认设置来烘培,这东西确实是引擎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的正确答案:
inline half3 DecodeLightmapDoubleLDR( fixed4 color )
{
float multiplier = IsGammaSpace() ? 2.0f : GammaToLinearSpace(2.0f).x;
return multiplier * color.rgb;
}
inline half3 GammaToLinearSpace (half3 sRGB)
{
// Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);
// Precise version, useful for debugging.
//return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
}
另外,美术把贴图做得亮度偏低,然后通过打光来提高整体亮度,貌似很多美术喜欢这种做法...我们美术在制定了线性空间下标准贴图亮度为187左右的情况下,还有部分场景故意使用较暗的贴图亮度。也可能是我们没给场景开HDR的原因。
感谢贾伟昊@UWA问答社区分享了该问答
渲染
Q:之前项目用PPS V1的Tonemapping时一直用的Neutral模式,最近感觉很多时候ACES调出的效果更好些。在PC端没问题,在手机上测试的时候发现ACES时在亮度很大的时候可能会出现奇怪的曝光效果。
试了骁龙820,845都出现这个问题,但是麒麟970反而没问题。类似下图:
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已经显示正常了,问题解决。
虚幻&渲染
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
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(原群已满员)
以上所述就是小编给大家介绍的《Lightmap平台色差问题解决方案》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Hadoop小文件解决方案-基于文件整合的解决方案
- Hadoop小文件解决方案-基于NameNode内存和MapReduce性能解决方案
- 10 种跨域解决方案(附终极方案)
- React 服务端渲染方案完美的解决方案
- 跨域解决方案
- 异步解决方案---promise
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Web Development Recipes
Brian P. Hogan、Chris Warren、Mike Weber、Chris Johnson、Aaron Godin / Pragmatic Bookshelf / 2012-1-22 / USD 35.00
You'll see a full spectrum of cutting-edge web development techniques, from UI and eye candy recipes to solutions for data analysis, testing, and web hosting. Make buttons and content stand out with s......一起来看看 《Web Development Recipes》 这本书的介绍吧!