当前位置:   article > 正文

Photoshop图层混合模式公式(Unity,CG实现)_ps图层效果 算法

ps图层效果 算法

本文主要目的来自于在unity符合美术在ps里面的演示效果。

两个图层叠加到一起的效果,废话不多说直接看效果:

图片资源在文章末尾

完整代码也在末尾

目录

目录

Multiply 正片叠底

 Screen 滤色

 Color Dodge 颜色减淡

 Color Burn 颜色加深

Linear Dodge 线形减淡

Linear Burn 线形加深

Overlay 叠加

 Hard Light 强光

Soft Light 柔光

亮光 vivid light

Linear Light 线形光

Pin Light 点光

Hard Mix 实色混合

Difference 差值

Excusion 排除

Hue 色相

HSV那几个模式异常说明:

完整代码:

测试效果图片资源:


Multiply 正片叠底

公式:

Ans = A * B;

half4 finalRGBA = half4(colorA.xyz * colorB.xyz,1);

效果对比:

核心代码:

half4 finalRGBA =  half4(1 - (1 - colorA.xyz) * (1 -colorB.xyz),1);

 Screen 滤色

公式:

Ans = 1 - (1 - colorA ) * (1 - colorB);

效果对比:

 核心代码:

half4 finalRGBA =  half4(1 - (1 - colorA.xyz) * (1 -colorB.xyz),1);

 Color Dodge 颜色减淡
 

公式:

ans=colorA / ( 1 - colorB);

效果对比:(unity存在些许过曝的情况)

核心代码:

finalRGBA = half4(colorA.xyz * (rcp(1 - colorB.xyz)),1);

 Color Burn 颜色加深

公式:

ans=1 -  (1 - colorA)/ colorB;

效果对比:

核心代码:

finalRGBA = half4(1- rcp(colorB.xyz) * (1 - colorA.xyz),1);

Linear Dodge 线形减淡

公式:

Ans  = colorA + colorB;

 效果对比:

核心代码:

finalRGBA = half4(colorB.xyz + colorA.xyz,1);

Linear Burn 线形加深

公式:

 Ans  = colorA + colorB  - 1 ;

效果对比:

核心代码:

finalRGBA = half4(colorB.xyz + colorA.xyz - 1,1);

Overlay 叠加


公式:


colorB<=0.5 :  Ans=2*colorA*colorB
colorB>0.5: Ans=1 - 2 * (1-colorA) * ( 1 - colorB)

效果对比:

核心代码:

  1. half3 c1 = colorA.xyz * colorB.xyz * 2 *OA ;
  2. half3 c2 = (1 - 2 * (1 - colorA.xyz) *(1 - colorB.xyz)) * (1 - OA);
  3. finalRGBA = half4(c1+ c2,1);

 Hard Light 强光

公式:

colorA <= 0.5:  Ans = 2 * colorA * colorB
colorA > 0.5   : Ans = 1 - 2 * (1 - colorA) * (1 - colorB)

效果对比:

核心代码:

  1. half3 OB = step(colorB.xyz,0.5);
  2. half3 c1 = colorA.xyz * colorB.xyz * 2 *OB ;
  3. half3 c2 = (1 - 2 * (1 - colorA.xyz) *(1 - colorB.xyz)) * (1 - OB);

Soft Light 柔光

公式:



colorA <= 0.5 : Ans = ( 2 * A - 1 ) * ( B - B * B ) + B;
colorA > 0.5 : Ans = ( 2 * A - 1 ) * ( sqrt ( B ) - B ) + B;

效果对比:

核心代码:

  1. half3 OB = step(colorB.xyz,0.5);
  2. half3 c1 = ((2 * colorB - 1) * (colorA - colorA * colorA) + colorA) * OB ;
  3. half3 c2 = ((2 * colorB - 1) * (sqrt(colorA)- colorA) + colorA) * (1 - OB);

亮光 vivid light

效果与ps中存在部分差异,但目前没找到原因,盲猜是因为自己没有模拟出图层上下级关系。

公式:

colorB <= 0.5 :  Ans = colorA - (1 - colorA) * ( 1 - 2 * colorB) / (2 * colorB);

colorB > 0.5  :  Ans = colorA + colorA * (2 * colorB - 1)/(2 * (1 - colorB));

效果对比:

上下层级不同的情况下(unity没有层级)

 

核心代码:

  1. float3 c1 = colorB - (1 - colorB) * (1 - 2 * colorA) / (2 * colorA);
  2. float3 c2 = colorB + colorB * (2 * colorA - 1) / (2 * (1 - colorA));
  3. float3 OB = step(colorA.xyz,0.5);
  4. c1 *= OB;
  5. c2 *= (1 - OB);
  6. finalRGBA = float4(c1+ c2,1);

