format_conversion.effect 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  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. #include "color.effect"
  15. uniform float width;
  16. uniform float height;
  17. uniform float width_i;
  18. uniform float height_i;
  19. uniform float width_d2;
  20. uniform float height_d2;
  21. uniform float width_x2_i;
  22. uniform float maximum_over_sdr_white_nits;
  23. uniform float sdr_white_nits_over_maximum;
  24. uniform float hlg_exponent;
  25. uniform float hlg_lw;
  26. uniform float4 color_vec0;
  27. uniform float4 color_vec1;
  28. uniform float4 color_vec2;
  29. uniform float3 color_range_min = {0.0, 0.0, 0.0};
  30. uniform float3 color_range_max = {1.0, 1.0, 1.0};
  31. uniform texture2d image;
  32. uniform texture2d image1;
  33. uniform texture2d image2;
  34. uniform texture2d image3;
  35. sampler_state def_sampler {
  36. Filter = Linear;
  37. AddressU = Clamp;
  38. AddressV = Clamp;
  39. };
  40. struct FragPos {
  41. float4 pos : POSITION;
  42. };
  43. struct VertTexPos {
  44. float2 uv : TEXCOORD0;
  45. float4 pos : POSITION;
  46. };
  47. struct VertPosWide {
  48. float3 pos_wide : TEXCOORD0;
  49. float4 pos : POSITION;
  50. };
  51. struct VertTexPosWide {
  52. float3 uuv : TEXCOORD0;
  53. float4 pos : POSITION;
  54. };
  55. struct VertTexPosWideWide {
  56. float4 uuvv : TEXCOORD0;
  57. float4 pos : POSITION;
  58. };
  59. struct FragTex {
  60. float2 uv : TEXCOORD0;
  61. };
  62. struct FragPosWide {
  63. float3 pos_wide : TEXCOORD0;
  64. };
  65. struct FragTexWide {
  66. float3 uuv : TEXCOORD0;
  67. };
  68. struct FragTexWideWide {
  69. float4 uuvv : TEXCOORD0;
  70. };
  71. FragPos VSPos(uint id : VERTEXID)
  72. {
  73. float idHigh = float(id >> 1);
  74. float idLow = float(id & uint(1));
  75. float x = idHigh * 4.0 - 1.0;
  76. float y = idLow * 4.0 - 1.0;
  77. FragPos vert_out;
  78. vert_out.pos = float4(x, y, 0.0, 1.0);
  79. return vert_out;
  80. }
  81. VertTexPosWide VSTexPos_Left(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_right = idHigh * 2.0;
  88. float u_left = u_right - width_i;
  89. float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0);
  90. VertTexPosWide vert_out;
  91. vert_out.uuv = float3(u_left, u_right, v);
  92. vert_out.pos = float4(x, y, 0.0, 1.0);
  93. return vert_out;
  94. }
  95. VertTexPosWideWide VSTexPos_TopLeft(uint id : VERTEXID)
  96. {
  97. float idHigh = float(id >> 1);
  98. float idLow = float(id & uint(1));
  99. float x = idHigh * 4.0 - 1.0;
  100. float y = idLow * 4.0 - 1.0;
  101. float u_right = idHigh * 2.0;
  102. float u_left = u_right - width_i;
  103. float v_bottom;
  104. float v_top;
  105. if (obs_glsl_compile) {
  106. v_bottom = idLow * 2.0;
  107. v_top = v_bottom + height_i;
  108. } else {
  109. v_bottom = 1.0 - idLow * 2.0;
  110. v_top = v_bottom - height_i;
  111. }
  112. VertTexPosWideWide vert_out;
  113. vert_out.uuvv = float4(u_left, u_right, v_top, v_bottom);
  114. vert_out.pos = float4(x, y, 0.0, 1.0);
  115. return vert_out;
  116. }
  117. VertTexPos VSTexPosHalf_Reverse(uint id : VERTEXID)
  118. {
  119. float idHigh = float(id >> 1);
  120. float idLow = float(id & uint(1));
  121. float x = idHigh * 4.0 - 1.0;
  122. float y = idLow * 4.0 - 1.0;
  123. float u = idHigh * 2.0;
  124. float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0);
  125. VertTexPos vert_out;
  126. vert_out.uv = float2(width_d2 * u, height * v);
  127. vert_out.pos = float4(x, y, 0.0, 1.0);
  128. return vert_out;
  129. }
  130. VertTexPos VSTexPosHalfHalf_Reverse(uint id : VERTEXID)
  131. {
  132. float idHigh = float(id >> 1);
  133. float idLow = float(id & uint(1));
  134. float x = idHigh * 4.0 - 1.0;
  135. float y = idLow * 4.0 - 1.0;
  136. float u = idHigh * 2.0;
  137. float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0);
  138. VertTexPos vert_out;
  139. vert_out.uv = float2(width_d2 * u, height_d2 * v);
  140. vert_out.pos = float4(x, y, 0.0, 1.0);
  141. return vert_out;
  142. }
  143. VertPosWide VSPosWide_Reverse(uint id : VERTEXID)
  144. {
  145. float idHigh = float(id >> 1);
  146. float idLow = float(id & uint(1));
  147. float x = idHigh * 4.0 - 1.0;
  148. float y = idLow * 4.0 - 1.0;
  149. float u = idHigh * 2.0;
  150. float v = obs_glsl_compile ? (idLow * 2.0) : (1.0 - idLow * 2.0);
  151. VertPosWide vert_out;
  152. vert_out.pos_wide = float3(float2(width, width_d2) * u, height * v);
  153. vert_out.pos = float4(x, y, 0.0, 1.0);
  154. return vert_out;
  155. }
  156. float PS_Y(FragPos frag_in) : TARGET
  157. {
  158. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb;
  159. float y = dot(color_vec0.xyz, rgb) + color_vec0.w;
  160. return y;
  161. }
  162. float PS_PQ_Y_709_2020(FragPos frag_in) : TARGET
  163. {
  164. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb * sdr_white_nits_over_maximum;
  165. rgb = rec709_to_rec2020(rgb);
  166. rgb = linear_to_st2084(rgb);
  167. float y = dot(color_vec0.xyz, rgb) + color_vec0.w;
  168. y = (65472. / 65535.) * y + (32. / 65535.); // set up truncation to 10 bits
  169. return y;
  170. }
  171. float PS_HLG_Y_709_2020(FragPos frag_in) : TARGET
  172. {
  173. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb * sdr_white_nits_over_maximum;
  174. rgb = rec709_to_rec2020(rgb);
  175. rgb = linear_to_hlg(rgb, hlg_lw);
  176. float y = dot(color_vec0.xyz, rgb) + color_vec0.w;
  177. y = (65472. / 65535.) * y + (32. / 65535.); // set up truncation to 10 bits
  178. return y;
  179. }
  180. float PS_SRGB_Y(FragPos frag_in) : TARGET
  181. {
  182. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb;
  183. rgb = srgb_linear_to_nonlinear(rgb);
  184. float y = dot(color_vec0.xyz, rgb) + color_vec0.w;
  185. y = (65472. / 65535.) * y + (32. / 65535.); // set up truncation to 10 bits
  186. return y;
  187. }
  188. float PS_I010_PQ_Y_709_2020(FragPos frag_in) : TARGET
  189. {
  190. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb * sdr_white_nits_over_maximum;
  191. rgb = rec709_to_rec2020(rgb);
  192. rgb = linear_to_st2084(rgb);
  193. float y = dot(color_vec0.xyz, rgb) + color_vec0.w;
  194. return y * (1023. / 65535.);
  195. }
  196. float PS_I010_HLG_Y_709_2020(FragPos frag_in) : TARGET
  197. {
  198. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb * sdr_white_nits_over_maximum;
  199. rgb = rec709_to_rec2020(rgb);
  200. rgb = linear_to_hlg(rgb, hlg_lw);
  201. float y = dot(color_vec0.xyz, rgb) + color_vec0.w;
  202. return y * (1023. / 65535.);
  203. }
  204. float PS_I010_SRGB_Y(FragPos frag_in) : TARGET
  205. {
  206. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb;
  207. rgb = srgb_linear_to_nonlinear(rgb);
  208. float y = dot(color_vec0.xyz, rgb) + color_vec0.w;
  209. return y * (1023. / 65535.);
  210. }
  211. float2 PS_UV_Wide(FragTexWide frag_in) : TARGET
  212. {
  213. float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb;
  214. float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb;
  215. float3 rgb = (rgb_left + rgb_right) * 0.5;
  216. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  217. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  218. return float2(u, v);
  219. }
  220. float2 PS_PQ_UV_709_2020_WideWide(FragTexWideWide frag_in) : TARGET
  221. {
  222. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  223. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  224. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  225. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  226. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * (0.25 * sdr_white_nits_over_maximum);
  227. rgb = rec709_to_rec2020(rgb);
  228. rgb = linear_to_st2084(rgb);
  229. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  230. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  231. float2 uv = float2(u, v);
  232. uv = (65472. / 65535.) * uv + (32. / 65535.); // set up truncation to 10 bits
  233. return uv;
  234. }
  235. float2 PS_HLG_UV_709_2020_WideWide(FragTexWideWide frag_in) : TARGET
  236. {
  237. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  238. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  239. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  240. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  241. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * (0.25 * sdr_white_nits_over_maximum);
  242. rgb = rec709_to_rec2020(rgb);
  243. rgb = linear_to_hlg(rgb, hlg_lw);
  244. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  245. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  246. float2 uv = float2(u, v);
  247. uv = (65472. / 65535.) * uv + (32. / 65535.); // set up truncation to 10 bits
  248. return uv;
  249. }
  250. float2 PS_SRGB_UV_WideWide(FragTexWideWide frag_in) : TARGET
  251. {
  252. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  253. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  254. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  255. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  256. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * 0.25;
  257. rgb = srgb_linear_to_nonlinear(rgb);
  258. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  259. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  260. float2 uv = float2(u, v);
  261. uv = (65472. / 65535.) * uv + (32. / 65535.); // set up truncation to 10 bits
  262. return uv;
  263. }
  264. float PS_U(FragPos frag_in) : TARGET
  265. {
  266. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb;
  267. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  268. return u;
  269. }
  270. float PS_V(FragPos frag_in) : TARGET
  271. {
  272. float3 rgb = image.Load(int3(frag_in.pos.xy, 0)).rgb;
  273. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  274. return v;
  275. }
  276. float PS_U_Wide(FragTexWide frag_in) : TARGET
  277. {
  278. float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb;
  279. float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb;
  280. float3 rgb = (rgb_left + rgb_right) * 0.5;
  281. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  282. return u;
  283. }
  284. float PS_V_Wide(FragTexWide frag_in) : TARGET
  285. {
  286. float3 rgb_left = image.Sample(def_sampler, frag_in.uuv.xz).rgb;
  287. float3 rgb_right = image.Sample(def_sampler, frag_in.uuv.yz).rgb;
  288. float3 rgb = (rgb_left + rgb_right) * 0.5;
  289. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  290. return v;
  291. }
  292. float PS_I010_PQ_U_709_2020_WideWide(FragTexWideWide frag_in) : TARGET
  293. {
  294. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  295. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  296. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  297. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  298. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * (0.25 * sdr_white_nits_over_maximum);
  299. rgb = rec709_to_rec2020(rgb);
  300. rgb = linear_to_st2084(rgb);
  301. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  302. return u * (1023. / 65535.);
  303. }
  304. float PS_I010_HLG_U_709_2020_WideWide(FragTexWideWide frag_in) : TARGET
  305. {
  306. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  307. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  308. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  309. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  310. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * (0.25 * sdr_white_nits_over_maximum);
  311. rgb = rec709_to_rec2020(rgb);
  312. rgb = linear_to_hlg(rgb, hlg_lw);
  313. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  314. return u * (1023. / 65535.);
  315. }
  316. float PS_I010_SRGB_U_WideWide(FragTexWideWide frag_in) : TARGET
  317. {
  318. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  319. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  320. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  321. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  322. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * 0.25;
  323. rgb = srgb_linear_to_nonlinear(rgb);
  324. float u = dot(color_vec1.xyz, rgb) + color_vec1.w;
  325. return u * (1023. / 65535.);
  326. }
  327. float PS_I010_PQ_V_709_2020_WideWide(FragTexWideWide frag_in) : TARGET
  328. {
  329. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  330. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  331. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  332. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  333. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * (0.25 * sdr_white_nits_over_maximum);
  334. rgb = rec709_to_rec2020(rgb);
  335. rgb = linear_to_st2084(rgb);
  336. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  337. return v * (1023. / 65535.);
  338. }
  339. float PS_I010_HLG_V_709_2020_WideWide(FragTexWideWide frag_in) : TARGET
  340. {
  341. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  342. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  343. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  344. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  345. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * (0.25 * sdr_white_nits_over_maximum);
  346. rgb = rec709_to_rec2020(rgb);
  347. rgb = linear_to_hlg(rgb, hlg_lw);
  348. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  349. return v * (1023. / 65535.);
  350. }
  351. float PS_I010_SRGB_V_WideWide(FragTexWideWide frag_in) : TARGET
  352. {
  353. float3 rgb_topleft = image.Sample(def_sampler, frag_in.uuvv.xz).rgb;
  354. float3 rgb_topright = image.Sample(def_sampler, frag_in.uuvv.yz).rgb;
  355. float3 rgb_bottomleft = image.Sample(def_sampler, frag_in.uuvv.xw).rgb;
  356. float3 rgb_bottomright = image.Sample(def_sampler, frag_in.uuvv.yw).rgb;
  357. float3 rgb = (rgb_topleft + rgb_topright + rgb_bottomleft + rgb_bottomright) * 0.25;
  358. rgb = srgb_linear_to_nonlinear(rgb);
  359. float v = dot(color_vec2.xyz, rgb) + color_vec2.w;
  360. return v * (1023. / 65535.);
  361. }
  362. float3 YUV_to_RGB(float3 yuv)
  363. {
  364. yuv = clamp(yuv, color_range_min, color_range_max);
  365. float r = dot(color_vec0.xyz, yuv) + color_vec0.w;
  366. float g = dot(color_vec1.xyz, yuv) + color_vec1.w;
  367. float b = dot(color_vec2.xyz, yuv) + color_vec2.w;
  368. return float3(r, g, b);
  369. }
  370. float3 PSUYVY_Reverse(FragTex frag_in) : TARGET
  371. {
  372. float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
  373. float2 y01 = y2uv.yw;
  374. float2 cbcr = y2uv.zx;
  375. float leftover = frac(frag_in.uv.x);
  376. float y = (leftover < 0.5) ? y01.x : y01.y;
  377. float3 yuv = float3(y, cbcr);
  378. float3 rgb = YUV_to_RGB(yuv);
  379. return rgb;
  380. }
  381. float3 PSYUY2_Reverse(FragTex frag_in) : TARGET
  382. {
  383. float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
  384. float2 y01 = y2uv.zx;
  385. float2 cbcr = y2uv.yw;
  386. float leftover = frac(frag_in.uv.x);
  387. float y = (leftover < 0.5) ? y01.x : y01.y;
  388. float3 yuv = float3(y, cbcr);
  389. float3 rgb = YUV_to_RGB(yuv);
  390. return rgb;
  391. }
  392. float3 PSYVYU_Reverse(FragTex frag_in) : TARGET
  393. {
  394. float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
  395. float2 y01 = y2uv.zx;
  396. float2 cbcr = y2uv.wy;
  397. float leftover = frac(frag_in.uv.x);
  398. float y = (leftover < 0.5) ? y01.x : y01.y;
  399. float3 yuv = float3(y, cbcr);
  400. float3 rgb = YUV_to_RGB(yuv);
  401. return rgb;
  402. }
  403. float3 PSPlanar420_Reverse(VertTexPos frag_in) : TARGET
  404. {
  405. float y = image.Load(int3(frag_in.pos.xy, 0)).x;
  406. int3 xy0_chroma = int3(frag_in.uv, 0);
  407. float cb = image1.Load(xy0_chroma).x;
  408. float cr = image2.Load(xy0_chroma).x;
  409. float3 yuv = float3(y, cb, cr);
  410. float3 rgb = YUV_to_RGB(yuv);
  411. return rgb;
  412. }
  413. float4 PSPlanar420A_Reverse(VertTexPos frag_in) : TARGET
  414. {
  415. int3 xy0_luma = int3(frag_in.pos.xy, 0);
  416. float y = image.Load(xy0_luma).x;
  417. int3 xy0_chroma = int3(frag_in.uv, 0);
  418. float cb = image1.Load(xy0_chroma).x;
  419. float cr = image2.Load(xy0_chroma).x;
  420. float alpha = image3.Load(xy0_luma).x;
  421. float3 yuv = float3(y, cb, cr);
  422. float4 rgba = float4(YUV_to_RGB(yuv), alpha);
  423. return rgba;
  424. }
  425. float3 PSPlanar422_Reverse(FragPosWide frag_in) : TARGET
  426. {
  427. float y = image.Load(int3(frag_in.pos_wide.xz, 0)).x;
  428. int3 xy0_chroma = int3(frag_in.pos_wide.yz, 0);
  429. float cb = image1.Load(xy0_chroma).x;
  430. float cr = image2.Load(xy0_chroma).x;
  431. float3 yuv = float3(y, cb, cr);
  432. float3 rgb = YUV_to_RGB(yuv);
  433. return rgb;
  434. }
  435. float4 PSPlanar422A_Reverse(FragPosWide frag_in) : TARGET
  436. {
  437. int3 xy0_luma = int3(frag_in.pos_wide.xz, 0);
  438. float y = image.Load(xy0_luma).x;
  439. int3 xy0_chroma = int3(frag_in.pos_wide.yz, 0);
  440. float cb = image1.Load(xy0_chroma).x;
  441. float cr = image2.Load(xy0_chroma).x;
  442. float alpha = image3.Load(xy0_luma).x;
  443. float3 yuv = float3(y, cb, cr);
  444. float4 rgba = float4(YUV_to_RGB(yuv), alpha);
  445. return rgba;
  446. }
  447. float3 PSPlanar444_Reverse(FragPos frag_in) : TARGET
  448. {
  449. int3 xy0 = int3(frag_in.pos.xy, 0);
  450. float y = image.Load(xy0).x;
  451. float cb = image1.Load(xy0).x;
  452. float cr = image2.Load(xy0).x;
  453. float3 yuv = float3(y, cb, cr);
  454. float3 rgb = YUV_to_RGB(yuv);
  455. return rgb;
  456. }
  457. float4 PSPlanar444A_Reverse(FragPos frag_in) : TARGET
  458. {
  459. int3 xy0 = int3(frag_in.pos.xy, 0);
  460. float y = image.Load(xy0).x;
  461. float cb = image1.Load(xy0).x;
  462. float cr = image2.Load(xy0).x;
  463. float alpha = image3.Load(xy0).x;
  464. float3 yuv = float3(y, cb, cr);
  465. float4 rgba = float4(YUV_to_RGB(yuv), alpha);
  466. return rgba;
  467. }
  468. float4 PSAYUV_Reverse(FragPos frag_in) : TARGET
  469. {
  470. float4 yuva = image.Load(int3(frag_in.pos.xy, 0));
  471. float4 rgba = float4(YUV_to_RGB(yuva.xyz), yuva.a);
  472. return rgba;
  473. }
  474. float3 PSNV12_Reverse(VertTexPos frag_in) : TARGET
  475. {
  476. float y = image.Load(int3(frag_in.pos.xy, 0)).x;
  477. float2 cbcr = image1.Load(int3(frag_in.uv, 0)).xy;
  478. float3 yuv = float3(y, cbcr);
  479. float3 rgb = YUV_to_RGB(yuv);
  480. return rgb;
  481. }
  482. float4 PSI010_SRGB_Reverse(VertTexPos frag_in) : TARGET
  483. {
  484. float ratio = 65535. / 1023.;
  485. float y = image.Load(int3(frag_in.pos.xy, 0)).x * ratio;
  486. int3 xy0_chroma = int3(frag_in.uv, 0);
  487. float cb = image1.Load(xy0_chroma).x * ratio;
  488. float cr = image2.Load(xy0_chroma).x * ratio;
  489. float3 yuv = float3(y, cb, cr);
  490. float3 rgb = YUV_to_RGB(yuv);
  491. rgb = srgb_nonlinear_to_linear(rgb);
  492. return float4(rgb, 1.0);
  493. }
  494. float4 PSI010_PQ_2020_709_Reverse(VertTexPos frag_in) : TARGET
  495. {
  496. float ratio = 65535. / 1023.;
  497. float y = image.Load(int3(frag_in.pos.xy, 0)).x * ratio;
  498. int3 xy0_chroma = int3(frag_in.uv, 0);
  499. float cb = image1.Load(xy0_chroma).x * ratio;
  500. float cr = image2.Load(xy0_chroma).x * ratio;
  501. float3 yuv = float3(y, cb, cr);
  502. float3 pq = YUV_to_RGB(yuv);
  503. float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
  504. float3 rgb = rec2020_to_rec709(hdr2020);
  505. return float4(rgb, 1.0);
  506. }
  507. float4 PSI010_HLG_2020_709_Reverse(VertTexPos frag_in) : TARGET
  508. {
  509. float ratio = 65535. / 1023.;
  510. float y = image.Load(int3(frag_in.pos.xy, 0)).x * ratio;
  511. int3 xy0_chroma = int3(frag_in.uv, 0);
  512. float cb = image1.Load(xy0_chroma).x * ratio;
  513. float cr = image2.Load(xy0_chroma).x * ratio;
  514. float3 yuv = float3(y, cb, cr);
  515. float3 hlg = YUV_to_RGB(yuv);
  516. float3 hdr2020 = hlg_to_linear(hlg, hlg_exponent) * maximum_over_sdr_white_nits;
  517. float3 rgb = rec2020_to_rec709(hdr2020);
  518. return float4(rgb, 1.0);
  519. }
  520. float4 PSP010_SRGB_Reverse(VertTexPos frag_in) : TARGET
  521. {
  522. float y = image.Load(int3(frag_in.pos.xy, 0)).x;
  523. float2 cbcr = image1.Load(int3(frag_in.uv, 0)).xy;
  524. float3 yuv = float3(y, cbcr);
  525. float3 rgb = YUV_to_RGB(yuv);
  526. rgb = srgb_nonlinear_to_linear(rgb);
  527. return float4(rgb, 1.0);
  528. }
  529. float4 PSP010_PQ_2020_709_Reverse(VertTexPos frag_in) : TARGET
  530. {
  531. float y = image.Load(int3(frag_in.pos.xy, 0)).x;
  532. float2 cbcr = image1.Load(int3(frag_in.uv, 0)).xy;
  533. float3 yuv = float3(y, cbcr);
  534. float3 pq = YUV_to_RGB(yuv);
  535. float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
  536. float3 rgb = rec2020_to_rec709(hdr2020);
  537. return float4(rgb, 1.0);
  538. }
  539. float4 PSP010_HLG_2020_709_Reverse(VertTexPos frag_in) : TARGET
  540. {
  541. float y = image.Load(int3(frag_in.pos.xy, 0)).x;
  542. float2 cbcr = image1.Load(int3(frag_in.uv, 0)).xy;
  543. float3 yuv = float3(y, cbcr);
  544. float3 hlg = YUV_to_RGB(yuv);
  545. float3 hdr2020 = hlg_to_linear(hlg, hlg_exponent) * maximum_over_sdr_white_nits;
  546. float3 rgb = rec2020_to_rec709(hdr2020);
  547. return float4(rgb, 1.0);
  548. }
  549. float3 PSY800_Limited(FragPos frag_in) : TARGET
  550. {
  551. float limited = image.Load(int3(frag_in.pos.xy, 0)).x;
  552. float full = (255.0 / 219.0) * limited - (16.0 / 219.0);
  553. return float3(full, full, full);
  554. }
  555. float3 PSY800_Full(FragPos frag_in) : TARGET
  556. {
  557. float3 full = image.Load(int3(frag_in.pos.xy, 0)).xxx;
  558. return full;
  559. }
  560. float4 PSRGB_Limited(FragPos frag_in) : TARGET
  561. {
  562. float4 rgba = image.Load(int3(frag_in.pos.xy, 0));
  563. rgba.rgb = (255.0 / 219.0) * rgba.rgb - (16.0 / 219.0);
  564. return rgba;
  565. }
  566. float3 PSBGR3_Limited(FragPos frag_in) : TARGET
  567. {
  568. float x = frag_in.pos.x * 3.0;
  569. float y = frag_in.pos.y;
  570. float b = image.Load(int3(x - 1.0, y, 0)).x;
  571. float g = image.Load(int3(x, y, 0)).x;
  572. float r = image.Load(int3(x + 1.0, y, 0)).x;
  573. float3 rgb = float3(r, g, b);
  574. rgb = (255.0 / 219.0) * rgb - (16.0 / 219.0);
  575. return rgb;
  576. }
  577. float3 PSBGR3_Full(FragPos frag_in) : TARGET
  578. {
  579. float x = frag_in.pos.x * 3.0;
  580. float y = frag_in.pos.y;
  581. float b = image.Load(int3(x - 1.0, y, 0)).x;
  582. float g = image.Load(int3(x, y, 0)).x;
  583. float r = image.Load(int3(x + 1.0, y, 0)).x;
  584. float3 rgb = float3(r, g, b);
  585. return rgb;
  586. }
  587. technique Planar_Y
  588. {
  589. pass
  590. {
  591. vertex_shader = VSPos(id);
  592. pixel_shader = PS_Y(frag_in);
  593. }
  594. }
  595. technique Planar_U
  596. {
  597. pass
  598. {
  599. vertex_shader = VSPos(id);
  600. pixel_shader = PS_U(frag_in);
  601. }
  602. }
  603. technique Planar_V
  604. {
  605. pass
  606. {
  607. vertex_shader = VSPos(id);
  608. pixel_shader = PS_V(frag_in);
  609. }
  610. }
  611. technique Planar_U_Left
  612. {
  613. pass
  614. {
  615. vertex_shader = VSTexPos_Left(id);
  616. pixel_shader = PS_U_Wide(frag_in);
  617. }
  618. }
  619. technique Planar_V_Left
  620. {
  621. pass
  622. {
  623. vertex_shader = VSTexPos_Left(id);
  624. pixel_shader = PS_V_Wide(frag_in);
  625. }
  626. }
  627. technique NV12_Y
  628. {
  629. pass
  630. {
  631. vertex_shader = VSPos(id);
  632. pixel_shader = PS_Y(frag_in);
  633. }
  634. }
  635. technique NV12_UV
  636. {
  637. pass
  638. {
  639. vertex_shader = VSTexPos_Left(id);
  640. pixel_shader = PS_UV_Wide(frag_in);
  641. }
  642. }
  643. technique I010_PQ_Y
  644. {
  645. pass
  646. {
  647. vertex_shader = VSPos(id);
  648. pixel_shader = PS_I010_PQ_Y_709_2020(frag_in);
  649. }
  650. }
  651. technique I010_HLG_Y
  652. {
  653. pass
  654. {
  655. vertex_shader = VSPos(id);
  656. pixel_shader = PS_I010_HLG_Y_709_2020(frag_in);
  657. }
  658. }
  659. technique I010_SRGB_Y
  660. {
  661. pass
  662. {
  663. vertex_shader = VSPos(id);
  664. pixel_shader = PS_I010_SRGB_Y(frag_in);
  665. }
  666. }
  667. technique I010_PQ_U
  668. {
  669. pass
  670. {
  671. vertex_shader = VSTexPos_TopLeft(id);
  672. pixel_shader = PS_I010_PQ_U_709_2020_WideWide(frag_in);
  673. }
  674. }
  675. technique I010_HLG_U
  676. {
  677. pass
  678. {
  679. vertex_shader = VSTexPos_TopLeft(id);
  680. pixel_shader = PS_I010_HLG_U_709_2020_WideWide(frag_in);
  681. }
  682. }
  683. technique I010_SRGB_U
  684. {
  685. pass
  686. {
  687. vertex_shader = VSTexPos_TopLeft(id);
  688. pixel_shader = PS_I010_SRGB_U_WideWide(frag_in);
  689. }
  690. }
  691. technique I010_PQ_V
  692. {
  693. pass
  694. {
  695. vertex_shader = VSTexPos_TopLeft(id);
  696. pixel_shader = PS_I010_PQ_V_709_2020_WideWide(frag_in);
  697. }
  698. }
  699. technique I010_HLG_V
  700. {
  701. pass
  702. {
  703. vertex_shader = VSTexPos_TopLeft(id);
  704. pixel_shader = PS_I010_HLG_V_709_2020_WideWide(frag_in);
  705. }
  706. }
  707. technique I010_SRGB_V
  708. {
  709. pass
  710. {
  711. vertex_shader = VSTexPos_TopLeft(id);
  712. pixel_shader = PS_I010_SRGB_V_WideWide(frag_in);
  713. }
  714. }
  715. technique P010_PQ_Y
  716. {
  717. pass
  718. {
  719. vertex_shader = VSPos(id);
  720. pixel_shader = PS_PQ_Y_709_2020(frag_in);
  721. }
  722. }
  723. technique P010_HLG_Y
  724. {
  725. pass
  726. {
  727. vertex_shader = VSPos(id);
  728. pixel_shader = PS_HLG_Y_709_2020(frag_in);
  729. }
  730. }
  731. technique P010_SRGB_Y
  732. {
  733. pass
  734. {
  735. vertex_shader = VSPos(id);
  736. pixel_shader = PS_SRGB_Y(frag_in);
  737. }
  738. }
  739. technique P010_PQ_UV
  740. {
  741. pass
  742. {
  743. vertex_shader = VSTexPos_TopLeft(id);
  744. pixel_shader = PS_PQ_UV_709_2020_WideWide(frag_in);
  745. }
  746. }
  747. technique P010_HLG_UV
  748. {
  749. pass
  750. {
  751. vertex_shader = VSTexPos_TopLeft(id);
  752. pixel_shader = PS_HLG_UV_709_2020_WideWide(frag_in);
  753. }
  754. }
  755. technique P010_SRGB_UV
  756. {
  757. pass
  758. {
  759. vertex_shader = VSTexPos_TopLeft(id);
  760. pixel_shader = PS_SRGB_UV_WideWide(frag_in);
  761. }
  762. }
  763. technique UYVY_Reverse
  764. {
  765. pass
  766. {
  767. vertex_shader = VSTexPosHalf_Reverse(id);
  768. pixel_shader = PSUYVY_Reverse(frag_in);
  769. }
  770. }
  771. technique YUY2_Reverse
  772. {
  773. pass
  774. {
  775. vertex_shader = VSTexPosHalf_Reverse(id);
  776. pixel_shader = PSYUY2_Reverse(frag_in);
  777. }
  778. }
  779. technique YVYU_Reverse
  780. {
  781. pass
  782. {
  783. vertex_shader = VSTexPosHalf_Reverse(id);
  784. pixel_shader = PSYVYU_Reverse(frag_in);
  785. }
  786. }
  787. technique I420_Reverse
  788. {
  789. pass
  790. {
  791. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  792. pixel_shader = PSPlanar420_Reverse(frag_in);
  793. }
  794. }
  795. technique I40A_Reverse
  796. {
  797. pass
  798. {
  799. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  800. pixel_shader = PSPlanar420A_Reverse(frag_in);
  801. }
  802. }
  803. technique I422_Reverse
  804. {
  805. pass
  806. {
  807. vertex_shader = VSPosWide_Reverse(id);
  808. pixel_shader = PSPlanar422_Reverse(frag_in);
  809. }
  810. }
  811. technique I42A_Reverse
  812. {
  813. pass
  814. {
  815. vertex_shader = VSPosWide_Reverse(id);
  816. pixel_shader = PSPlanar422A_Reverse(frag_in);
  817. }
  818. }
  819. technique I444_Reverse
  820. {
  821. pass
  822. {
  823. vertex_shader = VSPos(id);
  824. pixel_shader = PSPlanar444_Reverse(frag_in);
  825. }
  826. }
  827. technique YUVA_Reverse
  828. {
  829. pass
  830. {
  831. vertex_shader = VSPos(id);
  832. pixel_shader = PSPlanar444A_Reverse(frag_in);
  833. }
  834. }
  835. technique AYUV_Reverse
  836. {
  837. pass
  838. {
  839. vertex_shader = VSPos(id);
  840. pixel_shader = PSAYUV_Reverse(frag_in);
  841. }
  842. }
  843. technique NV12_Reverse
  844. {
  845. pass
  846. {
  847. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  848. pixel_shader = PSNV12_Reverse(frag_in);
  849. }
  850. }
  851. technique I010_SRGB_Reverse
  852. {
  853. pass
  854. {
  855. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  856. pixel_shader = PSI010_SRGB_Reverse(frag_in);
  857. }
  858. }
  859. technique I010_PQ_2020_709_Reverse
  860. {
  861. pass
  862. {
  863. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  864. pixel_shader = PSI010_PQ_2020_709_Reverse(frag_in);
  865. }
  866. }
  867. technique I010_HLG_2020_709_Reverse
  868. {
  869. pass
  870. {
  871. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  872. pixel_shader = PSI010_HLG_2020_709_Reverse(frag_in);
  873. }
  874. }
  875. technique P010_SRGB_Reverse
  876. {
  877. pass
  878. {
  879. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  880. pixel_shader = PSP010_SRGB_Reverse(frag_in);
  881. }
  882. }
  883. technique P010_PQ_2020_709_Reverse
  884. {
  885. pass
  886. {
  887. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  888. pixel_shader = PSP010_PQ_2020_709_Reverse(frag_in);
  889. }
  890. }
  891. technique P010_HLG_2020_709_Reverse
  892. {
  893. pass
  894. {
  895. vertex_shader = VSTexPosHalfHalf_Reverse(id);
  896. pixel_shader = PSP010_HLG_2020_709_Reverse(frag_in);
  897. }
  898. }
  899. technique Y800_Limited
  900. {
  901. pass
  902. {
  903. vertex_shader = VSPos(id);
  904. pixel_shader = PSY800_Limited(frag_in);
  905. }
  906. }
  907. technique Y800_Full
  908. {
  909. pass
  910. {
  911. vertex_shader = VSPos(id);
  912. pixel_shader = PSY800_Full(frag_in);
  913. }
  914. }
  915. technique RGB_Limited
  916. {
  917. pass
  918. {
  919. vertex_shader = VSPos(id);
  920. pixel_shader = PSRGB_Limited(frag_in);
  921. }
  922. }
  923. technique BGR3_Limited
  924. {
  925. pass
  926. {
  927. vertex_shader = VSPos(id);
  928. pixel_shader = PSBGR3_Limited(frag_in);
  929. }
  930. }
  931. technique BGR3_Full
  932. {
  933. pass
  934. {
  935. vertex_shader = VSPos(id);
  936. pixel_shader = PSBGR3_Full(frag_in);
  937. }
  938. }