Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.5 KiB

  1. fixed4 _ChromaKeyColor;
  2. float _ChromaKeySimilarity;
  3. float _ChromaKeySmoothRange;
  4. float _ChromaKeySpillRange;
  5. // https://en.wikipedia.org/wiki/YUV
  6. float3 RGB2YUV(float3 rgb)
  7. {
  8. float r = rgb.x;
  9. float g = rgb.y;
  10. float b = rgb.z;
  11. float y = 0.2126 * r + 0.7152 * g + 0.0722 * b;
  12. float u = -0.09991 * r - 0.33609 * g + 0.436 * b;
  13. float v = 0.615 * r - 0.55861 * g - 0.05639 * b;
  14. return float3(y, u, v);
  15. }
  16. float3 YUV2RGB(float3 yuv)
  17. {
  18. float y = yuv.x;
  19. float u = yuv.y;
  20. float v = yuv.z;
  21. float r = y + 1.28033 * v;
  22. float g = y - 0.21482 * u - 0.38059 * v;
  23. float b = y + 2.12798 * u;
  24. return float3(r, g, b);
  25. }
  26. fixed4 GetCameraColor(float2 colorUV);
  27. float ColorDistance_YUV_YUV(float3 yuv1, float3 yuv2)
  28. {
  29. float dist = distance(yuv1.yz, yuv2.yz);
  30. // Increase the distance if the brightness of the first color is too high.
  31. // It fixed the error on the over exposure areas
  32. dist += saturate(yuv1.x - 0.9);
  33. return dist;
  34. }
  35. float ColorDistance_RGB_YUV(float3 rgb1, float3 yuv2)
  36. {
  37. float3 yuv1 = RGB2YUV(rgb1);
  38. return ColorDistance_YUV_YUV(yuv1, yuv2);
  39. }
  40. float ColorDistance_RGB_RGB(float3 rgb1, float3 rgb2)
  41. {
  42. float3 yuv1 = RGB2YUV(rgb1);
  43. float3 yuv2 = RGB2YUV(rgb2);
  44. return ColorDistance_YUV_YUV(yuv1, yuv2);
  45. }
  46. float RGB2Gray(float3 rgb)
  47. {
  48. float r = rgb.x;
  49. float g = rgb.y;
  50. float b = rgb.z;
  51. float y = 0.2126 * r + 0.7152 * g + 0.0722 * b;
  52. return y;
  53. }
  54. float GetAlphaFromDistance(float dist)
  55. {
  56. float result = smoothstep(_ChromaKeySimilarity, _ChromaKeySimilarity + _ChromaKeySmoothRange, dist);
  57. result = result * result;
  58. return result;
  59. }
  60. float GetSpillFromDistance(float dist)
  61. {
  62. float result = smoothstep(_ChromaKeySimilarity, _ChromaKeySimilarity + _ChromaKeySpillRange, dist);
  63. result = result * result * result;
  64. return result;
  65. }
  66. float4 GetColorAfterChromaKey(float2 UV, float2 deltaUV, float step)
  67. {
  68. float3 chromaColor = _ChromaKeyColor.rgb;
  69. float3 chromaYUV = RGB2YUV(chromaColor);
  70. float dist = 0.0;
  71. const int samples = 3;
  72. float offset = ((float)samples - 1.0) / 2.0;
  73. for (int i = 0; i < samples; ++i)
  74. {
  75. for (int j = 0; j < samples; ++j)
  76. {
  77. fixed4 color = GetCameraColor(UV + float2((float)i - offset, (float)j - offset) * deltaUV * step);
  78. float d = ColorDistance_RGB_YUV(color, chromaYUV);
  79. dist += d;
  80. }
  81. }
  82. dist /= (samples * samples);
  83. fixed4 centerColor = GetCameraColor(UV);
  84. float alpha = GetAlphaFromDistance(dist);
  85. float spill = GetSpillFromDistance(dist);
  86. float gray = RGB2Gray(centerColor.rgb);
  87. float4 outColor;
  88. outColor.rgb = lerp(float3(gray, gray, gray), centerColor.rgb, spill);
  89. outColor.a = alpha;
  90. return outColor;
  91. }