whoimi

A geek blog

View on GitHub

UnrealLightmap结构和编码

光度图编码方式

​ 由于光照亮度的生成时其亮度范围远大于1的浮点数区间,故其最好的存储方式应当是浮点纹理,比如通用的exr格式。exr的缺点是更大的存储、内存和渲染时的带宽占用,同时有多平台兼容性问题,故目前主流的商业引擎或各大厂的自研引擎,其在移动端的光照图也大都使用RGB8或RGBA8图进行存储。

​ 把亮度数据从浮点数压缩到0~256的整数时需要进行编码进行存储(UE4中编码这一部分也叫做量化),通过此编码映射把无限范围的浮点数域映射到有限的[0,255]的整数域中,其压缩方式是有损的,在压缩过程中的信息损失会造成光照图的质量的下降和不可逆失真。

​ UE4中光照亮度编码映射没有采用传统的RGBM,RGBD,LOGLUV方式编码,而是使用自己开发的编码方式,分别对LQ和HQ光照的亮度信息进行压缩。

LQ编码

这部分代码在LightmapData.cpp源文件当中查看:

会对亮度信息进行编码,预乘之后,写入lightmap编码:

值域偏移0.5是为了把亮度x∈[0,1]之间的y的值域从[-0.5,0]平移到[0,0.5]之间,不丢失暗部信息?

log结果除以16,有两个好处,一是可以把更多的原始亮度信息编码到值域中。原本按照 y∈[0,1]的约束,log(x+0.00390625)的中x取值范围约为x∈[0,1.41],而在除了16之后,x的取值范围大约在x∈[0,255]之间。二是因为需要预乘颜色和亮度值,较小的亮度值乘以颜色可以很大程度规避掉数值上的上溢出。这部分来自网络,需要重新计算

使用y的最大和最小值对归一化参数进行变换,其变换公式为

N_mul = 1 /(max-min)

N_add = -min/(max-min)