forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			104 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
fixed4 _ChromaKeyColor;
 | 
						|
float _ChromaKeySimilarity;
 | 
						|
float _ChromaKeySmoothRange;
 | 
						|
float _ChromaKeySpillRange;
 | 
						|
 | 
						|
// https://en.wikipedia.org/wiki/YUV
 | 
						|
float3 RGB2YUV(float3 rgb)
 | 
						|
{
 | 
						|
	float r = rgb.x;
 | 
						|
	float g = rgb.y;
 | 
						|
	float b = rgb.z;
 | 
						|
	float y = 0.2126 * r + 0.7152 * g + 0.0722 * b;
 | 
						|
	float u = -0.09991 * r - 0.33609 * g + 0.436 * b;
 | 
						|
	float v = 0.615 * r - 0.55861 * g - 0.05639 * b;
 | 
						|
	return float3(y, u, v);
 | 
						|
}
 | 
						|
 | 
						|
float3 YUV2RGB(float3 yuv)
 | 
						|
{
 | 
						|
	float y = yuv.x;
 | 
						|
	float u = yuv.y;
 | 
						|
	float v = yuv.z;
 | 
						|
	float r = y + 1.28033 * v;
 | 
						|
	float g = y - 0.21482 * u - 0.38059 * v;
 | 
						|
	float b = y + 2.12798 * u;
 | 
						|
	return float3(r, g, b);
 | 
						|
}
 | 
						|
 | 
						|
fixed4 GetCameraColor(float2 colorUV);
 | 
						|
 | 
						|
float ColorDistance_YUV_YUV(float3 yuv1, float3 yuv2)
 | 
						|
{
 | 
						|
	float dist = distance(yuv1.yz, yuv2.yz);
 | 
						|
	// Increase the distance if the brightness of the first color is too high.
 | 
						|
	// It fixed the error on the over exposure areas
 | 
						|
	dist += saturate(yuv1.x - 0.9);
 | 
						|
	return dist;
 | 
						|
}
 | 
						|
 | 
						|
float ColorDistance_RGB_YUV(float3 rgb1, float3 yuv2)
 | 
						|
{
 | 
						|
	float3 yuv1 = RGB2YUV(rgb1);
 | 
						|
	return ColorDistance_YUV_YUV(yuv1, yuv2);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
float ColorDistance_RGB_RGB(float3 rgb1, float3 rgb2)
 | 
						|
{
 | 
						|
	float3 yuv1 = RGB2YUV(rgb1);
 | 
						|
	float3 yuv2 = RGB2YUV(rgb2);
 | 
						|
	return ColorDistance_YUV_YUV(yuv1, yuv2);
 | 
						|
}
 | 
						|
 | 
						|
float RGB2Gray(float3 rgb)
 | 
						|
{
 | 
						|
	float r = rgb.x;
 | 
						|
	float g = rgb.y;
 | 
						|
	float b = rgb.z;
 | 
						|
	float y = 0.2126 * r + 0.7152 * g + 0.0722 * b;
 | 
						|
	return y;
 | 
						|
}
 | 
						|
 | 
						|
float GetAlphaFromDistance(float dist)
 | 
						|
{
 | 
						|
	float result = smoothstep(_ChromaKeySimilarity, _ChromaKeySimilarity + _ChromaKeySmoothRange, dist);
 | 
						|
	result = result * result;
 | 
						|
	return result;
 | 
						|
}
 | 
						|
 | 
						|
float GetSpillFromDistance(float dist)
 | 
						|
{
 | 
						|
	float result = smoothstep(_ChromaKeySimilarity, _ChromaKeySimilarity + _ChromaKeySpillRange, dist);
 | 
						|
	result = result * result * result;
 | 
						|
	return result;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
float4 GetColorAfterChromaKey(float2 UV, float2 deltaUV, float step)
 | 
						|
{
 | 
						|
	float3 chromaColor = _ChromaKeyColor.rgb;
 | 
						|
	float3 chromaYUV = RGB2YUV(chromaColor);
 | 
						|
	float dist = 0.0;
 | 
						|
	const int samples = 3;
 | 
						|
	float offset = ((float)samples - 1.0) / 2.0;
 | 
						|
	for (int i = 0; i < samples; ++i)
 | 
						|
	{
 | 
						|
		for (int j = 0; j < samples; ++j)
 | 
						|
		{
 | 
						|
			fixed4 color = GetCameraColor(UV + float2((float)i - offset, (float)j - offset) * deltaUV * step);
 | 
						|
			float d = ColorDistance_RGB_YUV(color, chromaYUV);
 | 
						|
			dist += d;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	dist /= (samples * samples);
 | 
						|
	fixed4 centerColor = GetCameraColor(UV);
 | 
						|
	float alpha = GetAlphaFromDistance(dist);
 | 
						|
	float spill = GetSpillFromDistance(dist);
 | 
						|
	float gray = RGB2Gray(centerColor.rgb);
 | 
						|
	float4 outColor;
 | 
						|
	outColor.rgb = lerp(float3(gray, gray, gray), centerColor.rgb, spill);
 | 
						|
	outColor.a = alpha;
 | 
						|
	return outColor;
 | 
						|
}
 |