|
先上效果
泛光时颜色过白
修复后
起因是在虚幻5里做卡通渲染,但是虚幻官方的风格就是追求写实,泛光当然会变白,所以就变成如上图的样子了。场景也许很好看,但是放到原画画的卡通角色怪物等身上就不太好了,原本粉色尾巴发光的样子变成橙色且发白,发生严重的偏色。
首先是找到根本原因
虚幻官方文档
根本原因是4.27之后虚幻更换了Tonemapping曲线,从Legacy换成了Filmic,也就是ACES的tonemapping曲线(别人的aces感觉没那么白),总之一切锅就是aces的tonemapping,
但是我们又不能简单地换成其他曲线,因为这个曲线对于整个场景就是好看不少(确实)
我们来康康renderdoc就清楚了
我们能看到流程是先bloom,再生成colorgrading和tonemap等效果的ColorLUTS纹理,然后再tonemap里进行最终处理
我们可以在PostProcessTonemap里看到处理的过程,是先AddBloom
float3 BloomDirtMaskColor = Texture2DSample(BloomDirtMaskTexture, BloomDirtMaskSampler, DirtLensUV * .5f + .5f).rgb * BloomDirtMaskTint.rgb;
LinearColor += CombinedBloom.rgb * (1.0 + BloomDirtMaskColor);然后进行颜色映射
half3 OutDeviceColor = ColorLookupTable(LinearColor);问题找到之后就是解决方法了
最开始想到的是用gbuffer标记角色不执行tonemap,但是发现行不通,原因是postprocess整个流程的最初先进行TAA,TAA会根据velocity进行边缘颜色混合,所以TAA之后的gbuffer提供的mask全部失效,tonemap在最后一个pass里,所以这个方法行不通
第二种方法是提前在后处理之前进行反向Tonemap,这个就比较复杂了(不过后面可能继续研究,角色本身不bloom也可能有色差问题)目前想到的方法是利用CombineLUTS pass,在renderdoc里把tonemap之后的处理删掉,得到一张到tonemap为止的32x32x32的LUTS纹理图,等于我们有正向的LUTS就能写工具求出逆向的LUTS,但是问题感觉也有很多,我第一个疑问就是为什么32x32x32的颜色纹理映射处理后图像不会丢失精度,按理说256变成32精度丢失会很严重,第二个是正向的LUTS是通过Log2来把线性颜色压缩到0-1来取样的,我反向会不会又有精度问题,反正这里面感觉坑很多。
第三种方式感觉是个比较简单,改动也比较少的方案。因为最大的问题就是Bloom泛白,那只需要解决Bloom区域就好了。
BloomGrey = AddBloom.r * 0.299f + AddBloom.g * 0.587f + AddBloom.b * 0.144f;所以我在最终的tonemap pass里,在取得了Bloom部分之后计算他的明度来作为颜色过渡的值
在颜色映射之后用这个值去和原来的linearcolor做lerp,同时我们不希望完全lerp回去,所以外部传一个值去控制
OutDeviceColor = lerp(OutDeviceColor, LinearColor, BloomTonemapReduce * clamp(BloomGrey,0,0.7f));当然实验的时候改shader重载就好了,但是为了方便外部控制还是需要在引擎增加属性,在postprocesstonemap的pass里进行shaderparameter的绑定,这里可以参照filmwhiteclip等现有的参数去改
(友情提醒,postprocess里有个函数专门去检查每个参数的前缀,建议命名自觉和现有参数统一前缀,我就这样浪费了三小时编译时间)
气死了
新增的参数
lerp 0.7就到这个样子了
bloom本身就根据明度进行高斯模糊的,如果强度越大泛白也是正确的,但是UE的tonemap让泛光的部分太白了,但是完全拉回去的话颜色会变得比较死板,所以我感觉适当压一下就好
我感觉我这个方法比较野,但是这样既能满足泛光不过百,场景又保持ue本身tonemap的特点,应该也算一种解决方案吧 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|