目录

Unity-HDR颜色基础颜色强度强度HDR面板Intensity之间的相互转换

Unity HDR颜色、基础颜色、强度强度、HDR面板Intensity之间的相互转换


前言:

HDR(高动态范围成像),相比LDR(低动态范围成像)能够带来更好的画面效果,随着移动设备性能的提升,越来越多的设备都支持HDR模式。而在Unity中,如何在基础颜色以及HDR颜色之间相互转换,是这篇文章的主题。

一、UnityHDR面板的规律

https://i-blog.csdnimg.cn/direct/88343dcc95884546b05d09bc87d34ab0.png https://i-blog.csdnimg.cn/direct/7ae6ff7c348b4af3bceb9e0aa5a41d5c.png https://i-blog.csdnimg.cn/direct/0cfeb5e4bf6047e1b78ea76ee9d8a1ce.png

上面有三张图,第一张是一张简单的红色HDR配置面板,第二张是我改变Intensity,HDR面板的数值,而第三张则是在我确认输入Intensity后关闭面板再打开的HDR面板。

为什么最后确认输入打开的面板数值,和我设置看到的面板数值有不同了?

实际上,Unity在用户输入Intensity时和最终得到的intensity意义是有所不同的。它们之间做了一个转换与解压。

以下算法将会解答你的疑问。

二、HDR与基础颜色转换,HDR强度获取,输入设置强度获取

这个算法能帮助需要制作调色板功能的用户,对HDR颜色和基础色颜色之间进行自由操作。

1.基础色->HDR颜色

    //baseColor指代基础色,比如图1的红色(1,0,0,1)
    //intensity指代输入强度,比如图2输入的强度数值2
    internal static Color HDRColor(Color baseColor, float intensity)
    {
        return baseColor * Mathf.Pow(2f, intensity);
    }

很简单吧,基础色到HDR颜色,就是进行了一个Pow操作。

2.HDR颜色->基础色

     //其中hdrColor指代需要进行转换的HDR颜色,这个函数返回一个没有HDR的基础色
    //比如图3的hdr颜色数值(4,0,0,1),转换后就会得到图1的颜色数值(1,0,0,1)
    internal static Color32 DecomposeHdrColor(Color hdrColor)
    {
        Color32 baseColor = hdrColor;
        float maxColorComponent = hdrColor.maxColorComponent;
        if (maxColorComponent == 0f || (maxColorComponent <= 1f && maxColorComponent >= 0.003921569f))
        {
            baseColor.r = (byte)Mathf.RoundToInt(hdrColor.r * 255f);
            baseColor.g = (byte)Mathf.RoundToInt(hdrColor.g * 255f);
            baseColor.b = (byte)Mathf.RoundToInt(hdrColor.b * 255f);
        }
        else
        {
            float num = 255f / maxColorComponent;
            baseColor.r = Math.Min((byte)255, (byte)Mathf.CeilToInt(num * hdrColor.r));
            baseColor.g = Math.Min((byte)255, (byte)Mathf.CeilToInt(num * hdrColor.g));
            baseColor.b = Math.Min((byte)255, (byte)Mathf.CeilToInt(num * hdrColor.b));
        }
        return baseColor;
    }

3.获取HDR颜色在面板中的强度

//hdrColor就是需要进行获取的HDR颜色,此函数返回HDR颜色在编辑器中最终显示的强度
//比如图3的HDR颜色,它的强度在面板显示是2.416924,这个函数就会返回这个数值
internal static float GetHdrIntensity(Color hdrColor)
    {
        float maxColorComponent = hdrColor.maxColorComponent;
        if (maxColorComponent == 0f || (maxColorComponent <= 1f && maxColorComponent >= 0.003921569f))
        {
            return 0f;
        }
        else
        {
            float num = 191f / maxColorComponent;
            return Mathf.Log(255f / num) / Mathf.Log(2f);
        }
    }

4.获取HDR颜色在面板设置输入时的强度

//hdrColor指代需要解压的HDR颜色,此函数返回在HDR颜色设置面板输入的强度
//比如图3,它的HDR颜色为(4,0,0,1),它返回的输入强度就是图2的输入强度2
 internal static float DecomposeHdrIntensity(Color hdrColor)
    {
        float maxColorComponent = hdrColor.maxColorComponent;
        if (maxColorComponent == 0f || (maxColorComponent <= 1f && maxColorComponent >= 0.003921569f))
        {
            return 0f;
        }
        else
        {
            float num = 255f / maxColorComponent;
            return Mathf.Log(255f / num) / Mathf.Log(2f);
        }
    }

以上便是HDR颜色与基础色之间的操作。