|
| 1 | +// HSV Debugger Shader by UnityCoder.com - https://unitycoder.com/blog/2018/10/19/hsv-debugging-shader/ |
| 2 | + |
| 3 | +Shader "UnityLibrary/Debug/HSVDebugger" |
| 4 | +{ |
| 5 | + Properties |
| 6 | + { |
| 7 | + _MainTex ("Texture", 2D) = "white" {} |
| 8 | + _TargetColor ("Target Color", Color) = (1, 0, 0, 1) |
| 9 | + _HueThreshold ("Hue Threshold", Float) = 0.1 |
| 10 | + _SatThreshold ("Saturation Threshold", Float) = 0.1 |
| 11 | + _ValThreshold ("Value Threshold", Float) = 0.1 |
| 12 | + [KeywordEnum(None, Hue, Saturation, Value, HueDistance, SaturationDistance, ValueDistance, ColorMatch, RemapHue)] _Mode ("Draw Mode",float) = 1 |
| 13 | + _HueTex ("Hue Gradient Texture", 2D) = "white" {} |
| 14 | + } |
| 15 | + |
| 16 | + SubShader |
| 17 | + { |
| 18 | + Tags { "RenderType"="Opaque" } |
| 19 | + LOD 100 |
| 20 | + |
| 21 | + Pass |
| 22 | + { |
| 23 | + CGPROGRAM |
| 24 | + #pragma vertex vert |
| 25 | + #pragma fragment frag |
| 26 | + #pragma multi_compile _MODE_NONE _MODE_HUE _MODE_SATURATION _MODE_VALUE _MODE_HUEDISTANCE _MODE_SATURATIONDISTANCE _MODE_VALUEDISTANCE _MODE_COLORMATCH _MODE_REMAPHUE |
| 27 | + |
| 28 | + #include "UnityCG.cginc" |
| 29 | + |
| 30 | + struct appdata |
| 31 | + { |
| 32 | + float4 vertex : POSITION; |
| 33 | + float2 uv : TEXCOORD0; |
| 34 | + }; |
| 35 | + |
| 36 | + struct v2f |
| 37 | + { |
| 38 | + float2 uv : TEXCOORD0; |
| 39 | + float4 vertex : SV_POSITION; |
| 40 | + }; |
| 41 | + |
| 42 | + sampler2D _MainTex; |
| 43 | + sampler2D _HueTex; |
| 44 | + |
| 45 | + float4 _MainTex_ST; |
| 46 | + float _HueThreshold; |
| 47 | + float _SatThreshold; |
| 48 | + float _ValThreshold; |
| 49 | + float4 _TargetColor; |
| 50 | + |
| 51 | + // http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl |
| 52 | + float3 rgb2hsv(float3 c) |
| 53 | + { |
| 54 | + float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); |
| 55 | + float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); |
| 56 | + float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); |
| 57 | + float d = q.x - min(q.w, q.y); |
| 58 | + float e = 1.0e-10; |
| 59 | + return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); |
| 60 | + } |
| 61 | + |
| 62 | + v2f vert (appdata v) |
| 63 | + { |
| 64 | + v2f o; |
| 65 | + o.vertex = UnityObjectToClipPos(v.vertex); |
| 66 | + o.uv = TRANSFORM_TEX(v.uv, _MainTex); |
| 67 | + return o; |
| 68 | + } |
| 69 | + |
| 70 | + fixed4 frag (v2f i) : SV_Target |
| 71 | + { |
| 72 | + // read main texture |
| 73 | + fixed4 tex = tex2D(_MainTex, i.uv); |
| 74 | + |
| 75 | + // convert colors |
| 76 | + float3 sourceHSV = rgb2hsv(tex.rgb); |
| 77 | + float3 targetHSV = rgb2hsv(_TargetColor.rbg); |
| 78 | + |
| 79 | + // get distances to our target color |
| 80 | + float hueDist = abs(sourceHSV.x - (1-targetHSV.x)); // why -1? |
| 81 | + float satDist = abs(sourceHSV.y - targetHSV.y); |
| 82 | + float valDist = abs(sourceHSV.z - targetHSV.z); |
| 83 | + |
| 84 | + float4 results = tex; |
| 85 | + |
| 86 | + // select results, based on enum dropdowm |
| 87 | + #ifdef _MODE_HUE |
| 88 | + results.rgb = sourceHSV.x; |
| 89 | + #endif |
| 90 | + |
| 91 | + #ifdef _MODE_SATURATION |
| 92 | + results.rgb = sourceHSV.y; |
| 93 | + #endif |
| 94 | + |
| 95 | + #ifdef _MODE_VALUE |
| 96 | + results.rgb = sourceHSV.z; |
| 97 | + #endif |
| 98 | + |
| 99 | + #ifdef _MODE_HUEDISTANCE |
| 100 | + results.rgb = hueDist; |
| 101 | + #endif |
| 102 | + |
| 103 | + #ifdef _MODE_SATURATIONDISTANCE |
| 104 | + results.rgb = satDist; |
| 105 | + #endif |
| 106 | + |
| 107 | + #ifdef _MODE_VALUEDISTANCE |
| 108 | + results.rgb = valDist; |
| 109 | + #endif |
| 110 | + |
| 111 | + #ifdef _MODE_REMAPHUE |
| 112 | + results.rgb = tex2D(_HueTex, float2(sourceHSV.x,0.5)).rgb; |
| 113 | + #endif |
| 114 | + |
| 115 | + #ifdef _MODE_COLORMATCH |
| 116 | + if (hueDist < _HueThreshold) |
| 117 | + { |
| 118 | + if (satDist < _SatThreshold) |
| 119 | + { |
| 120 | + if (valDist < _ValThreshold) |
| 121 | + { |
| 122 | + // display inverted color for matching area |
| 123 | + results.rgb = 1-results.rgb; |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | + #endif |
| 128 | + |
| 129 | + // draw |
| 130 | + return results; |
| 131 | + } |
| 132 | + ENDCG |
| 133 | + } // pass |
| 134 | + } // subshader |
| 135 | +} // shader |
0 commit comments