参考:Unity 颜色空间(Color Space)转换_Unity鼓励师的博客-CSDN博客
大多数情况下,我们的项目使用的是Linear 颜色空间,但是又希望UI的显示是在Gamma 颜色空间,因为Gamma 空间下的ui能够正常显示,Linear下的UI显示会有颜色偏差,主要原因在于两个颜色空间下的透明度混合公式不一致:
Linear Color Space
ret = (srcColor^2.2 * srcAlpha + dstColor^2.2 * (1 - srcAlpha) ) ^(1/2.2)
Gamma Color Space
ret = srcColor * srcAlpha + dstColor * (1 - srcAlpha)
下面的代码挂载在Camera上即可:
Linear 颜色空间:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UICameraLinearCorrect : MonoBehaviour
{
private Material mat;
private Material RenderMat
{
get
{
if (mat == null)
{
mat = Resources.Load<Material>("Materials/UILinearCorrectMat");
}
return mat;
}
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source, destination, RenderMat);
}
}
Shader "MyShader/UILinearCorrectShader"
{
Properties
{
_MainTex("Main Tex", 2D) = "white"{}
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
//Blend SrcAlpha OneMinusSrcAlpha
Pass
{
Cull Off ZWrite Off ZTest Always
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 color = tex2D(_MainTex, i.uv);
color = pow(color, 2.2);
return color;
}
ENDCG
}
}
}
Gamma 颜色空间:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SceneCameraLinearCorrect : MonoBehaviour
{
private Material mat;
private Material RenderMat
{
get
{
if (mat == null)
{
mat = Resources.Load<Material>("Materials/SceneLinearCorrectMat");
}
return mat;
}
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source, destination, RenderMat);
}
}
Shader "MyShader/SceneLinearCorrectShader"
{
Properties
{
_MainTex("Main Tex", 2D) = "white"{}
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
//Blend SrcAlpha OneMinusSrcAlpha
Pass
{
// 制作后处理shader的时候要把这几个属性设置上
Cull Off ZWrite Off ZTest Always
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 color = tex2D(_MainTex, i.uv);
color = pow(color, 1.0 / 2.2);
return color;
}
ENDCG
}
}
}