panel_fragment.glsl 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. precision highp float;
  2. // Texture uniforms
  3. uniform sampler2D MatTexture;
  4. uniform vec2 MatTexinfo[3];
  5. // Macros to access elements inside the MatTexinfo array
  6. #define MatTexOffset MatTexinfo[0]
  7. #define MatTexRepeat MatTexinfo[1]
  8. #define MatTexFlipY bool(MatTexinfo[2].x) // not used
  9. #define MatTexVisible bool(MatTexinfo[2].y) // not used
  10. // Inputs from vertex shader
  11. in vec2 FragTexcoord;
  12. // Input uniform
  13. uniform vec4 Panel[8];
  14. #define Bounds Panel[0] // panel bounds in texture coordinates
  15. #define Border Panel[1] // panel border in texture coordinates
  16. #define Padding Panel[2] // panel padding in texture coordinates
  17. #define Content Panel[3] // panel content area in texture coordinates
  18. #define BorderColor Panel[4] // panel border color
  19. #define PaddingColor Panel[5] // panel padding color
  20. #define ContentColor Panel[6] // panel content color
  21. #define TextureValid bool(Panel[7].x) // texture valid flag
  22. // Output
  23. out vec4 FragColor;
  24. /***
  25. * Checks if current fragment texture coordinate is inside the
  26. * supplied rectangle in texture coordinates:
  27. * rect[0] - position x [0,1]
  28. * rect[1] - position y [0,1]
  29. * rect[2] - width [0,1]
  30. * rect[3] - height [0,1]
  31. */
  32. bool checkRect(vec4 rect) {
  33. if (FragTexcoord.x < rect[0]) {
  34. return false;
  35. }
  36. if (FragTexcoord.x > rect[0] + rect[2]) {
  37. return false;
  38. }
  39. if (FragTexcoord.y < rect[1]) {
  40. return false;
  41. }
  42. if (FragTexcoord.y > rect[1] + rect[3]) {
  43. return false;
  44. }
  45. return true;
  46. }
  47. void main() {
  48. // Discard fragment outside of received bounds
  49. // Bounds[0] - xmin
  50. // Bounds[1] - ymin
  51. // Bounds[2] - xmax
  52. // Bounds[3] - ymax
  53. if (FragTexcoord.x <= Bounds[0] || FragTexcoord.x >= Bounds[2]) {
  54. discard;
  55. }
  56. if (FragTexcoord.y <= Bounds[1] || FragTexcoord.y >= Bounds[3]) {
  57. discard;
  58. }
  59. // Check if fragment is inside content area
  60. if (checkRect(Content)) {
  61. // If no texture, the color will be the material color.
  62. vec4 color = ContentColor;
  63. if (TextureValid) {
  64. // Adjust texture coordinates to fit texture inside the content area
  65. vec2 offset = vec2(-Content[0], -Content[1]);
  66. vec2 factor = vec2(1.0/Content[2], 1.0/Content[3]);
  67. vec2 texcoord = (FragTexcoord + offset) * factor;
  68. vec4 texColor = texture(MatTexture, texcoord * MatTexRepeat + MatTexOffset);
  69. // Mix content color with texture color.
  70. // Note that doing a simple linear interpolation (e.g. using mix()) is not correct!
  71. // The right formula can be found here: https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
  72. // For a more in-depth discussion: http://apoorvaj.io/alpha-compositing-opengl-blending-and-premultiplied-alpha.html#toc4
  73. // Another great discussion here: https://ciechanow.ski/alpha-compositing/
  74. // Alpha premultiply the content color
  75. vec4 contentPre = ContentColor;
  76. contentPre.rgb *= contentPre.a;
  77. // Alpha premultiply the content color
  78. vec4 texPre = texColor;
  79. texPre.rgb *= texPre.a;
  80. // Combine colors to obtain the alpha premultiplied final color
  81. color = texPre + contentPre * (1.0 - texPre.a);
  82. // Un-alpha-premultiply
  83. color.rgb /= color.a;
  84. }
  85. FragColor = color;
  86. return;
  87. }
  88. // Checks if fragment is inside paddings area
  89. if (checkRect(Padding)) {
  90. FragColor = PaddingColor;
  91. return;
  92. }
  93. // Checks if fragment is inside borders area
  94. if (checkRect(Border)) {
  95. FragColor = BorderColor;
  96. return;
  97. }
  98. // Fragment is in margins area (always transparent)
  99. FragColor = vec4(1,1,1,0);
  100. }