format_conversion.effect 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /******************************************************************************
  2. Copyright (C) 2014 by Hugh Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. uniform float width;
  15. uniform float height;
  16. uniform float width_i;
  17. uniform float width_d2;
  18. uniform float height_d2;
  19. uniform float width_x2_i;
  20. uniform float4 color_vec0;
  21. uniform float4 color_vec1;
  22. uniform float4 color_vec2;
  23. uniform float3 color_range_min = {0.0, 0.0, 0.0};
  24. uniform float3 color_range_max = {1.0, 1.0, 1.0};
  25. uniform texture2d image;
  26. uniform texture2d image1;
  27. uniform texture2d image2;
  28. sampler_state def_sampler {
  29. Filter = Linear;
  30. AddressU = Clamp;
  31. AddressV = Clamp;
  32. };
  33. struct FragPos {
  34. float4 pos : POSITION;
  35. };
  36. struct VertTexPos {
  37. float2 uv : TEXCOORD0;
  38. float4 pos : POSITION;
  39. };
  40. struct VertPosWide {
  41. float3 pos_wide : TEXCOORD0;
  42. float4 pos : POSITION;
  43. };
  44. struct VertTexPosWide {
  45. float3 uuv : TEXCOORD0;
  46. float4 pos : POSITION;
  47. };
  48. struct FragTex {
  49. float2 uv : TEXCOORD0;
  50. };
  51. struct FragPosWide {
  52. float3 pos_wide : TEXCOORD0;
  53. };
  54. struct FragTexWide {
  55. float3 uuv : TEXCOORD0;
  56. };
  57. FragPos VSPos(uint id : VERTEXID)
  58. {
  59. float idHigh = float(id >> 1);
  60. float idLow = float(id & uint(1));
  61. float x = idHigh * 4.0 - 1.0;
  62. float y = idLow * 4.0 - 1.0;
  63. FragPos vert_out;
  64. vert_out.pos = float4(x, y, 0.0, 1.0);
  65. return vert_out;
  66. }
  67. VertTexPosWide VSTexPos_Left(uint id : VERTEXID)
  68. {
  69. float idHigh = float(id >> 1);
  70. float idLow = float(id & uint(1));
  71. float x = idHigh * 4.0 - 1.0;
  72. float y = idLow * 4.0 - 1.0;
  73. float u_right = idHigh * 2.0;
  74. float u_left = u_right - width_i;
  75. float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0);
  76. VertTexPosWide vert_out;
  77. vert_out.uuv = float3(u_left, u_right, v);
  78. vert_out.pos = float4(x, y, 0.0, 1.0);
  79. return vert_out;
  80. }
  81. VertTexPos VSTexPosHalf_Reverse(uint id : VERTEXID)
  82. {
  83. float idHigh = float(id >> 1);
  84. float idLow = float(id & uint(1));
  85. float x = idHigh * 4.0 - 1.0;
  86. float y = idLow * 4.0 - 1.0;
  87. float u = idHigh * 2.0;
  88. float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0);
  89. VertTexPos vert_out;
  90. vert_out.uv = float2(width_d2 * u, height * v);
  91. vert_out.pos = float4(x, y, 0.0, 1.0);
  92. return vert_out;
  93. }
  94. VertTexPos VSTexPosHalfHalf_Reverse(uint id : VERTEXID)
  95. {
  96. float idHigh = float(id >> 1);
  97. float idLow = float(id & uint(1));
  98. float x = idHigh * 4.0 - 1.0;
  99. float y = idLow * 4.0 - 1.0;
  100. float u = idHigh * 2.0;
  101. float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0);
  102. VertTexPos vert_out;
  103. vert_out.uv = float2(width_d2 * u, height_d2 * v);
  104. vert_out.pos = float4(x, y, 0.0, 1.0);
  105. return vert_out;
  106. }
  107. VertPosWide VSPosWide_Reverse(uint id : VERTEXID)
  108. {
  109. float idHigh = float(id >> 1);
  110. float idLow = float(id & uint(1));
  111. float x = idHigh * 4.0 - 1.0;
  112. float y = idLow * 4.0 - 1.0;
  113. float u = idHigh * 2.0;
  114. float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0);
  115. VertPosWide vert_out;
  116. vert_out.pos_wide = float3(float2(width, width_d2) * u, height * v);
  117. vert_out.pos = float4(x, y, 0.0, 1.0);
  118. return vert_out;
  119. }
  120. float PS_Y(FragPos frag_in) : TARGET
  121. {
  122. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb;
  123. float y = dot(color_vec0.xyz, rgb) + color_vec0.w;
  124. return y;
  125. }
  126. float2 PS_UV_Wide(FragTexWide frag_in) : TARGET
  127. {
  128. float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb;
  129. float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb;
  130. float3 rgb = (rgb_left + rgb_right) * 0.5;
  131. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  132. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  133. return float2(u, v);
  134. }
  135. float PS_U(FragPos frag_in) : TARGET
  136. {
  137. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb;
  138. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  139. return u;
  140. }
  141. float PS_V(FragPos frag_in) : TARGET
  142. {
  143. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb;
  144. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  145. return v;
  146. }
  147. float PS_U_Wide(FragTexWide frag_in) : TARGET
  148. {
  149. float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb;
  150. float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb;
  151. float3 rgb = (rgb_left + rgb_right) * 0.5;
  152. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  153. return u;
  154. }
  155. float PS_V_Wide(FragTexWide frag_in) : TARGET
  156. {
  157. float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb;
  158. float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb;
  159. float3 rgb = (rgb_left + rgb_right) * 0.5;
  160. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  161. return v;
  162. }
  163. float3 YUV_to_RGB(float3 yuv)
  164. {
  165. yuv = clamp(yuv, color_range_min, color_range_max);
  166. float r = dot(color_vec0.xyz, yuv) + color_vec0.w;
  167. float g = dot(color_vec1.xyz, yuv) + color_vec1.w;
  168. float b = dot(color_vec2.xyz, yuv) + color_vec2.w;
  169. return float3(r, g, b);
  170. }
  171. float3 PSUYVY_Reverse(FragTex frag_in) : TARGET
  172. {
  173. float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
  174. float2 y01 = y2uv.yw;
  175. float2 cbcr = y2uv.zx;
  176. float leftover = frac(frag_in.uv.x);
  177. float y = (leftover < 0.5) ? y01.x : y01.y;
  178. float3 yuv = float3(y, cbcr);
  179. float3 rgb = YUV_to_RGB(yuv);
  180. return rgb;
  181. }
  182. float3 PSYUY2_Reverse(FragTex frag_in) : TARGET
  183. {
  184. float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
  185. float2 y01 = y2uv.zx;
  186. float2 cbcr = y2uv.yw;
  187. float leftover = frac(frag_in.uv.x);
  188. float y = (leftover < 0.5) ? y01.x : y01.y;
  189. float3 yuv = float3(y, cbcr);
  190. float3 rgb = YUV_to_RGB(yuv);
  191. return rgb;
  192. }
  193. float3 PSYVYU_Reverse(FragTex frag_in) : TARGET
  194. {
  195. float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
  196. float2 y01 = y2uv.zx;
  197. float2 cbcr = y2uv.wy;
  198. float leftover = frac(frag_in.uv.x);
  199. float y = (leftover < 0.5) ? y01.x : y01.y;
  200. float3 yuv = float3(y, cbcr);
  201. float3 rgb = YUV_to_RGB(yuv);
  202. return rgb;
  203. }
  204. float3 PSPlanar420_Reverse(VertTexPos frag_in) : TARGET
  205. {
  206. float y = image.Load(int3(frag_in.pos.xy, 0)).x;
  207. int3 xy0_chroma = int3(frag_in.uv, 0);
  208. float cb = image1.Load(xy0_chroma).x;
  209. float cr = image2.Load(xy0_chroma).x;
  210. float3 yuv = float3(y, cb, cr);
  211. float3 rgb = YUV_to_RGB(yuv);
  212. return rgb;
  213. }
  214. float3 PSPlanar422_Reverse(FragPosWide frag_in) : TARGET
  215. {
  216. float y = image.Load(int3(frag_in.pos_wide.xz, 0)).x;
  217. int3 xy0_chroma = int3(frag_in.pos_wide.yz, 0);
  218. float cb = image1.Load(xy0_chroma).x;
  219. float cr = image2.Load(xy0_chroma).x;
  220. float3 yuv = float3(y, cb, cr);
  221. float3 rgb = YUV_to_RGB(yuv);
  222. return rgb;
  223. }
  224. float3 PSPlanar444_Reverse(FragPos frag_in) : TARGET
  225. {
  226. int3 xy0 = int3(frag_in.pos.xy, 0);
  227. float y = image.Load(xy0).x;
  228. float cb = image1.Load(xy0).x;
  229. float cr = image2.Load(xy0).x;
  230. float3 yuv = float3(y, cb, cr);
  231. float3 rgb = YUV_to_RGB(yuv);
  232. return rgb;
  233. }
  234. float3 PSNV12_Reverse(VertTexPos frag_in) : TARGET
  235. {
  236. float y = image.Load(int3(frag_in.pos.xy, 0)).x;
  237. float2 cbcr = image1.Load(int3(frag_in.uv, 0)).xy;
  238. float3 yuv = float3(y, cbcr);
  239. float3 rgb = YUV_to_RGB(yuv);
  240. return rgb;
  241. }
  242. float3 PSY800_Limited(FragPos frag_in) : TARGET
  243. {
  244. float limited = image.Load(int3(frag_in.pos.xy, 0)).x;
  245. float full = (255.0 / 219.0) * limited - (16.0 / 219.0);
  246. return float3(full, full, full);
  247. }
  248. float3 PSY800_Full(FragPos frag_in) : TARGET
  249. {
  250. float3 full = image.Load(int3(frag_in.pos.xy, 0)).xxx;
  251. return full;
  252. }
  253. float4 PSRGB_Limited(FragPos frag_in) : TARGET
  254. {
  255. float4 rgba = image.Load(int3(frag_in.pos.xy, 0));
  256. rgba.rgb = (255.0 / 219.0) * rgba.rgb - (16.0 / 219.0);
  257. return rgba;
  258. }
  259. float3 PSBGR3_Limited(FragPos frag_in) : TARGET
  260. {
  261. float x = frag_in.pos.x * 3.0;
  262. float y = frag_in.pos.y;
  263. float b = image.Load(int3(x - 1.0, y, 0)).x;
  264. float g = image.Load(int3(x, y, 0)).x;
  265. float r = image.Load(int3(x + 1.0, y, 0)).x;
  266. float3 rgb = float3(r, g, b);
  267. rgb = (255.0 / 219.0) * rgb - (16.0 / 219.0);
  268. return rgb;
  269. }
  270. float3 PSBGR3_Full(FragPos frag_in) : TARGET
  271. {
  272. float x = frag_in.pos.x * 3.0;
  273. float y = frag_in.pos.y;
  274. float b = image.Load(int3(x - 1.0, y, 0)).x;
  275. float g = image.Load(int3(x, y, 0)).x;
  276. float r = image.Load(int3(x + 1.0, y, 0)).x;
  277. float3 rgb = float3(r, g, b);
  278. return rgb;
  279. }
  280. technique Planar_Y
  281. {
  282. pass
  283. {
  284. vertex_shader = VSPos(id);
  285. pixel_shader = PS_Y(frag_in);
  286. }
  287. }
  288. technique Planar_U
  289. {
  290. pass
  291. {
  292. vertex_shader = VSPos(id);
  293. pixel_shader = PS_U(frag_in);
  294. }
  295. }
  296. technique Planar_V
  297. {
  298. pass
  299. {
  300. vertex_shader = VSPos(id);
  301. pixel_shader = PS_V(frag_in);
  302. }
  303. }
  304. technique Planar_U_Left
  305. {
  306. pass
  307. {
  308. vertex_shader = VSTexPos_Left(id);
  309. pixel_shader = PS_U_Wide(frag_in);
  310. }
  311. }
  312. technique Planar_V_Left
  313. {
  314. pass
  315. {
  316. vertex_shader = VSTexPos_Left(id);
  317. pixel_shader = PS_V_Wide(frag_in);
  318. }
  319. }
  320. technique NV12_Y
  321. {
  322. pass
  323. {
  324. vertex_shader = VSPos(id);
  325. pixel_shader = PS_Y(frag_in);
  326. }
  327. }
  328. technique NV12_UV
  329. {
  330. pass
  331. {
  332. vertex_shader = VSTexPos_Left(id);
  333. pixel_shader = PS_UV_Wide(frag_in);
  334. }
  335. }
  336. technique UYVY_Reverse
  337. {
  338. pass
  339. {
  340. vertex_shader = VSTexPosHalf_Reverse(id);
  341. pixel_shader = PSUYVY_Reverse(frag_in);
  342. }
  343. }
  344. technique YUY2_Reverse
  345. {
  346. pass
  347. {
  348. vertex_shader = VSTexPosHalf_Reverse(id);
  349. pixel_shader = PSYUY2_Reverse(frag_in);
  350. }
  351. }
  352. technique YVYU_Reverse
  353. {
  354. pass
  355. {
  356. vertex_shader = VSTexPosHalf_Reverse(id);
  357. pixel_shader = PSYVYU_Reverse(frag_in);
  358. }
  359. }
  360. technique I420_Reverse
  361. {
  362. pass
  363. {
  364. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  365. pixel_shader = PSPlanar420_Reverse(frag_in);
  366. }
  367. }
  368. technique I422_Reverse
  369. {
  370. pass
  371. {
  372. vertex_shader = VSPosWide_Reverse(id);
  373. pixel_shader = PSPlanar422_Reverse(frag_in);
  374. }
  375. }
  376. technique I444_Reverse
  377. {
  378. pass
  379. {
  380. vertex_shader = VSPos(id);
  381. pixel_shader = PSPlanar444_Reverse(frag_in);
  382. }
  383. }
  384. technique NV12_Reverse
  385. {
  386. pass
  387. {
  388. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  389. pixel_shader = PSNV12_Reverse(frag_in);
  390. }
  391. }
  392. technique Y800_Limited
  393. {
  394. pass
  395. {
  396. vertex_shader = VSPos(id);
  397. pixel_shader = PSY800_Limited(frag_in);
  398. }
  399. }
  400. technique Y800_Full
  401. {
  402. pass
  403. {
  404. vertex_shader = VSPos(id);
  405. pixel_shader = PSY800_Full(frag_in);
  406. }
  407. }
  408. technique RGB_Limited
  409. {
  410. pass
  411. {
  412. vertex_shader = VSPos(id);
  413. pixel_shader = PSRGB_Limited(frag_in);
  414. }
  415. }
  416. technique BGR3_Limited
  417. {
  418. pass
  419. {
  420. vertex_shader = VSPos(id);
  421. pixel_shader = PSBGR3_Limited(frag_in);
  422. }
  423. }
  424. technique BGR3_Full
  425. {
  426. pass
  427. {
  428. vertex_shader = VSPos(id);
  429. pixel_shader = PSBGR3_Full(frag_in);
  430. }
  431. }