Guest User

Untitled

a guest
Jun 26th, 2017
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.90 KB | None | 0 0
  1. /*
  2. pal-singlepass.slang
  3.  
  4. svo's PAL single pass shader, ported to libretro
  5. ------------------------------------------------
  6. "Software composite video modulation/demodulation experiments
  7.  
  8. The idea is to reproduce in GLSL shaders realistic composite-like
  9. artifacting by applying PAL modulation and demodulation.
  10.  
  11. Digital texture, passed through the model of an analog channel,
  12. should suffer same effects as its analog counterpart and exhibit properties,
  13. such as dot crawl and colour bleeding, that may be desirable for faithful
  14. reproduction of look and feel of old computer games."
  15.  
  16. https://github.com/svofski/CRT
  17.  
  18. Copyright (c) 2016, Viacheslav Slavinsky
  19. All rights reserved.
  20.  
  21. Redistribution and use in source and binary forms, with or without
  22. modification, are permitted provided that the following conditions are met:
  23.  
  24. 1. Redistributions of source code must retain the above copyright notice,
  25. this list of conditions and the following disclaimer.
  26.  
  27. 2. Redistributions in binary form must reproduce the above copyright notice,
  28. this list of conditions and the following disclaimer in the documentation
  29. and/or other materials provided with the distribution.
  30.  
  31. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  32. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  34. ARE DISCLAIMED.
  35. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
  36. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  39. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  41. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. */
  43.  
  44. #include "ReShade.fxh"
  45.  
  46. uniform float texture_sizeX <
  47. ui_type = "drag";
  48. ui_min = 1.0;
  49. ui_max = BUFFER_WIDTH;
  50. ui_label = "Screen Width [PAL]";
  51. > = 320.0;
  52.  
  53. uniform float texture_sizeY <
  54. ui_type = "drag";
  55. ui_min = 1.0;
  56. ui_max = BUFFER_HEIGHT;
  57. ui_label = "Screen Height [PAL]";
  58. > = 240.0;
  59.  
  60. uniform float FIR_GAIN <
  61. ui_type = "drag";
  62. ui_min = 0.0;
  63. ui_max = 5.0;
  64. ui_step = 0.1;
  65. ui_label = "FIR lowpass gain [PAL]";
  66. > = 1.5;
  67.  
  68. uniform float FIR_INVGAIN <
  69. ui_type = "drag";
  70. ui_min = 0.0;
  71. ui_max = 5.0;
  72. ui_step = 0.1;
  73. ui_label = "Inverse gain for luma recovery [PAL]";
  74. > = 1.1;
  75.  
  76. uniform float PHASE_NOISE <
  77. ui_type = "drag";
  78. ui_min = 0.0;
  79. ui_max = 5.0;
  80. ui_step = 0.1;
  81. ui_label = "Phase noise [PAL]";
  82. > = 1.0;
  83.  
  84. uniform int FrameCount < source = "framecount"; >;
  85.  
  86. /* Subcarrier frequency */
  87. #define FSC 4433618.75
  88.  
  89. /* Line frequency */
  90. #define FLINE 15625.
  91.  
  92. #define VISIBLELINES 312.
  93.  
  94. #define PI 3.14159265358
  95.  
  96. #define RGB_to_YIQ float3x3( 0.299, 0.595716, 0.211456,\
  97. 0.587, -0.274453, -0.522591,\
  98. 0.114, -0.321263, 0.311135)
  99.  
  100. #define YIQ_to_RGB float3x3( 1.0 , 1.0, 1.0,\
  101. 0.9563, -0.2721, -1.1070,\
  102. 0.6210, -0.6474, 1.7046)
  103.  
  104. #define RGB_to_YUV float3x3( 0.299, -0.14713, 0.615,\
  105. 0.587, -0.28886, -0.514991,\
  106. 0.114, 0.436, -0.10001)
  107.  
  108. #define YUV_to_RGB float3x3( 1.0, 1.0, 1.0,\
  109. 0.0, -0.39465, 2.03211,\
  110. 1.13983, -0.58060, 0.0)
  111.  
  112. #define texture_size float2(texture_sizeX, texture_sizeY)
  113. #define SourceSize float4(texture_size, 1.0 / texture_size) //either TextureSize or InputSize
  114.  
  115. #define FIRTAPS 20
  116.  
  117. /* subcarrier counts per scan line = FSC/FLINE = 283.7516 */
  118. /* We save the reciprocal of this only to optimize it */
  119. float counts_per_scanline_reciprocal = 1.0 / (FSC/FLINE);
  120.  
  121. float width_ratio;
  122. float height_ratio;
  123. float altv;
  124. float invx;
  125.  
  126. float mod(float x, float y)
  127. {
  128. return x - y * floor(x/y);
  129. }
  130.  
  131. float rand(float2 co)
  132. {
  133. float a = 12.9898;
  134. float b = 78.233;
  135. float c = 43758.5453;
  136. float dt = dot(co.xy, float2(a, b));
  137. float sn = mod(dt,3.14);
  138.  
  139. return frac(sin(sn) * c);
  140. }
  141.  
  142. float modulated(float2 xy, float sinwt, float coswt)
  143. {
  144. float3 rgb = tex2D(ReShade::BackBuffer, float2((0.0) * (invx) + xy.x, xy.y)).xyz;
  145. float3 yuv = RGB_to_YUV * rgb;
  146.  
  147. return clamp(yuv.x + yuv.y * sinwt + yuv.z * coswt, 0.0, 1.0);
  148. }
  149.  
  150. float2 modem_uv(float2 xy, float ofs) {
  151. float t = (xy.x + ofs * invx) * SourceSize.x;
  152. float wt = t * 2. * PI / width_ratio;
  153.  
  154. float sinwt = sin(wt);
  155. float coswt = cos(wt + altv);
  156.  
  157. float3 rgb = tex2D(ReShade::BackBuffer, float2((ofs) * (invx) + xy.x, xy.y)).xyz;
  158. float3 yuv = RGB_to_YUV * rgb;
  159. float signal = clamp(yuv.x + yuv.y * sinwt + yuv.z * coswt, 0.0, 1.0);
  160.  
  161. if (PHASE_NOISE != 0.)
  162. {
  163. /* .yy is horizontal noise, .xx looks bad, .xy is classic noise */
  164. float2 seed = xy.yy * float(FrameCount);
  165. wt = wt + PHASE_NOISE * (rand(seed) - 0.5);
  166. sinwt = sin(wt);
  167. coswt = cos(wt + altv);
  168. }
  169.  
  170. return float2(signal * sinwt, signal * coswt);
  171. }
  172.  
  173. void PS_PAL(float4 pos : SV_POSITION, float2 coords : TEXCOORD0, out float4 col : COLOR)
  174. {
  175. float2 xy = coords;
  176. width_ratio = SourceSize.x * (counts_per_scanline_reciprocal);
  177. height_ratio = SourceSize.y / VISIBLELINES;
  178. altv = mod(floor(xy.y * VISIBLELINES + 0.5), 2.0) * PI;
  179. invx = 0.25 * (counts_per_scanline_reciprocal); // equals 4 samples per Fsc period
  180.  
  181. float2 uv;
  182. float2 filtered = float2(0.0,0.0);
  183. float FIR1 = -0.008030271;
  184. float FIR2 = 0.003107906;
  185. float FIR3 = 0.016841352;
  186. float FIR4 = 0.032545161;
  187. float FIR5 = 0.049360136;
  188. float FIR6 = 0.066256720;
  189. float FIR7 = 0.082120150;
  190. float FIR8 = 0.095848433;
  191. float FIR9 = 0.106453014;
  192. float FIR10 = 0.113151423;
  193. float FIR11 = 0.115441842;
  194. float FIR12 = 0.113151423;
  195. float FIR13 = 0.106453014;
  196. float FIR14 = 0.095848433;
  197. float FIR15 = 0.082120150;
  198. float FIR16 = 0.066256720;
  199. float FIR17 = 0.049360136;
  200. float FIR18 = 0.032545161;
  201. float FIR19 = 0.016841352;
  202. float FIR20 = 0.003107906;
  203.  
  204. #define macro_loopz(c) uv = modem_uv(xy, float(c) - FIRTAPS*0.5); \
  205. filtered += FIR_GAIN * uv * FIR##c;
  206.  
  207. float FIR[20] = {
  208. -0.008030271,
  209. 0.003107906,
  210. 0.016841352,
  211. 0.032545161,
  212. 0.049360136,
  213. 0.066256720,
  214. 0.082120150,
  215. 0.095848433,
  216. 0.106453014,
  217. 0.113151423,
  218. 0.115441842,
  219. 0.113151423,
  220. 0.106453014,
  221. 0.095848433,
  222. 0.082120150,
  223. 0.066256720,
  224. 0.049360136,
  225. 0.032545161,
  226. 0.016841352,
  227. 0.003107906
  228. };
  229.  
  230. if(__RENDERER__ == 0x09300 || __RENDERER__ >= 0x10000){
  231. macro_loopz(1)
  232. macro_loopz(2)
  233. macro_loopz(3)
  234. macro_loopz(4)
  235. macro_loopz(5)
  236. macro_loopz(6)
  237. macro_loopz(7)
  238. macro_loopz(8)
  239. macro_loopz(9)
  240. macro_loopz(10)
  241. macro_loopz(11)
  242. macro_loopz(12)
  243. macro_loopz(13)
  244. macro_loopz(14)
  245. macro_loopz(15)
  246. macro_loopz(16)
  247. macro_loopz(17)
  248. macro_loopz(18)
  249. macro_loopz(19)
  250. macro_loopz(20)
  251. } else {
  252. for (int i = 0; i < FIRTAPS; i++) {
  253. float2 uv = modem_uv(xy, i - FIRTAPS*0.5);
  254. filtered += FIR_GAIN * uv * FIR[i];
  255. }
  256. }
  257.  
  258. float t = xy.x * SourceSize.x;
  259. float wt = t * 2. * PI / width_ratio;
  260.  
  261. float sinwt = sin(wt);
  262. float coswt = cos(wt + altv);
  263.  
  264. float luma = modulated(xy, sinwt, coswt) - FIR_INVGAIN * (filtered.x * sinwt + filtered.y * coswt);
  265. float3 yuv_result = float3(luma, filtered.x, filtered.y);
  266.  
  267. col = float4(YUV_to_RGB * yuv_result, 1.0);
  268. }
  269.  
  270. technique PAL
  271. {
  272. pass PAL
  273. {
  274. VertexShader = PostProcessVS;
  275. PixelShader = PS_PAL;
  276. }
  277. }
Advertisement
Add Comment
Please, Sign In to add comment