SplitScreen.shader 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. shader_type canvas_item;
  2. render_mode unshaded;
  3. uniform vec2 viewport_size; // size in pixels of the viewport. Cannot be access from the shader in GLES2
  4. uniform sampler2D viewport1 : hint_albedo;
  5. uniform sampler2D viewport2 : hint_albedo;
  6. uniform bool split_active; // true: split screen, false: use view1
  7. uniform vec2 player1_position; // position of player 1 un UV coordinates
  8. uniform vec2 player2_position; // position of player 2 un UV coordinates
  9. uniform float split_line_thickness; // width of the split boder
  10. uniform vec4 split_line_color; // color of the split border
  11. // from https://stackoverflow.com/questions/15276454/is-it-possible-to-draw-line-thickness-in-a-fragment-shader
  12. float distanceToLine(vec2 p1, vec2 p2, vec2 point) {
  13. float a = p1.y - p2.y;
  14. float b = p2.x - p1.x;
  15. return abs(a * point.x + b * point.y + p1.x * p2.y - p2.x * p1.y) / sqrt(a * a + b * b);
  16. }
  17. void fragment() {
  18. vec3 view1 = texture(viewport1, UV).rgb;
  19. vec3 view2 = texture(viewport2, UV).rgb;
  20. float width = viewport_size.x;
  21. float height = viewport_size.y;
  22. if (split_active) {
  23. vec2 dx = player2_position - player1_position;
  24. float split_slope;
  25. if (dx.y != 0.0) {
  26. split_slope = dx.x / dx.y;
  27. }
  28. else {
  29. split_slope = 100000.0; // High value (vertical split) if dx.y = 0
  30. }
  31. vec2 split_origin = vec2(0.5, 0.5);
  32. vec2 split_line_start = vec2(0.0, height * ((split_origin.x - 0.0) * split_slope + split_origin.y));
  33. vec2 split_line_end = vec2(width, height * ((split_origin.x - 1.0) * split_slope + split_origin.y));
  34. float distance_to_split_line = distanceToLine(split_line_start, split_line_end, vec2(UV.x * width, UV.y * height));
  35. // Draw split border if close enough
  36. if (distance_to_split_line < split_line_thickness) {
  37. COLOR = split_line_color;
  38. }
  39. else {
  40. float split_current_y = (split_origin.x - UV.x) * split_slope + split_origin.y;
  41. float split_player1_position_y = (split_origin.x - player1_position.x) * split_slope + split_origin.y;
  42. // Check on which side of the split UV is and select the proper view
  43. if (UV.y > split_current_y) {
  44. if (player1_position.y > split_player1_position_y) {
  45. COLOR = vec4(view1, 1.0);
  46. }
  47. else {
  48. COLOR = vec4(view2, 1.0);
  49. }
  50. }
  51. else {
  52. if (player1_position.y < split_player1_position_y) {
  53. COLOR = vec4(view1, 1.0);
  54. }
  55. else {
  56. COLOR = vec4(view2, 1.0);
  57. }
  58. }
  59. }
  60. }
  61. else {
  62. COLOR = vec4(view1, 1.0);
  63. }
  64. }