area.effect 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. uniform float4x4 ViewProj;
  2. uniform float2 base_dimension;
  3. uniform float2 base_dimension_i;
  4. uniform texture2d image;
  5. sampler_state textureSampler {
  6. Filter = Linear;
  7. AddressU = Clamp;
  8. AddressV = Clamp;
  9. };
  10. struct VertData {
  11. float4 pos : POSITION;
  12. float2 uv : TEXCOORD0;
  13. };
  14. struct VertInOut {
  15. float2 uv : TEXCOORD0;
  16. float4 pos : POSITION;
  17. };
  18. struct FragData {
  19. float2 uv : TEXCOORD0;
  20. };
  21. VertInOut VSDefault(VertData vert_in)
  22. {
  23. VertInOut vert_out;
  24. vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
  25. vert_out.uv = vert_in.uv;
  26. return vert_out;
  27. }
  28. float4 PSDrawAreaRGBA(FragData frag_in) : TARGET
  29. {
  30. float2 uv = frag_in.uv;
  31. float2 uv_delta = float2(ddx(uv.x), ddy(uv.y));
  32. // Handle potential OpenGL flip.
  33. if (obs_glsl_compile)
  34. uv_delta.y = abs(uv_delta.y);
  35. float2 uv_min = uv - 0.5 * uv_delta;
  36. float2 uv_max = uv_min + uv_delta;
  37. float2 load_index_begin = floor(uv_min * base_dimension);
  38. float2 load_index_end = ceil(uv_max * base_dimension);
  39. float2 target_dimension = 1.0 / uv_delta;
  40. float2 target_pos = uv * target_dimension;
  41. float2 target_pos_min = target_pos - 0.5;
  42. float2 target_pos_max = target_pos + 0.5;
  43. float2 scale = base_dimension_i * target_dimension;
  44. float4 total_color = float4(0.0, 0.0, 0.0, 0.0);
  45. float load_index_y = load_index_begin.y;
  46. do {
  47. float source_y_min = load_index_y * scale.y;
  48. float source_y_max = source_y_min + scale.y;
  49. float y_min = max(source_y_min, target_pos_min.y);
  50. float y_max = min(source_y_max, target_pos_max.y);
  51. float height = y_max - y_min;
  52. float load_index_x = load_index_begin.x;
  53. do {
  54. float source_x_min = load_index_x * scale.x;
  55. float source_x_max = source_x_min + scale.x;
  56. float x_min = max(source_x_min, target_pos_min.x);
  57. float x_max = min(source_x_max, target_pos_max.x);
  58. float width = x_max - x_min;
  59. float area = width * height;
  60. float4 color = image.Load(int3(load_index_x, load_index_y, 0));
  61. total_color += area * color;
  62. ++load_index_x;
  63. } while (load_index_x < load_index_end.x);
  64. ++load_index_y;
  65. } while (load_index_y < load_index_end.y);
  66. return total_color;
  67. }
  68. float4 PSDrawAreaUpscaleRGBA(FragData frag_in) : TARGET
  69. {
  70. float2 uv = frag_in.uv;
  71. float2 uv_delta = float2(ddx(uv.x), ddy(uv.y));
  72. // Handle potential OpenGL flip.
  73. if (obs_glsl_compile)
  74. uv_delta.y = abs(uv_delta.y);
  75. float2 uv_min = uv - 0.5 * uv_delta;
  76. float2 uv_max = uv_min + uv_delta;
  77. float2 load_index_first = floor(uv_min * base_dimension);
  78. float2 load_index_last = ceil(uv_max * base_dimension) - 1.0;
  79. if (load_index_first.x < load_index_last.x) {
  80. float uv_boundary_x = load_index_last.x * base_dimension_i.x;
  81. uv.x = ((uv.x - uv_boundary_x) / uv_delta.x) * base_dimension_i.x + uv_boundary_x;
  82. } else
  83. uv.x = (load_index_first.x + 0.5) * base_dimension_i.x;
  84. if (load_index_first.y < load_index_last.y) {
  85. float uv_boundary_y = load_index_last.y * base_dimension_i.y;
  86. uv.y = ((uv.y - uv_boundary_y) / uv_delta.y) * base_dimension_i.y + uv_boundary_y;
  87. } else
  88. uv.y = (load_index_first.y + 0.5) * base_dimension_i.y;
  89. return image.Sample(textureSampler, uv);
  90. }
  91. technique Draw
  92. {
  93. pass
  94. {
  95. vertex_shader = VSDefault(vert_in);
  96. pixel_shader = PSDrawAreaRGBA(frag_in);
  97. }
  98. }
  99. technique DrawUpscale
  100. {
  101. pass
  102. {
  103. vertex_shader = VSDefault(vert_in);
  104. pixel_shader = PSDrawAreaUpscaleRGBA(frag_in);
  105. }
  106. }