{"id":1513,"date":"2016-06-07T17:38:08","date_gmt":"2016-06-07T09:38:08","guid":{"rendered":"http:\/\/www.clonefactor.com\/wordpress\/?p=1513"},"modified":"2016-07-27T19:42:24","modified_gmt":"2016-07-27T11:42:24","slug":"shader-hsbc","status":"publish","type":"post","link":"https:\/\/www.clonefactor.com\/wordpress\/program\/unity3d\/1513\/","title":{"rendered":"Shader HSBC"},"content":{"rendered":"<p>\u53c3\u8003:\u00a0<a href=\"http:\/\/forum.unity3d.com\/threads\/hue-saturation-brightness-contrast-shader.260649\/\">http:\/\/forum.unity3d.com\/threads\/hue-saturation-brightness-contrast-shader.260649\/<\/a>\u00a0\u7684\u6587\u7ae0<\/p>\n<p>\u53e6\u5916\u91cd\u5beb\u4e00\u500b\u53ef\u52d5\u614b\u4fee\u6539\u7684 shader.<\/p>\n<p><iframe loading=\"lazy\" title=\"Texture HSBC\" width=\"1260\" height=\"709\" src=\"https:\/\/www.youtube.com\/embed\/_3VbJtRFP7I?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe><\/p>\n<p>\u4fee\u6539\u5f8c\u7684\u4ee3\u78bc<\/p>\n<pre class=\"brush:ruby\">Shader \"Unlit\/Texture HSBC\" {\r\n\tProperties\r\n\t{\r\n\t\t_MainTex(\"Base (RGB), Alpha (A)\", 2D) = \"black\" {}\r\n\t\t_Hue(\"Hue\", Range(0, 1.0)) = 0\r\n\t\t_Saturation(\"Saturation\", Range(0, 1.0)) = 0.5\r\n\t\t_Brightness(\"Brightness\", Range(0, 1.0)) = 0.5\r\n\t\t_Contrast(\"Contrast\", Range(0, 1.0)) = 0.5\r\n\t}\r\n\r\n\tSubShader\r\n\t{\r\n\t\tLOD 100\r\n\t\tTags\r\n\t\t{\r\n\t\t\t\"Queue\" = \"Transparent\"\r\n\t\t\t\"IgnoreProjector\" = \"True\"\r\n\t\t\t\"RenderType\" = \"Transparent\"\r\n\t\t}\r\n\r\n\t\tCull Off\r\n\t\tLighting Off\r\n\t\tZWrite On\r\n\t\tFog{ Mode Off }\r\n\t\tOffset -1, -1\r\n\t\tBlend SrcAlpha OneMinusSrcAlpha\r\n\r\n\t\tPass\r\n\t\t{\r\n\t\t\tCGPROGRAM\r\n\t\t\t#pragma vertex vert\r\n\t\t\t#pragma fragment frag\r\n\r\n\t\t\t#include \"UnityCG.cginc\"\r\n\r\n\t\t\t\/\/ Function\r\n\t\t\tinline float3 applyHue(float3 aColor, float aHue)\r\n\t\t\t{\r\n\t\t\t\tfloat angle = radians(aHue);\r\n\t\t\t\tfloat3 k = float3(0.57735, 0.57735, 0.57735);\r\n\t\t\t\tfloat cosAngle = cos(angle);\r\n\t\t\t\t\/\/Rodrigues' rotation formula\r\n\t\t\t\treturn aColor * cosAngle + cross(k, aColor) * sin(angle) + k * dot(k, aColor) * (1 - cosAngle);\r\n\t\t\t}\r\n\r\n\r\n\t\t\tinline float4 applyHSBEffect(float4 startColor, fixed4 hsbc)\r\n\t\t\t{\r\n\t\t\t\tfloat hue = 360 * hsbc.r;\r\n\t\t\t\tfloat saturation = hsbc.g * 2;\r\n\t\t\t\tfloat brightness = hsbc.b * 2 - 1;\r\n\t\t\t\tfloat contrast = hsbc.a * 2;\r\n\r\n\t\t\t\tfloat4 outputColor = startColor;\r\n\t\t\t\toutputColor.rgb = applyHue(outputColor.rgb, hue);\r\n\t\t\t\toutputColor.rgb = (outputColor.rgb - 0.5f) * contrast + 0.5f + brightness;\r\n\t\t\t\toutputColor.rgb = lerp(Luminance(outputColor.rgb), outputColor.rgb, saturation);\r\n\t\t\t\t\r\n\t\t\t\treturn outputColor;\r\n\t\t\t}\r\n\r\n\r\n\t\t\tstruct appdata_t\r\n\t\t\t{\r\n\t\t\t\tfloat4 vertex : POSITION;\r\n\t\t\t\tfloat2 texcoord : TEXCOORD0;\r\n\t\t\t\tfixed4 color : COLOR;\r\n\t\t\t};\r\n\r\n\t\t\tstruct v2f\r\n\t\t\t{\r\n\t\t\t\tfloat4 vertex : SV_POSITION;\r\n\t\t\t\thalf2 texcoord : TEXCOORD0;\r\n\t\t\t\tfixed4 hsbc : COLOR;\r\n\t\t\t};\r\n\r\n\t\t\tsampler2D _MainTex;\r\n\t\t\tfixed _Hue, _Saturation, _Brightness, _Contrast;\r\n\r\n\t\t\tv2f vert(appdata_t v)\r\n\t\t\t{\r\n\t\t\t\tv2f o;\r\n\t\t\t\to.vertex = mul(UNITY_MATRIX_MVP, v.vertex);\r\n\t\t\t\to.texcoord = v.texcoord;\r\n\t\t\t\to.hsbc = fixed4(_Hue, _Saturation, _Brightness, _Contrast);\r\n\t\t\t\treturn o;\r\n\t\t\t}\r\n\r\n\t\t\tfixed4 frag(v2f i) : COLOR\r\n\t\t\t{\r\n\t\t\t\tfloat4 startColor = tex2D(_MainTex, i.texcoord);\r\n\t\t\t\tfloat4 hsbColor = applyHSBEffect(startColor, i.hsbc);\r\n\t\t\t\treturn hsbColor;\r\n\t\t\t}\r\n\t\t\tENDCG\r\n\t\t} \/\/ Pass\r\n\t} \/\/ SubShader\r\n\r\n\tSubShader\r\n\t{\r\n\t\tLOD 100\r\n\t\tTags\r\n\t\t{\r\n\t\t\t\"Queue\" = \"Transparent\"\r\n\t\t\t\"IgnoreProjector\" = \"True\"\r\n\t\t\t\"RenderType\" = \"Transparent\"\r\n\t\t}\r\n\r\n\t\tPass\r\n\t\t{\r\n\t\t\tCull Off\r\n\t\t\tLighting Off\r\n\t\t\tZWrite Off\r\n\t\t\tFog{ Mode Off }\r\n\t\t\tOffset -1, -1\r\n\t\t\tColorMask RGB\r\n\t\t\t\/\/AlphaTest Greater .01\r\n\t\t\tBlend SrcAlpha OneMinusSrcAlpha\r\n\t\t\tColorMaterial AmbientAndDiffuse\r\n\r\n\t\t\tSetTexture[_MainTex] { Combine Texture * Primary }\r\n\t\t} \/\/ Pass\r\n\t} \/\/ SubShader\r\n}<\/pre>\n<p>\u63a5\u8457\u5728 Unity3D \u56e0\u70ba\u9805\u76ee\u8981\u6c42\u9700\u8981\u5230\u540c\u6642\u4fee\u6539\u4e00\u7cfb\u5217\u7684 shader HSBC, \u6240\u4ee5\u5206\u5225\u5efa\u7acb\u4ee5\u4e0b\u7684\u7d44\u4ef6:<\/p>\n<pre class=\"brush:csharp\">struct HSBC : IEquatable&lt;HSBC&gt;\r\n{\r\n\tpublic float Hue, Saturation, Brightness, Contrast;\r\n\tpublic HSBC(float hue, float saturation, float brightness, float contrast)\r\n\t{\r\n\t\tHue = hue;\r\n\t\tSaturation = saturation;\r\n\t\tBrightness = brightness;\r\n\t\tContrast = contrast;\r\n\t}\r\n\r\n\tpublic bool Equals(HSBC other)\r\n\t{\r\n\t\treturn\r\n\t\t\tMathf.Approximately(Hue, other.Hue) &amp;&amp;\r\n\t\t\tMathf.Approximately(Saturation, other.Saturation) &amp;&amp;\r\n\t\t\tMathf.Approximately(Brightness, other.Brightness) &amp;&amp;\r\n\t\t\tMathf.Approximately(Contrast, other.Contrast);\r\n\t}\r\n\r\n\tpublic void LerpTo(HSBC target, float t)\r\n\t{\r\n\t\tHue = LerpNear(Hue, target.Hue, t);\r\n\t\tSaturation = LerpNear(Saturation, target.Saturation, t);\r\n\t\tBrightness = LerpNear(Brightness, target.Brightness, t);\r\n\t\tContrast = LerpNear(Contrast, target.Contrast, t);\r\n\t}\r\n\r\n\tprivate float LerpNear(float current, float target, float t)\r\n\t{\r\n\t\treturn (Mathf.Approximately(current, target)) ? target : Mathf.Lerp(current, target, t);\r\n\t}\r\n}<\/pre>\n<p>\u7136\u5f8c\u5be6\u969b\u4f7f\u7528\u7684\u5143\u4ef6\u9762\u7248.<\/p>\n<pre class=\"brush:csharp\">using UnityEngine;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\n\r\npublic class CWorldMapColorHandler : CSingleton&lt;CWorldMapColorHandler&gt;\r\n{\r\n\tpublic Shader m_TargetShader;\r\n\tpublic List&lt;Material&gt; m_MaterialList = new List&lt;Material&gt;();\r\n\r\n\t[Range(0f,1f)]\r\n\tpublic float\r\n\t\tm_Hue = 0f,\r\n\t\tm_Saturation = 0.5f,\r\n\t\tm_Brightness = 0.5f,\r\n\t\tm_Contrast = 0.5f;\r\n\r\n\tHSBC m_Last;\r\n\tHSBC m_Current { get { return new HSBC(m_Hue, m_Saturation, m_Brightness, m_Contrast); } }\r\n\r\n\t[ContextMenu(\"Register Child Renderer\")]\r\n\tvoid OnValidate()\r\n\t{\r\n\t\t\/\/ Ensure all related material reference in the list.\r\n\t\tList&lt;MeshRenderer&gt; renders = GetComponentsInChildren&lt;MeshRenderer&gt;().ToList();\r\n\t\tforeach (MeshRenderer render in renders)\r\n\t\t{\r\n\t\t\tfor (int i = 0; i &lt; render.sharedMaterials.Length; i++)\r\n\t\t\t{\r\n\t\t\t\tif (render.sharedMaterials[i] == null || render.sharedMaterials[i].shader.GetInstanceID() != m_TargetShader.GetInstanceID())\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\tif (!m_MaterialList.Any(o =&gt; o.GetHashCode() == render.sharedMaterials[i].GetHashCode()))\r\n\t\t\t\t\tm_MaterialList.Add(render.sharedMaterials[i]);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tnew void Awake()\r\n\t{\r\n\t\tbase.Awake();\r\n\t\tm_Last = new HSBC(m_Hue, m_Saturation, m_Brightness, m_Contrast);\r\n\t}\r\n\t\r\n\tvoid Update()\r\n\t{\r\n\t\tif(!m_Current.Equals(m_Last))\r\n\t\t{\r\n\t\t\tm_Last.LerpTo(m_Current, Time.deltaTime);\r\n\t\t\t\/\/ direct change Material values, 3 loops, change sharedMaterials 237 loops\r\n\t\t\tforeach(Material mat in m_MaterialList)\r\n\t\t\t{\r\n\t\t\t\tmat.SetFloat(\"_Hue\", m_Last.Hue);\r\n\t\t\t\tmat.SetFloat(\"_Saturation\", m_Last.Saturation);\r\n\t\t\t\tmat.SetFloat(\"_Brightness\", m_Last.Brightness);\r\n\t\t\t\tmat.SetFloat(\"_Contrast\", m_Last.Contrast);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tnew void OnDestroy()\r\n\t{\r\n\t\tbase.OnDestroy();\r\n\r\n\t\t\/\/ reset material color.\r\n\t\tforeach (Material mat in m_MaterialList)\r\n\t\t{\r\n\t\t\tmat.SetFloat(\"_Hue\", 0f);\r\n\t\t\tmat.SetFloat(\"_Saturation\", .5f);\r\n\t\t\tmat.SetFloat(\"_Brightness\", .5f);\r\n\t\t\tmat.SetFloat(\"_Contrast\", .5f);\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>\u53c3\u8003\u6587\u4ef6 :<\/p>\n<p><a href=\"http:\/\/wiki.unity3d.com\/index.php?title=Shader_Code\">http:\/\/wiki.unity3d.com\/index.php?title=Shader_Code<\/a><\/p>\n<p><a href=\"http:\/\/www.graficaobscura.com\/matrix\/\">http:\/\/www.graficaobscura.com\/matrix\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u53c3\u8003:\u00a0http:\/\/forum.unity3d.com\/threads\/hue-saturatio &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[88,11],"tags":[],"class_list":["post-1513","post","type-post","status-publish","format-standard","hentry","category-shader","category-unity3d"],"_links":{"self":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts\/1513","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1513"}],"version-history":[{"count":0,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts\/1513\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1513"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1513"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1513"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}