+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d9381f4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,208 @@
+# obs-xbrz
+
+## OBS XBRz-like shader fIlter
+
+1. get a copy of [obs-shaderfilter](https://github.com/exeldro/obs-shaderfilter/releases) plugin and install it
+2. place [files from this repo](./shaders) anywhere on your device
+3. add a userdefined shader to your source's filter list
+4. select the \*.effect file in the "load from file"
+5. toy with the settings!
+
+## Samples
+
+Below are some samples from Top Gear 2 for SMD/Genesis with settings applied
+
+### Title Screen
+
+
+ | no filter |
+ scalefx-like |
+
+
+ |
+ |
+
+
+ | no shader |
+
+ Single pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.50,
+ SamplingPointScale: 0.50
+ |
+
+
+ | xbrz-like |
+ two-pass |
+
+ |
+ |
+
+
+
+ Single pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.25,
+ SamplingPointScale: 1.00
+ |
+
+ First pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.25,
+ SamplingPointScale: 1.00
+ |
+
+ Second pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.50,
+ SamplingPointScale: 0.50
+ |
+
+
+
+
+
+### Main Menu
+
+
+ | no filter |
+ scalefx-like |
+
+
+ |
+ |
+
+
+ | no shader |
+
+ Single pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.50,
+ SamplingPointScale: 0.50
+ |
+
+
+ | xbrz-like |
+ two-pass |
+
+ |
+ |
+
+
+
+ Single pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.25,
+ SamplingPointScale: 1.00
+ |
+
+ First pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.25,
+ SamplingPointScale: 1.00
+ |
+
+ Second pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.50,
+ SamplingPointScale: 0.50
+ |
+
+
+
+
+### Gameplay
+
+
+ | no filter |
+ scalefx-like |
+
+
+ |
+ |
+
+
+ | no shader |
+
+ Single pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.50,
+ SamplingPointScale: 0.50
+ |
+
+
+ | xbrz-like |
+ two-pass |
+
+ |
+ |
+
+
+
+ Single pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.25,
+ SamplingPointScale: 1.00
+ |
+
+ First pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.25,
+ SamplingPointScale: 1.00
+ |
+
+ Second pass
+ Sharpness: -0.84,
+ StartSmoothingWeight: 1.00,
+ MinFilterWeight: 0.00,
+ MaxFilterWeight: 1.00,
+ Smoothing: 0.00,
+ ScalingFactor: 0.50,
+ SamplingPointScale: 0.50
+ |
+
+
\ No newline at end of file
diff --git a/img/gameplay_no_filer.png b/img/gameplay_no_filer.png
new file mode 100644
index 0000000..f8e9180
Binary files /dev/null and b/img/gameplay_no_filer.png differ
diff --git a/img/gameplay_scalefx.png b/img/gameplay_scalefx.png
new file mode 100644
index 0000000..e946cde
Binary files /dev/null and b/img/gameplay_scalefx.png differ
diff --git a/img/gameplay_two_pass.png b/img/gameplay_two_pass.png
new file mode 100644
index 0000000..91e810a
Binary files /dev/null and b/img/gameplay_two_pass.png differ
diff --git a/img/gameplay_xbrz.png b/img/gameplay_xbrz.png
new file mode 100644
index 0000000..d30849d
Binary files /dev/null and b/img/gameplay_xbrz.png differ
diff --git a/img/menu_no_filer.png b/img/menu_no_filer.png
new file mode 100644
index 0000000..c38faa6
Binary files /dev/null and b/img/menu_no_filer.png differ
diff --git a/img/menu_scalefx.png b/img/menu_scalefx.png
new file mode 100644
index 0000000..3556648
Binary files /dev/null and b/img/menu_scalefx.png differ
diff --git a/img/menu_two_pass.png b/img/menu_two_pass.png
new file mode 100644
index 0000000..da715e3
Binary files /dev/null and b/img/menu_two_pass.png differ
diff --git a/img/menu_xbrz.png b/img/menu_xbrz.png
new file mode 100644
index 0000000..3216b21
Binary files /dev/null and b/img/menu_xbrz.png differ
diff --git a/img/title_no_filer.png b/img/title_no_filer.png
new file mode 100644
index 0000000..355b6fe
Binary files /dev/null and b/img/title_no_filer.png differ
diff --git a/img/title_scalefx.png b/img/title_scalefx.png
new file mode 100644
index 0000000..e828554
Binary files /dev/null and b/img/title_scalefx.png differ
diff --git a/img/title_two_pass.png b/img/title_two_pass.png
new file mode 100644
index 0000000..98f32dd
Binary files /dev/null and b/img/title_two_pass.png differ
diff --git a/img/title_xbrz.png b/img/title_xbrz.png
new file mode 100644
index 0000000..b66795a
Binary files /dev/null and b/img/title_xbrz.png differ
diff --git a/shaders/obs-xbrz.effect b/shaders/obs-xbrz.effect
new file mode 100644
index 0000000..783ac4a
--- /dev/null
+++ b/shaders/obs-xbrz.effect
@@ -0,0 +1,116 @@
+uniform float4x4 ViewProj;
+uniform texture2d image;
+uniform float elapsed_time;
+uniform string notes = "Sharpness: -0.84, StartSmoothingWeight = 1, MinFilterWeight = 0, MaxFilterWeight = 1, Smoothing = 0, ScalingFactor = 0.25";
+uniform float Sharpness = -0.250; // use positive values to get blurry pixels, use negative values to get clean smooth results
+uniform float StartSmoothingWeight = 1.000; // start smoothing eight
+uniform float MaxFilterWeight = 0.750; // max filter weigth
+uniform float MinFilterWeight = 0.250; // min filter weigth
+uniform float Smoothing = 0.330; // effects smoothing
+uniform float ScalingFactor = 0.250; // donwsampling 4x in size
+uniform float SamplingPointScale1 = 0.5;
+
+sampler_state textureSampler {
+ Filter = Linear;
+ AddressU = Border;
+ AddressV = Border;
+ BorderColor = 00000000;
+};
+
+struct VertData {
+ float4 pos : POSITION;
+ float2 uv : TEXCOORD0;
+};
+
+VertData mainTransform(VertData v_in)
+{
+ VertData vert_out;
+ vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
+ vert_out.uv = v_in.uv * uv_scale + uv_offset;
+ return vert_out;
+}
+
+float4 mainImage(VertData v_in) : TARGET
+{
+ float2 uv = v_in.uv;
+
+ float4 color = image.Sample(textureSampler, v_in.uv );
+ float3 c = color.xyz;
+ float x = 0.5 * (1.0 / uv_size.x/ScalingFactor);
+ float y = 0.5 * (1.0 / uv_size.y/ScalingFactor);
+
+ const float3 dt = 1.0 * float3(1.0, 1.0, 1.0);
+
+ float2 dg1 = float2( x, y);
+ float2 dg2 = float2(x, -y);
+
+ float2 sd1 = dg1*SamplingPointScale1;
+ float2 sd2 = dg2*SamplingPointScale1;
+
+ float2 ddx = float2( x, 0.0);
+ float2 ddy = float2( 0.0, y);
+
+ float4 t1 = float4(uv-sd1,uv-ddy);
+ float4 t2 = float4(uv-sd2,uv+ddx);
+ float4 t3 = float4(uv+sd1,uv+ddy);
+ float4 t4 = float4(uv+sd2,uv-ddx);
+ float4 t5 = float4(uv-dg1,uv-dg2);
+ float4 t6 = float4(uv+dg1,uv+dg2);
+
+ float3 i1 = image.Sample(textureSampler, t1.xy).xyz;
+ float3 i2 = image.Sample(textureSampler, t2.xy).xyz;
+ float3 i3 = image.Sample(textureSampler, t3.xy).xyz;
+ float3 i4 = image.Sample(textureSampler, t4.xy).xyz;
+
+ float3 o1 = image.Sample(textureSampler, t5.xy).xyz;
+ float3 o3 = image.Sample(textureSampler, t6.xy).xyz;
+ float3 o2 = image.Sample(textureSampler, t5.zw).xyz;
+ float3 o4 = image.Sample(textureSampler, t6.zw).xyz;
+
+ float3 s1 = image.Sample(textureSampler, t1.zw).xyz;
+ float3 s2 = image.Sample(textureSampler, t2.zw).xyz;
+ float3 s3 = image.Sample(textureSampler, t3.zw).xyz;
+ float3 s4 = image.Sample(textureSampler, t4.zw).xyz;
+
+ float ko1 = dot(abs(o1-c),dt);
+ float ko2 = dot(abs(o2-c),dt);
+ float ko3 = dot(abs(o3-c),dt);
+ float ko4 = dot(abs(o4-c),dt);
+
+ float k1=min(dot(abs(i1-i3),dt),max(ko1,ko3));
+ float k2=min(dot(abs(i2-i4),dt),max(ko2,ko4));
+
+ float w1 = k2; if(ko3