关于Unity gamma校正

现实 => 捕捉设备 => 显示器 => 显示图像
encoding decoding
1/2.2 2.2
1.liner空间
图片本身亮度与显示的亮度成线性相关 y=x
2.sRGB空间(encoding)
输入与输出亮度成幂相关 y = x ^ (1/2.2)
3.crt显示颜色 (decoding)
由于显示器硬件特点 输入与输出的亮度成幂相关 y = x ^ 2.2
后面的显示器 为了兼容
会自己做一个gamma校正 让sRGB的图正常显示
4.sRGB刚好补偿crt偏暗的颜色
5.unity
a.gamma 模式 不作任何校正 (ps也是此模式)
流程 sRGB(1/2.2) ->显示器(2.2)
b.liner 模式 sRGB勾选 认为图片是sRGB空间的 先进行gamma校正 到liner空间
不勾选 认为你是liner空间的 就不处理
在进行所有的计算完成之后
会进行反gamma 提亮图片 来补偿显示器
流程 sRGB(1/2.2) -> unity sRGB转换(2.2) ->unity liner 反gamma(1/2.2) ->显示器(2.2)

问题:
1.ps出的图到unity liner图片下面 变亮了
主要是因为 unity liner 最后会做一个 反gamma 提亮的操作
没有勾选sRGB 流程 sRGB(1/2.2) ->unity liner 反gamma(1/2.2) ->显示器(2.2) 最终结果1/2.2 变亮
勾选了sRGB 就是上面的通用流程
2.sRGB勾选之后 透明度有误差
因为透明度是线性的 在“unity sRGB转换(2.2)”这个节点 没有对alpha进行变换 但是在“unity liner 反 gamma(1/2.2)”这个节点进行了反变换
liner模式 ret = (srcColor^2.2 * srcAlpha + dstColor^2.2 * (1 - srcAlpha) ) ^(1/2.2)
gamma模式 ret = srcColor * srcAlpha + dstColor * (1 - srcAlpha)
目前只能用pow2.2的方法来修正一下混合问题

以上是我综合了一大堆我看不懂的文章之后,写了一点我能看懂的知识
贴一下参照吧
这个参照没图也是难受

贴一下我自己修改的shader UI-Default的代码吧

Shader "UI/GammaAdjust"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)

        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255

        _ColorMask ("Color Mask", Float) = 15
		
		_AlphaAdjust("Alpha Adjust", Float) = 2.2

        [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp]
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]
        }

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask [_ColorMask]

        Pass
        {
            Name "Default"
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0

            #include "UnityCG.cginc"
            #include "UnityUI.cginc"

            #pragma multi_compile __ UNITY_UI_CLIP_RECT
            #pragma multi_compile __ UNITY_UI_ALPHACLIP

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                float2 texcoord  : TEXCOORD0;
                float4 worldPosition : TEXCOORD1;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            sampler2D _MainTex;
            fixed4 _Color;
            fixed4 _TextureSampleAdd;
            float4 _ClipRect;
            float4 _MainTex_ST;
			float _AlphaAdjust;

            v2f vert(appdata_t v)
            {
                v2f OUT;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
                OUT.worldPosition = v.vertex;
                OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

                OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);

                OUT.color = v.color * _Color;
                return OUT;
            }

            fixed4 frag(v2f IN) : SV_Target
            {
                half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
				
                #ifdef UNITY_UI_CLIP_RECT
                color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
                #endif

                #ifdef UNITY_UI_ALPHACLIP
                clip (color.a - 0.001);
                #endif

				color.a = pow(color.a, 2.2); //主要加了这么一句话
                return color;
            }
        ENDCG
        }
    }
}

color.a = pow(color.a, 2.2); 就加了这么一句话
搞个Material贴到UIImage的Material框就行了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中的Gamma空间模型是一种颜色空间模型,用于描述计算机图形中的颜色显示和计算方式。在Gamma空间模型中,计算机图形使用的颜色值会根据人类视觉系统的特性进行调整,以更好地适应人类的视觉感知。 在Gamma空间模型中,颜色值会经过一个Gamma校正的过程。这是因为人类眼睛在感知亮度时对不同光强的变化有不同的感知能力。Gamma校正可以调整颜色值中的亮度信息,使得较暗的颜色更容易被人眼感知,而较亮的颜色则会被衰减,以便在显示设备上更好地还原真实场景中的亮度级别。 在Unity中,Gamma空间模型是默认的颜色空间模型。它的工作原理是将颜色从sRGB空间(标准的RGB颜色空间)转换到线性空间,并在渲染完毕后再将颜色转回到sRGB空间,以便正确显示。 Gamma空间模型在图形渲染中起到重要作用。由于人眼对亮度的感知非线性,使用Gamma空间模型可以使渲染的图像更加逼真和准确。而在一些特殊的情况下,使用线性空间模型可能会导致图像亮度不平衡或者颜色失真的问题。 总结起来,Unity中的Gamma空间模型是一种能够根据人类视觉系统特性进行颜色调整的模型,能够使渲染图像更加真实和准确。通过使用Gamma校正,它可以调整颜色的亮度信息,以适应人眼对亮度的感知能力。而相对于线性空间模型,在大部分情况下,Gamma空间模型能够提供更好的图像表现效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值