基本调色

  • 亮度:表示颜色的明暗程度,亮度的公式为 :luminance = 0.2125 * col.r + 0.7154 * col.g + 0.0721 * col.b,调节亮度是通过颜色的RGB直接与亮度系数相乘

  • 饱和度:彩色偏离同亮度灰色的程度,饱和度大,偏离越大,色彩越鲜艳,可以通过lerp同亮度的灰色和当前颜色来调整

  • 对比度:指的是一幅图像中明暗区域最亮的白和最暗的黑之间的差距,对比度越大,差距越大,可以通过lerp(0.05,0.5,0.5)的灰色和当前颜色来调整

    fixed4 renderTex = tex2D(_MainTex, i.uv);
    //调节亮度
    fixed3 finalColor = renderTex.rgb * _Brightness;
    //获取亮度值
    fixed luminance = luminanceFun(finalColor);
    fixed3 luminanceColor = fixed3(luminance, luminance, luminance);
    //调节饱和度
    finalColor = lerp(luminanceColor, finalColor, _Saturation);
    fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
    //调节对比度
    finalColor = lerp(avgColor, finalColor, _Contrast);
    

ToneMapping

ToneMapping用于HDR到LDR的转换,也就是亮度需要通过函数将取值范围从0-N(N可以远大于1)转化到0-1,目前使用最多的是ACES方案,其公式为

1
2
3
4
5
6
7
8
9
10
11
float3 ACESToneMapping(float3 color, float adapted_lum)
{
const float A = 2.51f;
const float B = 0.03f;
const float C = 2.43f;
const float D = 0.59f;
const float E = 0.14f;

color *= adapted_lum;
return (color * (A * color + B)) / (color * (C * color + D) + E);
}

它的曲线是这样的

这使得在HDR中亮度在0.07以下和0.73以上的颜色会变暗,而在0.07到0.73的颜色会变亮


Lut Color Adjust

Lut调色是通过Look Up Table来对画面进行风格化处理,简单来说就是通过某种形式来将一个颜色映射到另一个颜色。其主要需要解决的是如果进行映射,很容易想到的是通过将R,G,B三个数值作为坐标,形成一个三维的坐标系,用一个3D的立方体存储映射信息,这种存储方式称为3D查找表,其缺点是有较大的内存消耗。

因此往往使用它的简化版1D查找表,其简化形式是将B通道变为梯度式的,让立方体变成一张张图片然后将图片按B通道的大小顺序拼接成一张图,让R和B通道共同决定uv的x,让G通道决定uv的y来采样图片获得映射颜色。

需要注意的是,由于在x轴上,R通道的数值是会在每张图片之间从发生1->0的变化,考虑到精度误差,需要在采样时往中心偏移来防止R通道数值的异常

代码如下:

float boxNum = floor((_Width + 1.0f) / _Height);
float maxColor = boxNum - 1;
float threshold = maxColor / boxNum;
//偏移半格,使得偏移后的采样区域的两边空隙都为半格大小
float halfOffsetX = 0.5 / _Width;
float halfOffsetY = 0.5 / _Height;
float xOffset = halfOffsetX + mainColor.r * threshold / boxNum;
float yOffset = halfOffsetY + mainColor.g * threshold;
float cell = floor(mainColor.b * maxColor);
float2 lutUV = float2(cell / boxNum + xOffset, yOffset);
float3 lutColor = tex2D(_LutTex, lutUV);
float3 finalColor = lerp(mainColor, lutColor, _LutRate);