Linear Light 线形光


公式:

Ans = colorB + 2 * colorA - 1;

效果对比:

核心代码:

finalRGBA = float4(colorA + 2 * colorB) - 1;

Pin Light 点光

公式:

colorB < 2 * colorA - 1 :  Ans = 2 * colorA - 1;

 2 * A - 1 < B < 2 * A    :  Ans = colorB;
colorB > 2 * colorA      :  Ans = 2 * colorA;

效果展示:

核心代码:

  1. half3 OB = step(colorA,2 *colorB - 1);
  2. half3 c1 = (2 * colorB - 1) * OB;
  3. half3 OB1 = (1 - OB) * step(colorA , 2 * colorB);
  4. half3 c2 = colorA * OB1;
  5. half3 OB2 = 1 - step(colorA ,2 * colorB);
  6. half3 c3 = 2 * colorB * OB2;
  7. finalRGBA = half4(c1 + c2 + c3,1);

Hard Mix 实色混合


公式:


colorA < 1 - colorB :  Ans = 0;
colorA > 1 - colorB :  Ans = 1;

效果展示:

核心代码:

  1. half3 OA = step(colorB, 1 - colorA);
  2. half3 c1 = 0 * OA;
  3. half3 OA1 = step(1 - colorA,colorB);
  4. half3 c2 = 1 * OA1;
  5. finalRGBA = half4(c1 + c2,1);

Difference 差值

公式:

Ans=|colorA-colorB|

效果展示:

核心代码:

finalRGBA = half4(abs(colorB.xyz - colorA.xyz),1);

Excusion 排除

公式:

Ans=colorA+colorB-(colorA×colorB) * 2

效果展示:

核心代码:

finalRGBA = half4(colorB + colorA - 2 * colorB * colorA);

Hue 色相

公式:


Ans( HSV) =HB SA  VA

(HSV空间下) Ans = (colorB.x,colorA.y,colorB.z);

该效果再HSV空间下进行计算(后续需要转化为RGB)

效果展示:

 核心代码:

  1. float3 c1 = float3(colorBHSV.x,colorAHSV.yz);
  2. c1 = HSV2RGB(c1);
  3. finalRGBA = half4(c1,1);

HSV那几个模式异常说明:

  • 这几个模式按照公式去计算并不能正常的得到目标结果所以,复刻不出来但是不是很懂怎么回事经测试转颜色空间并无差别且计算并无问题,具体的的混合算法来源也无差别出自官方文档维基百科等都是显示该结果,或为还有部分转化过程,待查证。
  • 饱和度混合模式保留底层的亮度和色调,同时采用顶层的色度。
  • 颜色混合模式保留底层的亮度,同时采用顶层的色调和色度。
  • 亮度混合模式保留底层的色调和色度,同时采用顶层的亮度。、

颜色混合未完待续。

