1// Always provided by OBS
2uniform float4x4 ViewProj<
3	bool automatic = true;
4	string name = "View Projection Matrix";
5>;
6
7// Provided by Stream Effects
8uniform float4 Time<
9	bool automatic = true;
10	string name = "Time Array";
11	string description = "A float4 value containing the total time, rendering time and the time since the last tick. The last value is a random number between 0 and 1.";
12>;
13uniform float4x4 Random<
14	bool automatic = true;
15	string name = "Random Array";
16	string description = "A float4x4 value containing random values between 0 and 1";
17>;
18uniform float4 ViewSize<
19	bool automatic = true;
20>;
21uniform texture2d InputA<
22	bool automatic = true;
23>;
24
25uniform float _0_Strength<
26	string name = "Strength";
27	string field_type = "slider";
28	float minimum = 0.;
29	float maximum = 100.;
30	float step = 0.01;
31	float scale = 0.01;
32> = 100.0;
33uniform int _1_Scanlines<
34	string name = "Scanlines";
35	string field_type = "slider";
36	int minimum = 128;
37	int maximum = 16384;
38	int step = 1;
39> = 525;
40
41uniform float2 _1_Intensity<
42	string name = "Intensity Limits";
43	string field_type = "slider";
44	float2 minimum = {0., 0.};
45	float2 maximum = {100., 100.};
46	float2 step = {0.01, 0.01};
47	float2 scale = {0.01, 0.01};
48> = {95.0, 100.0};
49uniform bool _2_EnableBleed<
50	string name = "Enable NTSC Bleeding";
51> = true;
52uniform float _3_ScanlineSize<
53	string name = "Scanline Scaling";
54	string field_type = "slider";
55	float minimum = 0.01;
56	float maximum = 100.;
57	float step = 0.01;
58	float scale = 0.01;
59> = 100.0;
60uniform float _4_Speed<
61	string name = "Timescale";
62	string field_type = "slider";
63	float minimum = 0.01;
64	float maximum = 100.;
65	float step = 0.01;
66	float scale = 0.01;
67> = 60.0;
68
69
70#define PI		3.1415926f
71#define TwoPI	6.2831853f
72#define HalfPI	1.5707963f
73
74// ---------- Shader Code
75sampler_state def_sampler {
76	AddressU  = Clamp;
77	AddressV  = Clamp;
78	Filter    = Linear;
79};
80
81struct VertData {
82	float4 pos : POSITION;
83	float2 uv  : TEXCOORD0;
84};
85
86VertData VSDefault(VertData v_in) {
87	VertData vert_out;
88	vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
89	vert_out.uv  = v_in.uv;
90	return vert_out;
91}
92
93float4 PSDefault(VertData v_in) : TARGET {
94	float2 uv = v_in.uv;
95	float time_offset = Time.y * _4_Speed;
96
97	// Scanline stuff.
98	uint scanline_index = floor(fmod((uv.y + time_offset), 1.) * _1_Scanlines);
99	uint scanline_intensity = scanline_index % 2;
100
101	// Calculate final color;
102	float4 rgb = InputA.Sample(def_sampler, uv);
103
104	// Bleeding
105	if (_2_EnableBleed) {
106		// Not true bleeding, missing some gaussian blur.
107		float offset = float(scanline_intensity) * 0.0005;
108
109		float colorShift = 0.001;
110		float r = InputA.Sample(def_sampler, uv + offset + colorShift).r;
111		float g = InputA.Sample(def_sampler, uv + offset - colorShift).g;
112		float b = rgb.b;
113
114		rgb.rgb = float3(r, g, b); // g * 0.99?
115	}
116
117	// Intensity;
118	rgb.rgb *= clamp(float(scanline_intensity), _1_Intensity.x, _1_Intensity.y);
119
120	// rollbar
121	const float rollbar_cycle_length = 5.;
122	float rollbar_cycle = Time.y + fmod(Time.z, rollbar_cycle_length);
123	float rollbar = sin((uv.y + rollbar_cycle / rollbar_cycle_length) * TwoPI);
124	rgb.rgb = lerp(rgb, rgb + (rollbar * 0.1), _0_Strength);
125
126	return rgb;
127}
128
129technique Draw
130{
131	pass
132	{
133		vertex_shader = VSDefault(v_in);
134		pixel_shader  = PSDefault(v_in);
135	}
136}
137