[Unity] UnityShader:HSV(色相,饱和度,亮度)转换

查看:8158 |回复:87 | 2015-12-29 15:11:43

您需要 登录 才可以下载或查看,没有账号?注册

x
http://blog.csdn.net/costfine/article/details/46930473

发现其实美术调整颜色的时候大部分都是调整的HSV,因为可以方便的分别调整色相(hue)、饱和度(saturation)和色调(value)。例如人们要将颜色调整的偏红一点,那么只需要修改色相, 如果使用RGB的话,就需要同时调整3个值,仅仅只是增加R值的话,理论上讲,只是把红色值加重了而已。就算是平时使用的调色板,大部分也是按照HSV来的,例如U3D的调色板:
20150717171107096.jpg
颜色空间有很多中,RGB、HSL、HSV、CMYK...等等好多,如果有兴趣的话可以去搜搜。但我们这里只用HSV 。比如一张贴图是红色系的,我们要改成绿色系,只需要将hue值偏移到绿色值就好了。各种颜色空间转换的公式:http://www.easyrgb.com/index.php?X=MATH&H=22#text22方法我们知道了,公式也有了,下面直接写代码。
  1. Shader "Tornado/ColorGradation_HSV" {
  2.     Properties {
  3.         //贴图
  4.         _MainTex ("MainTex (RGB)", 2D) = "white" {}
  5.         //Hue的值范围为0-359. 其他两个为0-1 ,这里我们设置到3,因为乘以3后 都不一定能到超过.
  6.         _Hue ("Hue", Range(0,359)) = 0
  7.         _Saturation ("Saturation", Range(0,3.0)) = 1.0
  8.         _Value ("Value", Range(0,3.0)) = 1.0
  9.     }
  10.     SubShader {
  11.     Pass {
  12.         Tags { "RenderType"="Opaque" }
  13.         LOD 200

  14.         Lighting Off

  15.         CGPROGRAM
  16.         #pragma vertex vert_img
  17.         #pragma fragment frag
  18.         #include "UnityCG.cginc"


  19.         sampler2D _MainTex;
  20.         half _Hue;
  21.         half _Saturation;
  22.         half _Value;

  23.         struct Input {
  24.             float2 uv_MainTex;
  25.         };

  26.         //RGB to HSV
  27.         float3 RGBConvertToHSV(float3 rgb)
  28.         {
  29.             float R = rgb.x,G = rgb.y,B = rgb.z;
  30.             float3 hsv;
  31.             float max1=max(R,max(G,B));
  32.             float min1=min(R,min(G,B));
  33.             if (R == max1)
  34.             {
  35.                 hsv.x = (G-B)/(max1-min1);
  36.             }
  37.             if (G == max1)
  38.             {
  39.                 hsv.x = 2 + (B-R)/(max1-min1);
  40.                 }
  41.             if (B == max1)
  42.             {
  43.                 hsv.x = 4 + (R-G)/(max1-min1);
  44.                 }
  45.             hsv.x = hsv.x * 60.0;   
  46.             if (hsv.x < 0)
  47.                 hsv.x = hsv.x + 360;
  48.             hsv.z=max1;
  49.             hsv.y=(max1-min1)/max1;
  50.             return hsv;
  51.         }

  52.         //HSV to RGB
  53.         float3 HSVConvertToRGB(float3 hsv)
  54.         {
  55.             float R,G,B;
  56.             //float3 rgb;
  57.             if( hsv.y == 0 )
  58.             {
  59.                 R=G=B=hsv.z;
  60.             }
  61.             else
  62.             {
  63.                 hsv.x = hsv.x/60.0;
  64.                 int i = (int)hsv.x;
  65.                 float f = hsv.x - (float)i;
  66.                 float a = hsv.z * ( 1 - hsv.y );
  67.                 float b = hsv.z * ( 1 - hsv.y * f );
  68.                 float c = hsv.z * ( 1 - hsv.y * (1 - f ) );
  69.                 switch(i)
  70.                 {
  71.                     case 0: R = hsv.z; G = c; B = a;
  72.                         break;
  73.                     case 1: R = b; G = hsv.z; B = a;
  74.                         break;
  75.                     case 2: R = a; G = hsv.z; B = c;
  76.                         break;
  77.                     case 3: R = a; G = b; B = hsv.z;
  78.                         break;
  79.                     case 4: R = c; G = a; B = hsv.z;
  80.                         break;
  81.                     default: R = hsv.z; G = a; B = b;
  82.                         break;
  83.                 }
  84.             }
  85.             return float3(R,G,B);
  86.         }      

  87.         fixed4 frag (v2f_img i) : SV_Target
  88.         {
  89.             fixed4 original = tex2D(_MainTex, i.uv);    //获取贴图原始颜色

  90.             float3 colorHSV;   
  91.             colorHSV.xyz = RGBConvertToHSV(original.xyz);   //转换为HSV
  92.             colorHSV.x += _Hue; //调整偏移Hue值
  93.             colorHSV.x = colorHSV.x%360;    //超过360的值从0开始

  94.             colorHSV.y *= _Saturation;  //调整饱和度
  95.             colorHSV.z *= _Value;                           

  96.             original.xyz = HSVConvertToRGB(colorHSV.xyz);   //将调整后的HSV,转换为RGB颜色

  97.             return original;
  98.         }
  99.         ENDCG
  100.     }
  101.     }
  102.     FallBack "Diffuse"
  103. }
