您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
244 行
7.7 KiB
244 行
7.7 KiB
Shader "GraphicTests/ComparerShader"
|
|
{
|
|
Properties
|
|
{
|
|
_MainTex("Texture", 2D) = "white" {}
|
|
_CompareTex("Texture", 2D) = "white" {}
|
|
[Enum(Red, 0, Green, 1, Blue, 2, Color, 3, Greyscale, 4, Heatmap, 5)]
|
|
_Mode("Mode", int) = 5
|
|
[Toggle] _MaxMode("Max Mode", int)=0
|
|
_Split("Split", Range(0,1)) = 0.5
|
|
_ResultSplit ("Result Split", Range(0,1)) = 0.1
|
|
_LineWidth("Line Width", float) = 0.001
|
|
}
|
|
SubShader
|
|
{
|
|
Tags { "RenderType"="Opaque" }
|
|
LOD 100
|
|
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
|
|
#pragma multi_compile Compare_RGB Compare_Lab Compare_Jab
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
struct appdata
|
|
{
|
|
float4 vertex : POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float2 uv : TEXCOORD0;
|
|
float4 vertex : SV_POSITION;
|
|
};
|
|
|
|
sampler2D _MainTex;
|
|
sampler2D _CompareTex;
|
|
int _Mode, _MaxMode;
|
|
|
|
float _FlipV2 = 1;
|
|
float _CorrectGamma = 0;
|
|
|
|
float _Split, _ResultSplit, _LineWidth;
|
|
|
|
v2f vert (appdata v)
|
|
{
|
|
v2f o;
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
o.uv = v.uv;
|
|
return o;
|
|
}
|
|
|
|
// Folowing color conversion code source : https://github.com/nschloe/colorio
|
|
|
|
// RGB to XYZ : file:///C:/Users/Remy/Downloads/srgb.pdf
|
|
float3 RGB2XYZ ( float4 color )
|
|
{
|
|
return float3(
|
|
color.r * 0.4124564 + color.g * 0.3575761 + color.b * 0.1804375,
|
|
color.r * 0.2126729 + color.g * 0.7151522 + color.b * 0.0721750,
|
|
color.r * 0.0193339 + color.g * 0.1191920 + color.b * 0.9503041
|
|
);
|
|
}
|
|
|
|
// JzAzBz color conversion : https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-25-13-15131&id=368272
|
|
|
|
static const float b = 1.15;
|
|
static const float g = 0.66;
|
|
static const float c1 = 0.8359375; // 3424f / 2^12
|
|
static const float c2 = 18.8515625; // 2413f / 2^7
|
|
static const float c3 = 18.6875; // 2392f / 2^7
|
|
static const float n = 0.15930175781; // 2610/2^14
|
|
static const float p = 134.034375; // 1.7*2523/2^5
|
|
static const float d = -0.56;
|
|
static const float d0 = 1.6295499532821566E-11;
|
|
|
|
// JzAzBz min/max: (0.0, -0.1, -0.2) / (0.2, 0.1, 0.1)
|
|
static const float3 jabMin = float3(0, -0.1, -0.2);
|
|
static const float3 jabMax = float3(0.2, 0.1, 0.1);
|
|
static const float3 jabRange = float3(0.2, 0.2, 0.3);
|
|
|
|
// min / max lab for srgb : (0.0, -577.4, -286.8) / (186.9, 577.4, 294.5)
|
|
static const float3 labMin = float3(0.0, -577.4, -286.8);
|
|
static const float3 labMax = float3(186.9, 577.4, 294.5);
|
|
static const float3 labRange = float3(186.9, 1154.8, 581.3);
|
|
|
|
float3 RGB2JzAzBz (float4 color)
|
|
{
|
|
float3 xyz = RGB2XYZ( color);
|
|
|
|
float x2 = b * xyz.x - (b-1) * xyz.z;
|
|
float y2 = g * xyz.y - (g-1) * xyz.x;
|
|
|
|
float3 lms = float3(
|
|
0.41478372 * x2 + 0.579999 * y2 + 0.0146480 * xyz.z,
|
|
-0.2015100 * x2 + 1.120649 * y2 + 0.0531008 * xyz.z,
|
|
-0.0166008 * x2 + 0.264800 * y2 + 0.6684799 * xyz.z
|
|
);
|
|
|
|
float3 lmsPowN = pow(lms/10000, n);
|
|
|
|
float3 lms2 = pow( (c1.xxx + c2 * lmsPowN) / ( float3(1,1,1) + c3 * lmsPowN ) , p ) ;
|
|
|
|
float3 jab = float3(
|
|
0.5 * lms2.x + 0.5 * lms2.y,
|
|
3.524000 * lms2.x + -4.066708 * lms2.y + 0.542708 * lms2.z,
|
|
0.199076 * lms2.x + 1.096799 * lms2.y + -1.295875 * lms2.z
|
|
);
|
|
|
|
jab.x = (((1+d)*jab.x)/(1+d*jab.x))-d0;
|
|
|
|
return jab;
|
|
}
|
|
|
|
float JzAzBzDiff( float3 v1, float3 v2)
|
|
{
|
|
float c1 = sqrt(v1.y*v1.y + v1.z*v1.z);
|
|
float c2 = sqrt(v2.y*v2.y + v2.z*v2.z);
|
|
|
|
float h1 = atan(v1.z/v1.y);
|
|
float h2 = atan(v2.z/v2.y);
|
|
|
|
float deltaH = 2*sqrt( c1*c2 ) * sin((h1-h2)/2);
|
|
|
|
return sqrt( pow( v1.x-v2.x ,2) + pow(c1-c2, 2) + deltaH * deltaH );
|
|
}
|
|
|
|
float XYZ2LabFunc( float f )
|
|
{
|
|
float delta = 6./29.;
|
|
|
|
if ( f > delta )
|
|
return pow(f, 0.333333333);
|
|
else
|
|
return f/(3*delta*delta) + 4./29.;
|
|
}
|
|
|
|
float3 RGB2Lab( float4 color )
|
|
{
|
|
float3 xyz = RGB2XYZ( color);
|
|
|
|
float xn = 95.047;
|
|
float yn = 100;
|
|
float zn = 108.883;
|
|
|
|
return float3(
|
|
116. * XYZ2LabFunc( xyz.y / yn ) - 16.,
|
|
500. * ( XYZ2LabFunc(xyz.x / xn) - XYZ2LabFunc(xyz.y/yn) ),
|
|
200. * (XYZ2LabFunc(xyz.y / yn) - XYZ2LabFunc(xyz.z / zn))
|
|
);
|
|
}
|
|
|
|
fixed4 frag (v2f i) : SV_Target
|
|
{
|
|
fixed4 c1 = tex2D(_MainTex, i.uv);
|
|
float2 uv2 = i.uv;
|
|
if (_FlipV2 > 0) uv2.y = 1 - uv2.y;
|
|
fixed4 c2 = tex2D(_CompareTex, uv2);
|
|
|
|
fixed4 o = c1 - c2;
|
|
o.a = 1;
|
|
o = abs(o);
|
|
|
|
float f = 0;
|
|
|
|
if (_MaxMode == 1)
|
|
f = max(o.r, max(o.g, o.b));
|
|
else
|
|
{
|
|
#ifdef Compare_RGB
|
|
f = (o.r*o.r + o.g*o.g + o.b*o.b) / 3;
|
|
#endif
|
|
|
|
#ifdef Compare_Jab
|
|
float3 jabColor1 = ( RGB2JzAzBz(c1) - jabMin ) / jabRange;
|
|
float3 jabColor2 = ( RGB2JzAzBz(c2) - jabMin ) / jabRange;
|
|
float3 jabDiff = jabColor1 - jabColor2;
|
|
f = JzAzBzDiff(jabColor1, jabColor2);
|
|
#endif
|
|
|
|
#ifdef Compare_Lab
|
|
float3 labColor1 = ( RGB2Lab(c1) - labMin ) / labRange;
|
|
float3 labColor2 = ( RGB2Lab(c2) - labMin ) / labRange;
|
|
|
|
float3 labDiff = labColor1 - labColor2;
|
|
f = length(labDiff);
|
|
#endif
|
|
}
|
|
|
|
if (_Mode == 0)
|
|
o.gb = 0;
|
|
if (_Mode == 1)
|
|
o.rb = 0;
|
|
if (_Mode == 2)
|
|
o.rg = 0;
|
|
if (_Mode == 4) // Greyscale view
|
|
o.rgb = f;
|
|
if (_Mode == 5) // Heat view
|
|
{
|
|
f = f * 3;
|
|
|
|
o.b = 1-abs( clamp(f, 0, 2)-1) ;
|
|
o.g = 1-abs( clamp(f, 1, 3)-2 );
|
|
o.r = clamp(f, 2, 3) - 2;
|
|
}
|
|
|
|
_Split = lerp(_Split, 0.5, _ResultSplit);
|
|
|
|
float a1 = saturate(_Split - _ResultSplit * 0.5 - _LineWidth);
|
|
float a2 = saturate(_Split - _ResultSplit * 0.5);
|
|
float b1 = saturate(_Split + _ResultSplit * 0.5);
|
|
float b2 = saturate(_Split + _ResultSplit * 0.5 + _LineWidth);
|
|
|
|
if (i.uv.x < a1)
|
|
{
|
|
o.rgb = c1.rgb;
|
|
}
|
|
else if (i.uv.x < a2)
|
|
{
|
|
o.rgb = 0;
|
|
}
|
|
else if (i.uv.x > b2)
|
|
{
|
|
o.rgb = c2.rgb;
|
|
}
|
|
else if (i.uv.x > b1)
|
|
{
|
|
o.rgb = 0;
|
|
}
|
|
|
|
if (_CorrectGamma > 0)
|
|
o.rgb = pow(o.rgb, 0.4545454545);
|
|
|
|
return o;
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
}
|