1// Always provided by OBS
2uniform float4x4 ViewProj<
3	bool visible = false;
4	string name = "View Projection Matrix";
5>;
6
7// Provided by Stream Effects
8uniform float4 Time<
9	bool visible = false;
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 visible = false;
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
25// Shader Parameters
26uniform float p_drunk_strength<
27	bool visible = true;
28	string field_type = "slider";
29	string name = "Strength";
30	float minimum = 0.;
31	float maximum = 100.;
32	float step = .01;
33> = 25.0;
34uniform float p_drunk_speed<
35	bool visible = true;
36	string field_type = "slider";
37	string name = "Speed";
38	float minimum = 0.;
39	float maximum = 100.;
40	float step = .01;
41> = 2.0;
42
43// ---------- Shader Code
44sampler_state def_sampler {
45	AddressU  = Clamp;
46	AddressV  = Clamp;
47	Filter    = Linear;
48};
49
50struct VertData {
51	float4 pos : POSITION;
52	float2 uv  : TEXCOORD0;
53};
54
55VertData VSDefault(VertData vtx) {
56	vtx.pos = mul(float4(vtx.pos.xyz, 1.0), ViewProj);
57	return vtx;
58}
59
60#define MAX_PTS 5
61#define MAX_LINE 5.
62
63float random_time_at(int x, int y) {
64	const float ts[MAX_PTS + 1][MAX_PTS + 1] = {
65		{.2, .8, -.2, .452, -.2832, .8},
66		{-.28, -1, -.42, -.89, .72, -.29},
67		{.75, .25, .33, .67, .98, .01},
68		{-.28, 0.8, -.32, -.189, .11, .84},
69		{-.48, 0.1, -.2323, -.555, .421, .23},
70		{-.28, 0.3, -1.3333, 1.333, 4, 1},
71	};
72
73	return ts[x][y];
74}
75
76float2 mult_at(int x, int y) {
77	float x2 = fmod(x, 2.);
78	float y2 = fmod(y, 2.);
79
80	float2 mult;
81	mult.x = (x2 < 1.) ? -1. : 1.;
82	mult.y = (y2 < 1.) ? -1. : 1.;
83
84	return mult;
85}
86
87float4 PSDrunkStage1(VertData vtx) : TARGET {
88	float2 uvs[MAX_PTS + 1][MAX_PTS + 1];
89	for (int x = 0; x <= MAX_PTS; x++) {
90		for (int y = 0; y <= MAX_PTS; y++) {
91			float2 off = float2(0, 0);
92			if ((x > 0) && (x < MAX_PTS)) {
93				off.x = cos(Time.x * p_drunk_speed + random_time_at(x, y)) * ViewSize.z;
94			}
95			if ((y > 0) && (y < MAX_PTS)) {
96				off.y = sin(Time.x * p_drunk_speed + random_time_at(x, y)) * ViewSize.w;
97			}
98			off *= (p_drunk_strength / 100.0) * ViewSize.xy * 0.5 * mult_at(x, y);
99
100			uvs[x][y] = float2(x / MAX_LINE + off.x, y / MAX_LINE + off.y);
101		}
102	}
103
104	float2 fade = frac(vtx.uv * MAX_LINE);
105	fade = (sin((fade - 0.5) * 3.141) + 1.0) * 0.5;
106
107	int2 _low = int2(floor(vtx.uv * MAX_LINE));
108	int2 _hig = int2(ceil(vtx.uv * MAX_LINE));
109
110	float2 uv = vtx.uv;
111	float2 uv_tl = uvs[_low.x][_low.y];
112	float2 uv_tr = uvs[_hig.x][_low.y];
113	float2 uv_bl = uvs[_low.x][_hig.y];
114	float2 uv_br = uvs[_hig.x][_hig.y];
115
116	float2 uv_t = lerp(uv_tl, uv_tr, fade.x);
117	float2 uv_b = lerp(uv_bl, uv_br, fade.x);
118	uv = lerp(uv_t, uv_b, fade.y);
119
120	return InputA.Sample(def_sampler, uv);
121}
122
123technique Draw
124{
125	pass
126	{
127		vertex_shader = VSDefault(vtx);
128		pixel_shader  = PSDrunkStage1(vtx);
129	}
130}
131