forked from linnaea/obs-rotaeno-stablizer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rotaeno-stablizer.effect
69 lines (56 loc) · 1.81 KB
/
rotaeno-stablizer.effect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#define PI 3.14159265
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float2 offset_s;
uniform float2 aspect_s;
sampler_state sp_linear
{
Filter = Linear;
AddressU = Border;
AddressV = Border;
BorderColor = 00000000;
};
struct vertex_data
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
vertex_data vertex_shader_main(vertex_data v_in)
{
vertex_data v_out;
v_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
v_out.uv = v_in.uv;
return v_out;
}
float4 pixel_shader_main(vertex_data v_in) : TARGET
{
float4 sFullCcw = image.Sample(sp_linear, offset_s);
float4 sFullCw = image.Sample(sp_linear, float2(1,1)-offset_s);
float4 sHorizon = image.Sample(sp_linear, float2(1-offset_s.x,offset_s.y));
float dFullCw = distance(sHorizon, sFullCw);
float dFullCcw = distance(sHorizon, sFullCcw);
float rotation = 0;
if (dFullCw != 0 && dFullCcw != 0) {
float4 sRotation = image.Sample(sp_linear, float2(offset_s.x,1-offset_s.y));
float dCw = distance(sRotation, sFullCw) / dFullCw;
float dCcw = distance(sRotation, sFullCcw) / dFullCcw;
rotation = (1-min(dCw, dCcw)/min(1, max(dCw, dCcw))) * PI * (dCw < dCcw ? 1 : -1);
}
#ifdef _OPENGL
mat2 mRotation = mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation));
#else
float2x2 mRotation = {cos(rotation), -sin(rotation), sin(rotation), cos(rotation)};
#endif
float2 p_source = mul(mRotation, v_in.uv - 0.5) + 0.5;
p_source = p_source * aspect_s;
p_source = p_source + (1 - aspect_s) / 2;
return image.Sample(sp_linear, p_source);
}
technique Draw
{
pass
{
vertex_shader = vertex_shader_main(v_in);
pixel_shader = pixel_shader_main(v_in);
}
}