area.effect 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #include "color.effect"
  2. uniform float4x4 ViewProj;
  3. uniform float2 base_dimension;
  4. uniform float2 base_dimension_i;
  5. uniform texture2d image;
  6. uniform float multiplier;
  7. sampler_state textureSampler {
  8. Filter = Linear;
  9. AddressU = Clamp;
  10. AddressV = Clamp;
  11. };
  12. struct VertData {
  13. float4 pos : POSITION;
  14. float2 uv : TEXCOORD0;
  15. };
  16. struct VertInOut {
  17. float2 uv : TEXCOORD0;
  18. float4 pos : POSITION;
  19. };
  20. struct FragData {
  21. float2 uv : TEXCOORD0;
  22. };
  23. VertInOut VSDefault(VertData vert_in)
  24. {
  25. VertInOut vert_out;
  26. vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
  27. vert_out.uv = vert_in.uv;
  28. return vert_out;
  29. }
  30. float4 DrawArea(FragData frag_in)
  31. {
  32. float2 uv = frag_in.uv;
  33. float2 uv_delta = float2(ddx(uv.x), ddy(uv.y));
  34. // Handle potential OpenGL flip.
  35. if (obs_glsl_compile)
  36. uv_delta.y = abs(uv_delta.y);
  37. float2 uv_min = uv - 0.5 * uv_delta;
  38. float2 uv_max = uv_min + uv_delta;
  39. float2 load_index_begin = floor(uv_min * base_dimension);
  40. float2 load_index_end = ceil(uv_max * base_dimension);
  41. float2 target_dimension = 1.0 / uv_delta;
  42. float2 target_pos = uv * target_dimension;
  43. float2 target_pos_min = target_pos - 0.5;
  44. float2 target_pos_max = target_pos + 0.5;
  45. float2 scale = base_dimension_i * target_dimension;
  46. float4 total_color = float4(0.0, 0.0, 0.0, 0.0);
  47. float load_index_y = load_index_begin.y;
  48. do {
  49. float source_y_min = load_index_y * scale.y;
  50. float source_y_max = source_y_min + scale.y;
  51. float y_min = max(source_y_min, target_pos_min.y);
  52. float y_max = min(source_y_max, target_pos_max.y);
  53. float height = y_max - y_min;
  54. float load_index_x = load_index_begin.x;
  55. do {
  56. float source_x_min = load_index_x * scale.x;
  57. float source_x_max = source_x_min + scale.x;
  58. float x_min = max(source_x_min, target_pos_min.x);
  59. float x_max = min(source_x_max, target_pos_max.x);
  60. float width = x_max - x_min;
  61. float area = width * height;
  62. float4 color = image.Load(int3(load_index_x, load_index_y, 0));
  63. total_color += area * color;
  64. ++load_index_x;
  65. } while (load_index_x < load_index_end.x);
  66. ++load_index_y;
  67. } while (load_index_y < load_index_end.y);
  68. return total_color;
  69. }
  70. float4 PSDrawAreaRGBA(FragData frag_in) : TARGET
  71. {
  72. return DrawArea(frag_in);
  73. }
  74. float4 PSDrawAreaRGBAMultiply(FragData frag_in) : TARGET
  75. {
  76. float4 rgba = DrawArea(frag_in);
  77. rgba.rgb *= multiplier;
  78. return rgba;
  79. }
  80. float4 PSDrawAreaRGBATonemap(FragData frag_in) : TARGET
  81. {
  82. float4 rgba = DrawArea(frag_in);
  83. rgba.rgb = rec709_to_rec2020(rgba.rgb);
  84. rgba.rgb = reinhard(rgba.rgb);
  85. rgba.rgb = rec2020_to_rec709(rgba.rgb);
  86. return rgba;
  87. }
  88. float4 PSDrawAreaRGBAMultiplyTonemap(FragData frag_in) : TARGET
  89. {
  90. float4 rgba = DrawArea(frag_in);
  91. rgba.rgb *= multiplier;
  92. rgba.rgb = rec709_to_rec2020(rgba.rgb);
  93. rgba.rgb = reinhard(rgba.rgb);
  94. rgba.rgb = rec2020_to_rec709(rgba.rgb);
  95. return rgba;
  96. }
  97. float4 PSDrawAreaRGBADivide(FragData frag_in) : TARGET
  98. {
  99. float4 rgba = DrawArea(frag_in);
  100. rgba.rgb *= max(1. / rgba.a, 0.);
  101. return rgba;
  102. }
  103. float4 DrawAreaUpscale(FragData frag_in)
  104. {
  105. float2 uv = frag_in.uv;
  106. float2 uv_delta = float2(ddx(uv.x), ddy(uv.y));
  107. // Handle potential OpenGL flip.
  108. if (obs_glsl_compile)
  109. uv_delta.y = abs(uv_delta.y);
  110. float2 uv_min = uv - 0.5 * uv_delta;
  111. float2 uv_max = uv_min + uv_delta;
  112. float2 load_index_first = floor(uv_min * base_dimension);
  113. float2 load_index_last = ceil(uv_max * base_dimension) - 1.0;
  114. if (load_index_first.x < load_index_last.x) {
  115. float uv_boundary_x = load_index_last.x * base_dimension_i.x;
  116. uv.x = ((uv.x - uv_boundary_x) / uv_delta.x) * base_dimension_i.x + uv_boundary_x;
  117. } else
  118. uv.x = (load_index_first.x + 0.5) * base_dimension_i.x;
  119. if (load_index_first.y < load_index_last.y) {
  120. float uv_boundary_y = load_index_last.y * base_dimension_i.y;
  121. uv.y = ((uv.y - uv_boundary_y) / uv_delta.y) * base_dimension_i.y + uv_boundary_y;
  122. } else
  123. uv.y = (load_index_first.y + 0.5) * base_dimension_i.y;
  124. return image.Sample(textureSampler, uv);
  125. }
  126. float4 PSDrawAreaRGBAUpscale(FragData frag_in) : TARGET
  127. {
  128. return DrawAreaUpscale(frag_in);
  129. }
  130. float4 PSDrawAreaRGBAUpscaleMultiply(FragData frag_in) : TARGET
  131. {
  132. float4 rgba = DrawAreaUpscale(frag_in);
  133. rgba.rgb *= multiplier;
  134. return rgba;
  135. }
  136. float4 PSDrawAreaRGBAUpscaleTonemap(FragData frag_in) : TARGET
  137. {
  138. float4 rgba = DrawAreaUpscale(frag_in);
  139. rgba.rgb = rec709_to_rec2020(rgba.rgb);
  140. rgba.rgb = reinhard(rgba.rgb);
  141. rgba.rgb = rec2020_to_rec709(rgba.rgb);
  142. return rgba;
  143. }
  144. float4 PSDrawAreaRGBAUpscaleMultiplyTonemap(FragData frag_in) : TARGET
  145. {
  146. float4 rgba = DrawAreaUpscale(frag_in);
  147. rgba.rgb *= multiplier;
  148. rgba.rgb = rec709_to_rec2020(rgba.rgb);
  149. rgba.rgb = reinhard(rgba.rgb);
  150. rgba.rgb = rec2020_to_rec709(rgba.rgb);
  151. return rgba;
  152. }
  153. technique Draw
  154. {
  155. pass
  156. {
  157. vertex_shader = VSDefault(vert_in);
  158. pixel_shader = PSDrawAreaRGBA(frag_in);
  159. }
  160. }
  161. technique DrawMultiply
  162. {
  163. pass
  164. {
  165. vertex_shader = VSDefault(vert_in);
  166. pixel_shader = PSDrawAreaRGBAMultiply(frag_in);
  167. }
  168. }
  169. technique DrawTonemap
  170. {
  171. pass
  172. {
  173. vertex_shader = VSDefault(vert_in);
  174. pixel_shader = PSDrawAreaRGBATonemap(frag_in);
  175. }
  176. }
  177. technique DrawMultiplyTonemap
  178. {
  179. pass
  180. {
  181. vertex_shader = VSDefault(vert_in);
  182. pixel_shader = PSDrawAreaRGBAMultiplyTonemap(frag_in);
  183. }
  184. }
  185. technique DrawAlphaDivide
  186. {
  187. pass
  188. {
  189. vertex_shader = VSDefault(vert_in);
  190. pixel_shader = PSDrawAreaRGBADivide(frag_in);
  191. }
  192. }
  193. technique DrawUpscale
  194. {
  195. pass
  196. {
  197. vertex_shader = VSDefault(vert_in);
  198. pixel_shader = PSDrawAreaRGBAUpscale(frag_in);
  199. }
  200. }
  201. technique DrawUpscaleMultiply
  202. {
  203. pass
  204. {
  205. vertex_shader = VSDefault(vert_in);
  206. pixel_shader = PSDrawAreaRGBAUpscaleMultiply(frag_in);
  207. }
  208. }
  209. technique DrawUpscaleTonemap
  210. {
  211. pass
  212. {
  213. vertex_shader = VSDefault(vert_in);
  214. pixel_shader = PSDrawAreaRGBAUpscaleTonemap(frag_in);
  215. }
  216. }
  217. technique DrawUpscaleMultiplyTonemap
  218. {
  219. pass
  220. {
  221. vertex_shader = VSDefault(vert_in);
  222. pixel_shader = PSDrawAreaRGBAUpscaleMultiplyTonemap(frag_in);
  223. }
  224. }