Unity怎么调背景颜色_待解决


什么是颜色迁移

简单的讲,就是将一张图片A的颜色分布转移到另一张图片B上,其中B称为原图片,A称为目标图片。例如下面的例子,b是原图片,a是目标图片,c是做迁移之后生成的图片。算法很多人都讲过,可以参考这篇https://zhuanlan.zhihu.com/p/37018069。


Unity怎么调背景颜色_标准差_02

图片来自论文:https://www.cs.tau.ac.il/~turkel/imagepapers/ColorTransfer.pdf


为什么要在Unity中实现

离线的版本很多人都实现过,那么实时的颜色迁移会怎么样呢,每帧之间怎么变化呢,不做实验不知道,所以就在后处理中用Compute Shader实现了,流程如下:


Unity怎么调背景颜色_待解决_03


其中颜色迁移公式如下:


Unity怎么调背景颜色_标准差_04


k指的是lab(三通道分别计算),S为原图像,T为目标图像,μ为图像均值,σ为图像标准差。至于rgb和lab的转换,论文里讲的很详细,不再赘述。

遇到的坑

在计算均值和标准差时,GPU内的数据同步问题,要么用原子计算,要么用barrier。barrier用了DeviceMemoryBarrierWithGroupSync没使成功,只是用了原子加法,但是原子加法只支持整型,只好牺牲精度了。

还有,如果对整张图片求均值和标准差是很耗性能的,所以做了下采样再计算的。

感觉GPU和CPU的数据同步,以及GPU内部的数据同步,对实时图像处理造成不小的困难。

结果如何

还不错,对一个场景使用了不同目标图片的话,会产生有趣的效果。

原场景如下,来自Unity的3D Game Kit。


Unity怎么调背景颜色_Unity怎么调背景颜色_05

原场景

用了吉卜力风格的图片做迁移:


Unity怎么调背景颜色_unity游戏中提示信息如何实现_06

吉卜力风格的图片

Unity怎么调背景颜色_数据同步_07

结果图片

用了赛博朋克风格的图片做迁移:


Unity怎么调背景颜色_Unity怎么调背景颜色_08

赛博朋克风格的图片

Unity怎么调背景颜色_数据同步_09

结果图片

用了新海诚风格的图片做迁移:


Unity怎么调背景颜色_数据同步_10

新海诚风格的图片

Unity怎么调背景颜色_Unity怎么调背景颜色_11

结果图片

代码

代码还是GitHub:

alpacasking/PostProcessingLibgithub.com

Unity怎么调背景颜色_标准差_12


有两个问题待解决:

  • 每帧之间的颜色迁移不是连续的
  • lab颜色空间的精度不够高