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>;
24uniform texture2d InputB<
25	bool automatic = true;
26>;
27uniform float TransitionTime<
28	bool automatic = true;
29>;
30uniform int2 TransitionSize<
31	bool automatic = true;
32>;
33
34uniform bool _0_oldStyle<
35	string name = "Retro Style";
36
37> = false;
38uniform float2 _1_pixelateCenter<
39	string name = "Pixelation Center";
40	string field_type = "slider";
41	float2 minimum = {0., 0.};
42	float2 maximum = {100., 100.};
43	float2 scale = {0.01, 0.01};
44> = {50., 50.};
45uniform float _2_maximumBlockSize<
46	string name = "Maximum Pixelation";
47	string field_type = "slider";
48	float minimum = 1.0;
49	float maximum = 16.0;
50	float step = 1.0;
51> = 12.;
52uniform float2 _3_blockOffset<
53	string name = "Block Offset";
54	string field_type = "slider";
55	float2 minimum = {0., 0.};
56	float2 maximum = {100., 100.};
57	float2 scale = {0.01, 0.01};
58> = {50., 50.};
59uniform float _4_transitionRange<
60	string name = "Transition Range";
61	string field_type = "slider";
62	float minimum = 0.;
63	float maximum = 100.;
64	float scale = .005;
65	float step = .01;
66> = 25.0;
67
68// ---------- Shader Code
69sampler_state def_sampler {
70	AddressU  = Clamp;
71	AddressV  = Clamp;
72	Filter    = Linear;
73};
74
75struct VertData {
76	float4 pos : POSITION;
77	float2 uv  : TEXCOORD0;
78};
79
80VertData VSDefault(VertData v_in) {
81	VertData vert_out;
82	vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
83	vert_out.uv  = v_in.uv;
84	return vert_out;
85}
86
87float4 PSDefault(VertData v_in) : TARGET {
88    float animProgress = TransitionTime;
89
90	// Progress as a bounce value (0..1..0)
91    float animStuff = 1.0 - (abs(animProgress - 0.5) * 2.0);
92    // There are two ways to calculate this, one is pixel aligned the other is block aligned.
93	float animBlockSize = 0;
94    if (_0_oldStyle) {
95		// Block Size, always a multiple of 2. (Block Aligned)
96		animBlockSize = pow(2.0, floor(_2_maximumBlockSize * animStuff));
97	} else {
98		// Block Size, always a multiple of 2. (Pixel Aligned)
99		animBlockSize = floor(pow(2.0, _2_maximumBlockSize * animStuff));
100	}
101
102	// UV Calculations
103	float2 finalUV = v_in.uv;
104	finalUV -= _1_pixelateCenter;				// Offset by the pixelation center.
105	finalUV *= ViewSize.xy;					// Convert to 0..Resolution UVs for pixelation.
106	finalUV /= animBlockSize;				// Divide by current block size.
107	finalUV = floor(finalUV) + _3_blockOffset;	// Use floor() on it to get aligned pixels.
108	finalUV *= animBlockSize;				// Multiply by current block size.
109	finalUV *= ViewSize.zw;					// Convert back to 0..1 UVs for texture sampling.
110	finalUV += _1_pixelateCenter;				// Revert the offset by the pixelation center again.
111
112	float4 sampleA = InputA.Sample(def_sampler, finalUV);
113	float4 sampleB = InputB.Sample(def_sampler, finalUV);
114
115	float transition = clamp(
116		((TransitionTime - 0.5) / _4_transitionRange) * .5 + .5,
117		0.,
118		1.
119	);
120
121	float4 rgb = lerp(sampleA, sampleB, transition);
122
123	return rgb;
124}
125
126technique Draw
127{
128	pass
129	{
130		vertex_shader = VSDefault(v_in);
131		pixel_shader  = PSDefault(v_in);
132	}
133}
134