完整代码:

  1. Shader "Unlit/TestPs"
  2. {
  3. Properties
  4. {
  5. _MainTexA ("TextureA", 2D) = "white" {}
  6. _MainTexB ("TextureB", 2D) = "white" {}
  7. }
  8. SubShader
  9. {
  10. Tags { "RenderType"="Opaque" }
  11. LOD 100
  12. Pass
  13. {
  14. CGPROGRAM
  15. #pragma vertex vert
  16. #pragma fragment frag
  17. // make fog work
  18. #pragma multi_compile_fog
  19. #include "UnityCG.cginc"
  20. struct appdata
  21. {
  22. float4 vertex : POSITION;
  23. float2 uv : TEXCOORD0;
  24. };
  25. struct v2f
  26. {
  27. float4 uv : TEXCOORD0;
  28. float4 vertex : SV_POSITION;
  29. };
  30. float3 RGB2HSV(float3 c)
  31. {
  32. float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
  33. float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g));
  34. float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r));
  35. float d = q.x - min(q.w, q.y);
  36. float e = 1.0e-10;
  37. return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
  38. }
  39. // Official HSV to RGB conversion
  40. float3 HSV2RGB( float3 c ){
  41. float3 rgb = clamp( abs(fmod(c.x*6.0+float3(0.0,4.0,2.0),6)-3.0)-1.0, 0, 1);
  42. rgb = rgb*rgb*(3.0-2.0*rgb);
  43. return c.z * lerp( float3(1,1,1), rgb, c.y);
  44. }
  45. sampler2D _MainTexA;
  46. float4 _MainTexA_ST;
  47. sampler2D _MainTexB;
  48. float4 _MainTexB_ST;
  49. v2f vert (appdata v)
  50. {
  51. v2f o;
  52. o.vertex = UnityObjectToClipPos(v.vertex);
  53. o.uv.xy = TRANSFORM_TEX(v.uv.xy, _MainTexA);
  54. o.uv.zw = TRANSFORM_TEX(v.uv.xy, _MainTexB);
  55. UNITY_TRANSFER_FOG(o,o.vertex);
  56. return o;
  57. }
  58. half4 frag (v2f i) : SV_Target
  59. {
  60. float4 colorA = tex2D(_MainTexA, i.uv.xy);
  61. float colorALum = Luminance(colorA.xyz);
  62. float4 colorB = tex2D(_MainTexB, i.uv.zw);
  63. float3 colorAHSV = RGB2HSV(colorA.xyz);
  64. float3 colorBHSV = RGB2HSV(colorB.xyz);
  65. float colorBLum = Luminance(colorA.xyz);
  66. float4 finalRGBA = 0;
  67. // opacity 正片叠底
  68. finalRGBA = float4(colorA.xyz * colorB.xyz,1);
  69. // Screen 滤色
  70. // finalRGBA = float4(1 - (1 - colorA.xyz) * (1 -colorB.xyz),1);
  71. // Color Dodge 颜色减淡
  72. // finalRGBA = float4(colorA.xyz * (rcp(1 - colorB.xyz)),1);
  73. // Color Burn 颜色加深
  74. // finalRGBA = float4(1- rcp(colorB.xyz) * (1 - colorA.xyz),1);
  75. // Linear Dodge 线形减淡
  76. // finalRGBA = float4(colorB.xyz + colorA.xyz,1);
  77. // Linear Burn 线形加深
  78. // finalRGBA = float4(colorB.xyz + colorA.xyz - 1,1);
  79. // overlay 叠加
  80. // float3 OA = step(colorA.xyz,0.5);
  81. // float3 c1 = colorA.xyz * colorB.xyz * 2 *OA ;
  82. // float3 c2 = (1 - 2 * (1 - colorA.xyz) *(1 - colorB.xyz)) * (1 - OA);
  83. // finalRGBA = float4(c1+ c2,1);
  84. // hard light 强光
  85. // float3 OB = step(colorB.xyz,0.5);
  86. // float3 c1 = colorA.xyz * colorB.xyz * 2 *OB ;
  87. // float3 c2 = (1 - 2 * (1 - colorA.xyz) *(1 - colorB.xyz)) * (1 - OB);
  88. // soft light 柔光
  89. // float3 OB = step(colorB.xyz,0.5);
  90. // float3 c1 = ((2 * colorB - 1) * (colorA - colorA * colorA) + colorA) * OB ;
  91. // float3 c2 = ((2 * colorB - 1) * (sqrt(colorA)- colorA) + colorA) * (1 - OB);
  92. // vivid light 亮光///
  93. // float3 c1 = colorB - (1 - colorB) * (1 - 2 * colorA) / (2 * colorA);
  94. // float3 c2 = colorB + colorB * (2 * colorA - 1) / (2 * (1 - colorA));
  95. // float3 OB = step(colorA.xyz,0.5);
  96. // c1 *= OB;
  97. // c2 *= (1 - OB);
  98. // finalRGBA = float4(c1+ c2,1);
  99. // linear Light 线性光
  100. // finalRGBA = float4(colorA + 2 * colorB) - 1;
  101. // 点光(存在等于符号问题)
  102. // B<2*A-1: C=2*A-1
  103. // 2*A-1<B<2*A: C=B
  104. // B>2*A: C=2*A
  105. // float3 OB = step(colorA,2 *colorB - 1);
  106. // float3 c1 = (2 * colorB - 1) * OB;
  107. // float3 OB1 = (1 - OB) * step(colorA , 2 * colorB);
  108. // float3 c2 = colorA * OB1;
  109. // float3 OB2 = 1 - step(colorA ,2 * colorB);
  110. // float3 c3 = 2 * colorB * OB2;
  111. // finalRGBA = float4(c1 + c2 + c3,1);
  112. // 混合实色
  113. // float3 OA = step(colorB, 1 - colorA);
  114. // float3 c1 = 0 * OA;
  115. // float3 OA1 = step(1 - colorA,colorB);
  116. // float3 c2 = 1 * OA1;
  117. // finalRGBA = float4(c1 + c2,1);
  118. // 差值
  119. // finalRGBA = float4(abs(colorB.xyz - colorA.xyz),1);
  120. // Excusion 排除
  121. // finalRGBA = float4(colorB + colorA - 2 * colorB * colorA);
  122. // hue 色相
  123. // float3 c1 = float3(colorBHSV.x,colorAHSV.yz);
  124. // c1 = HSV2RGB(c1);
  125. // finalRGBA = half4(c1,1);
  126. return finalRGBA;
  127. }
  128. ENDCG
  129. }
  130. }
  131. }

测试效果图片资源:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/116334
推荐阅读
相关标签
  

闽ICP备14008679号