[Shader/渲染] Lightmap平台色差问题解决方案

查看:18712 |回复:70 | 2018-11-12 20:10:38

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 剑爆膀胱 于 2018-11-14 11:01 编辑



  • 其实问题已经解决,为了大家不用再踩这个坑,所以写下来方便大家搜索。

  • 问题描述
  • 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
  • 解决方案:拿原图重新编码,游戏中使用重新编码的贴图进行解析。这个方案比较靠谱,但是我这边测试做不出来。

  • 问题的进一步分析
  • 我这边已经基本上完全排除其他因素了,用新建的项目和同样的贴图、灯光对象,全部使用默认设置来烘培,这东西确实是引擎Bug,但有些项目却不会遇到,这让我感到困惑,这一定是制作流程问题。

  • 通过对比我发现,我们场景的贴图画得非常暗,而烘培使用了高亮度的烘培,而这个做法是不合理的,贴图那么暗(基本压到0.4以下),是一种严重的精度浪费,而光照强度也很不符合正常环境的亮度。

  • 所以如果没特殊原因,应该所有出问题的项目都是因为低亮度贴图强行烘亮的操作引起的。

  • 我个人认为最科学的解决方案
  • 以正常亮度为标准来绘制贴图,以符合现实世界强度的灯光参数来烘培场景,就不会出现这个问题了。不需要重新编码,也不需要实时解码,就可以避开这个引擎问题。但是如果有高亮度烘培的硬性需求的话,就必须自行编码重新保存了。
  • 感谢小黑@UWA问答社区分享了该经验,欢迎大家转至社区交流

  • 贾伟昊:解释两句。
  • 题主说的那个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 ... s-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问答社区分享了该问答

  • 欢迎大家转至社区交流:
  • https://answer.uwa4d.com/question/5be90015a8b4ee66df69c250
  • 渲染
  • Q:之前项目用PPS V1的Tonemapping时一直用的Neutral模式,最近感觉很多时候ACES调出的效果更好些。在PC端没问题,在手机上测试的时候发现ACES时在亮度很大的时候可能会出现奇怪的曝光效果。
  • 试了骁龙820,845都出现这个问题,但是麒麟970反而没问题。类似下图:
  • 810675be96e389bfbf.png
  • Tonemaping的设置: 901365be96e57d76f0.png
  • 反复查了很多遍,现在比较怀疑出问题的地方,是在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堆内存是由哪些具体代码进行分配的,进而对其进行完善。
  • 未命名-1.png

    评分

    参与人数 1活跃度 +20 展开 理由
    林夕Ker + 20 厉害了!我们之前也遇到过

    查看全部评分

    2018-11-12 20:10:38  
     赞 赞 0

    使用道具 登录

    70个回答,把该问题分享到群,邀请大神一起回答。
    2#
    从业不识微元素,做遍项目也枉然
    回复 收起回复
    2018-11-12 20:18:23   回复
     赞 赞 0

    使用道具 登录

    3#
    资源不错
    回复 收起回复
    2018-11-12 20:51:39   回复
     赞 赞 0

    使用道具 登录

    4#
    感谢分享     
    回复 收起回复
    2018-11-12 22:19:21   回复
     赞 赞 0

    使用道具 登录

    5#
    谢谢分享
    回复 收起回复
    2018-11-13 08:48:19   回复
     赞 赞 0

    使用道具 登录

    6#
    : Lightmap平台色差问题解决方案 [修改]
    回复 收起回复
    2018-11-13 08:53:24   回复
     赞 赞 0

    使用道具 登录

    7#
    回复 收起回复
    2018-11-13 09:05:10   回复
     赞 赞 0

    使用道具 登录

    8#
    想要成大触,天天上元素!
    回复 收起回复
    2018-11-13 09:05:14   回复
     赞 赞 0

    使用道具 登录

    9#
    资源哪里好,肯定元素找
    回复 收起回复
    2018-11-13 09:46:42   回复
     赞 赞 0

    使用道具 登录

    10#
    感谢分享
    回复 收起回复
    2018-11-13 09:49:22   回复
     赞 赞 0

    使用道具 登录

    11#
    感谢分享
    回复 收起回复
    2018-11-13 09:49:24   回复
     赞 赞 0

    使用道具 登录

    12#
    感谢分享
    回复 收起回复
    2018-11-13 09:49:26   回复
     赞 赞 0

    使用道具 登录

    13#
    感谢分享
    回复 收起回复
    2018-11-13 09:49:29   回复
     赞 赞 0

    使用道具 登录

    14#
    nice
    回复 收起回复
    2018-11-13 09:51:54   回复
     赞 赞 0

    使用道具 登录

    15#
    不错的资源,谢谢分享
    回复 收起回复
    2018-11-13 14:58:52   回复
     赞 赞 0

    使用道具 登录

    16#
    感谢分享,点赞
    回复 收起回复
    2018-11-13 15:26:12   回复
     赞 赞 0

    使用道具 登录

    17#
    谢谢分享
    回复 收起回复
    2018-11-13 16:59:10   回复
     赞 赞 0

    使用道具 登录

    18#
    干货
    谢谢
    回复 收起回复
    2018-11-14 11:39:47   回复
     赞 赞 0

    使用道具 登录

    19#
    元素那么大,我想来看看
    回复 收起回复
    2018-11-14 15:14:46   回复
     赞 赞 0

    使用道具 登录

    20#
    回复 收起回复
    2018-11-14 17:31:55   回复
     赞 赞 0

    使用道具 登录

    CG 游戏行业专业问题

    Unity3D技术手机游戏引擎手游引擎
    1234下一页
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表