点击此处复制文本

原图和调整Hue后的对比,像不像以前玩格斗游戏,两个玩家选同一个角色,然后2P变色的效果…
   20150717172323961.jpg
同样的也可以应用到摄像机特效上….瞬间改变场景的氛围

当然还可以调整饱和度和亮度。。。饱和度调整到0就成了黑白图了
参考
http://blog.csdn.net/idfaya/article/details/6770414



评分

参与人数 1元素币 +30 活跃度 +20 贡献值 +1 展开 理由
元素界王神 + 30 + 20 + 1 阅贴无数,楼主最强!

查看全部评分

2015-12-29 15:11:43  
 赞 赞 1

使用道具 登录

87个回答,把该问题分享到群,邀请大神一起回答。
2#
但是这样染色 有的颜色并不好控制吧 也不方便小范围有选择性的修改
回复 收起回复
2015-12-29 15:45:52   回复
 赞 赞 1

使用道具 登录

3#
123
回复 收起回复
2015-12-29 16:07:47   回复
 赞 赞 1

使用道具 登录

4#
Arthasづ 发表于 2015-12-29 15:45
但是这样染色 有的颜色并不好控制吧 也不方便小范围有选择性的修改

嗯,一般项目都不太会这样马虎的处理,就是看看原理
回复 收起回复
2015-12-29 17:18:43   回复
 赞 赞 1

使用道具 登录

5#
谢谢楼主分享
回复 收起回复
2015-12-30 10:24:38   回复
 赞 赞 1

使用道具 登录

6#

谢谢楼主分享
回复 收起回复
2016-1-5 15:44:36   回复
 赞 赞 1

使用道具 登录

7#
立刻提起了精神
回复 收起回复
2016-5-10 19:09:48   回复
 赞 赞 1

使用道具 登录

8#
立刻提起了精神
回复 收起回复
2016-5-10 19:09:49   回复
 赞 赞 1

使用道具 登录

9#
感谢楼主分享
回复 收起回复
2016-5-13 14:50:34   回复
 赞 赞 1

使用道具 登录

10#
呵呵呵呵呵呵呵呵呵呵
回复 收起回复
2016-5-14 21:40:28   回复
 赞 赞 1

使用道具 登录

11#
学习了
回复 收起回复
2016-6-3 17:39:22   回复
 赞 赞 1

使用道具 登录

12#
学习了
回复 收起回复
2016-6-21 10:07:13   回复
 赞 赞 1

使用道具 登录

13#
学习了
回复 收起回复
2016-6-21 10:07:17   回复
 赞 赞 1

使用道具 登录

14#
学习了
回复 收起回复
2016-6-21 10:07:21   回复
 赞 赞 1

使用道具 登录

15#
谢谢分享!可以方便初学者了解shader原理,实用价值不大。
回复 收起回复
2016-6-26 08:30:26   回复
 赞 赞 1

使用道具 登录

16#
确实是个快捷的办法,但是不能通用滥用。。。。
回复 收起回复
2016-8-15 13:58:45   回复
 赞 赞 1

使用道具 登录

17#
{:1_151:}
回复 收起回复
2016-9-5 09:42:09   回复
 赞 赞 1

使用道具 登录

18#
学习了
回复 收起回复
2016-9-22 12:50:27   回复
 赞 赞 1

使用道具 登录

19#
那这样这个shader的实用性就
回复 收起回复
2016-10-20 14:17:53   回复
 赞 赞 1

使用道具 登录

20#
加油加油  给力给力
回复 收起回复
2016-10-20 15:19:23   回复
 赞 赞 1

使用道具 登录

CG 游戏行业专业问题

Unity3D技术手机游戏引擎手游引擎
12345下一页
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表