部分顏色混合模式的公式如下:

覺着挺實用的,寫個shader來嘗試一下看看效果。
因為這里都是混合模式,所以需要兩張圖片,但是我們對攝像機的內容進行后處理,只有1個圖層,所以我就把A和B都使用相同內容來處理。
很明顯A和B圖層內容相同的話前兩個公式變量和變暗肯定是沒有效果的,我們從第三個公式來嘗試。
首先把公式放到shader里,像這樣:
//正片疊底
fixed4 Muitiply(fixed4 _color){
fixed r = pow(_color.r,2);
fixed g = pow(_color.g,2);
fixed b = pow(_color.b,2);
return fixed4(r,g,b,1.0f);
}
圖片公式中的顏色值都是按照0-255來計算的,而我們的shader里顏色值是0-1,所以我們要把公式中的所有顏色值除以255來得到0-1范圍的顏色值。經過換算后,代碼中的公式就變成了上面的樣子。
_color為一個像素點,對像素的rgb值分別進行計算,透明度這里不考慮,直接填1.0即可。
看看效果:

第一張是原圖,第二張是photoshop里正片疊底的效果,第三張是我們在unity中看到效果。
可以看到unity中得到的結果與photoshop中還是基本一致的,下面我們再試試其他的公式。
這次我們看一下濾色,相應的shader代碼如下:
//濾色
fixed4 Screen(fixed4 _color){
fixed r = 1-(pow((1-_color.r),2));
fixed g = 1-(pow((1-_color.g),2));
fixed b = 1-(pow((1-_color.b),2));
return fixed4(r,g,b,1.0f);
}
效果圖:

效果也基本一致,看來我們的思路是正確的,這樣看來上面圖片中給出的那些公式我們都可以正常使用。
這里我們只是對一張圖片做了處理,我們看一下應用在場景里的效果:

經過處理后場景感覺更明亮一些,除了上面圖片中的公式,其實還有一個比較常用的,就是去色,像王者榮耀里面玩家死亡后的效果,只要知道了公式實現起來也是非常簡單的,我們只要讓rgb各自都取它們的平均值就可以了,像這樣:
fixed4 DelColor(fixed4 _color){
fixed c = _color.r + _color.g + _color.b;
c /= 3;
return fixed4(c,c,c,1.0f);
}
效果:

好了,按照慣例上完整代碼
shader內容:
Shader "Custom/ColorCompute" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Pass{
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert_img
#pragma fragment frag
uniform sampler2D _MainTex;
//去色
fixed4 DelColor(fixed4 _color){
fixed c = _color.r + _color.g + _color.b;
c /= 3;
return fixed4(c,c,c,1.0f);
}
//曝光
21
fixed4 Exposure(fixed4 _color,fixed force){
22
fixed r = min(1,max(0,_color.r * pow(2,force)));
23
fixed g = min(1,max(0,_color.g * pow(2,force)));
24
fixed b = min(1,max(0,_color.b * pow(2,force)));
25
return fixed4(r,g,b,1.0f);
26
}
27
//顏色加深
28
fixed4 ColorPlus(fixed4 _color){
29
fixed r = 1-(1-_color.r)/_color.r;
30
fixed g = 1-(1-_color.g)/_color.g;
31
fixed b = 1-(1-_color.b)/_color.b;
32
return fixed4(r,g,b,1.0f);
33
}
34
//顏色減淡
35
fixed4 ColorMinus(fixed4 _color){
36
fixed r = _color.r + pow(_color.r,2)/(1-_color.r);
37
fixed g = _color.g + pow(_color.g,2)/(1-_color.g);
38
fixed b = _color.b + pow(_color.b,2)/(1-_color.b);
39
return fixed4(r,g,b,1.0f);
40
}
41
//濾色
42
fixed4 Screen(fixed4 _color){
43
fixed r = 1-(pow((1-_color.r),2));
44
fixed g = 1-(pow((1-_color.g),2));
45
fixed b = 1-(pow((1-_color.b),2));
46
return fixed4(r,g,b,1.0f);
47
}
48
//正片疊底
49
fixed4 Muitiply(fixed4 _color){
50
fixed r = pow(_color.r,2);
51
fixed g = pow(_color.g,2);
52
fixed b = pow(_color.b,2);
53
return fixed4(r,g,b,1.0f);
54
}
55
//強光
56
fixed4 ForceLight(fixed4 _color){
57
fixed r = 1-pow((1-_color.r),2) / 0.5f;
58
fixed g = 1-pow((1-_color.g),2) / 0.5f;
59
fixed b = 1-pow((1-_color.b),2) / 0.5f;
60
if(_color.r < 0.5f) r = pow(_color.r,2)/0.5f;
61
if(_color.g < 0.5f) g = pow(_color.g,2)/0.5f;
62
if(_color.b < 0.5f) b = pow(_color.b,2)/0.5f;
63
return fixed4(r,g,b,1.0f);
64
}
65
float4 frag( v2f_img o ) : COLOR
66
{
67
fixed4 _color = tex2D(_MainTex, o.uv);
68
_color = DelColor(_color);
69
return _color;
70
}
71
ENDCG
72
}
73
}
74
FallBack "Diffuse"
75
}
攝像機腳本:
1
[ExecuteInEditMode]
2
public class ColorCompute : MonoBehaviour {
3
public Material m;
4
void OnRenderImage(RenderTexture src, RenderTexture dest)
5
{
6
Graphics.Blit(src, dest, m);
7
}
8
}