panel_fragment.glsl 3.7 KB

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