文章目录
 

Blog

解决Unity线性空间光照贴图在移动端变暗的问题

  |   DroyLouo, Sundries   |   No comment

便于搜索:

Unity光照贴图变暗;Unity移动端光照贴图变暗;Unity移动端烘焙变暗;Unity光照贴图平台间表现不一致;Unity线性空间移动端光照贴图变暗;

A method to solve difference of lightmap on PC and Mobile platform in Unity.

Unity lightmap become darker on mobile after build.

省流版:明日方舟同款,把lightmap(.exr)改default,A通道挪到shadowmask的G通道,改一下lightmap解算方式,还能大幅压缩贴图。

TLDR: Same as <Arknights>: change lightmap(.exr) to default type, move the A channel to shadowmask’s G channel. Tweak lightmap decoding algorithm. Select more efficient compress format.

There is no English translation for the details. The overall content is not complicated, and perhaps Google Translate is able to help you understand, maybe. 😛

来源为UnityCN 2020年线上技术大会:

【[Unity 活动]-游戏专场|初创团队的曲折开发前行之路-《明日方舟》中3D和2D结合方案】 【精准空降到 37:17】 https://www.bilibili.com/video/av755481241/?t=2237

这个解决方案相较于知乎上的https://zhuanlan.zhihu.com/p/28728151,平台间差异更小,且可以使用更激进的贴图压缩方式。

(↑它说Unity解决了,根本没解决捏,明日方舟是Unity2017 BIRP,本文的测试环境是Unity2022 URP。这是平台特性DLDR导致的,除非移动端能使用和PC一致的带透明通道HDR图片压缩方式,要么别用线性空间,不然就是会有色差。)

解决了在线性空间下,烘焙后的光照贴图在移动端的压缩方式下,光照信息明显变暗,导致相较于编辑期环境内明显变暗的问题,并且丢弃了原始光照贴图的A通道以可以使用更激进的贴图压缩方式。

限制条件:

  • 光照模式为Shadowmask

BakedIndirect也许不行,因为这种模式两张图六个通道都有数据,没空地了。Subtractive没用没试不知道;

  • 烘焙时Directional Mode为Non-Directional

是Directional应该也行,只是需要修改的hlsl会多一些,我这没改,但原理应该是一样的。

  • 没有修改Terrain等处的SH采样方法

因为不会改。

  • 没有适配同时开启了实时GI的情况和动态Lightmap的情况

确定要给移动端用这个?

  • 解决方案代码没有最佳优化,也并没有解决非光照贴图下的DLDR不一致

又不是不能用。

 

环境:

Unity2022.3,URP 14,仅Vulkan(编辑器也是Vulkan)。

准备工作:

把URP、SRP-Core的package从\Library\PackageCache挪到 \Packages,要改这两个包的代码。

具体步骤:

1、 改HLSL

(SRP-Core的)EntityLighting.hlsl:

DecodeLightmap:加一个shadowmask采样参数。对RGBM的采样也改一下,这样确保在编辑期下看到的是和打包到移动端是基本一致的。

UnpackLightmapRGBM:加一个shadowmask采样参数

UnpacklightmapDoubleLDRW:加一个shadowmask采样参数

(URP的)GlobalIllumination.hlsl:

SampleLightmap & SampleSingleLightmap

把非动态lightmap且无directional lightmap的方法改了。其他的我这没改,但原理差不多。加一个shadowmask参数,这个过程需要加几个当参数的TEXTURE2D_LIGHTMAP_PARAM或者类似的宏,照着原有的写就行了,并且顺便把Vulkan、D3D11和用到的API的都写了,不然编辑器也会报错。

把 SAMPLE_GI宏改一下,再在LIGHTMAP_NAME 宏旁边加一个SHADOWMASK_NAME 宏

 

2、 对光照贴图进行处理

演示一个单次处理的。用GetPixels()拿图像数据,然后逐像素操作(嫌慢可以开个job),然后new一个Texture2D,用File.WriteAllBytes写成文件。

这样两张贴图都没有Alpha通道,可以使用一些比较舒适的压缩方式,比如ASTC。

处理完成后,comp_shadowmask上的R和G各论各的。

解包后看到单张1024分辨率的贴图为1.19m,可喜可贺。

实际测试比对编辑器、PC端、Android的截图后发现仅有微小色差,于纯Shadowmask的shadow模式,Forward+ path、Mixed的DirectionalLight及若干Mixed的SpotLight和PointLight的较为明亮鲜艳的固有色环境下,RGB各色色差基本都在5以内,差不多就是贴图压缩方式的区别了。

 

 

附1:用PS打开lightmap exr和shadowmask啥也看不出来,保存还会存一堆乱七八糟的数据,GIMP也没法操作,不如直接Editor内操作完事了。

附2:实际上只用了不到一天就弄完了,有笨蛋的手机一直在暴风闪退还以为API改坏了,结果换了台手机就好了,他奶奶的。

No Comments

Post A Comment