Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/effect masking #18

Merged
merged 15 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ else()
cmake_minimum_required(VERSION 3.18)
endif()

project(obs-composite-blur VERSION 0.0.3)
project(obs-composite-blur VERSION 0.0.7)
set(PROJECT_FULL_NAME "OBS Composite Blur")

# Set new UUIDs when you start to create a new plugin.
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,21 @@ Zoom blur is applied away from a center zoom point, and increases the further fr

### Tilt-Shift
Tilt-Shift blur defines an in-focus plane, specified by a location in the frame, and a thickness. All pixels outside of the in-focus plane have their blur value increased the further away from the plane they are. The resulting image gives a distorted sense of scale, making large objects look like mineature models. When applied to video scenes like a city street, the effect can be significant. Inputs are blur radius, focus plane angle, focus plane location, and focus plane thickness.

## Effect Masking
OBS Composite Blur offers a variety of ways to mask where and how blur is applied to your source. For all mask options, the mask can also be inverted by checking the "Invert Mask" box. The following options are available.

### Crop
Specify the percentage distance in from the top, bottom, left, and right edges of your source that you want masked. Additionally, the crop mask allows you to specify a corner radius for nice, smooth rounded corners.

### Source
Use another OBS source or scene as a mask for your blur. Simply select the source or scene you want to use, and then specify if you want to use the source's alpha channel, grayscale value, luminosity, or a custom combination of the red, green, blue, and alpha channels to mask the blur effect. You can also multiply the resulting mask by a value. The multiply value comes in handy if you have a translucent source, but want everything behind the translucent source to be fully blurred.

### Image
All of the same options as [Source](#source), but allows you to select an image file rather than a source.

### Rectangle
Is the same as the [Crop](#crop) option, but instead of specifying the edges, you specify the center of the rectangle, the rectangle width, and rectangle height. This is easier to use with plugins like Move Transition if you want to animate the movement or size of the rectangular masked blur.

### Circle
Similar to the [Rectangle](#rectangle) option, but lets you specify the center of a circle and its radius. Some nice sweep effects can be made by using a very large circle, and moving it from off the source (less than 0 or greater than 100 for the center coordinates) over the source.
160 changes: 80 additions & 80 deletions buildspec.json
Original file line number Diff line number Diff line change
@@ -1,83 +1,83 @@
{
"dependencies": {
"obs-studio": {
"version": "28.0.0-beta1",
"repository": "https://github.com/obsproject/obs-studio.git",
"branch": "master",
"hash": "43a49dca47344a5170159ef99b86b97f90d4e4ad"
},
"prebuilt": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built obs-deps",
"hashes": {
"macos-x86_64": "7637e52305e6fc53014b5aabd583f1a4490b1d97450420e977cae9a336a29525",
"macos-arm64": "755e0fa69b17a3ae444e1befa9d91d77e3cafe628fbd1c6333686091826595cd",
"macos-universal": "de057e73e6fe0825664c258ca2dd6798c41ae580bf4d896e1647676a4941934a",
"windows-x64": "2192d8ce780c4281b807cd457994963669e5202659ecd92f19b54c3e7d0c1915",
"windows-x86": "9f8582ab5891b000869d6484ea591add9fbac9f1c91b56c7b85fdfd56a261c1b"
}
},
"qt5": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built Qt5",
"hashes": {
"macos-x86_64": "3d0381a52b0e4d49967936c4357f79ac711f43564329304a6db5c90edadd2697",
"macos-arm64": "f4b32548c0530f121956bf0a9a70c36ecbbfca81073d39c396a1759baf2a05c3",
"macos-universal": "9a6cf3b9a6c9efee6ba10df649202e8075e99f3c54ae88dc9a36dbc9d7471c1e",
"windows-x64": "6488a33a474f750d5a4a268a5e20c78bb40799d99136a1b7ce3365a843cb2fd7",
"windows-x86": "a916e09b0a874036801deab2c8a7ec14fdf5d268aa5511eac5bf40727e0c4e33"
},
"pdb-hashes": {
"windows-x64": "e0e5070143fcad9311a68ce5685d8ba8f34f581ed6942b7a92d360f94ca1ba11",
"windows-x86": "36642d1052aa461964f46c17610477b0d9b9defbe2d745ccaacb85f805c1bec2"
}
},
"qt6": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built Qt6",
"hashes": {
"macos-x86_64": "a83f72a11023b03b6cb2dc365f0a66ad9df31163bbb4fe2df32d601856a9fad3",
"macos-arm64": "2f30af90c049670a5660656adbb440668aa1b0567f75a5f29e1def9108928403",
"macos-universal": "252e6684f43ab9c6f262c73af739e2296ce391b998da2c4ee04c254aaa07db18",
"windows-x64": "e5509b54196a3f935250cc4b9c54160c8e588fd0f92bc078a2a64f9d9e2e4e93",
"windows-x86": "24fc03bef153a0e027c1479e42eb08097a4ea1d70a4710825be0783d0626cb0d"
},
"pdb-hashes": {
"windows-x64": "60e5b1d2bc4d7c431bc05f14e3b1e85e088788c372fa85f58717cd6c49555a46",
"windows-x86": "f34d1a89fc85d92913bd6c7f75ec5c28471d74db708c98161100bc8b75f8fc63"
}
}
"dependencies": {
"obs-studio": {
"version": "28.0.0-beta1",
"repository": "https://github.com/obsproject/obs-studio.git",
"branch": "master",
"hash": "43a49dca47344a5170159ef99b86b97f90d4e4ad"
},
"platformConfig": {
"macos-x86_64": {
"qtVersion": 6,
"deploymentTarget": "10.15"
},
"macos-arm64": {
"qtVersion": 6,
"deploymentTarget": "11.0"
},
"macos-universal": {
"qtVersion": 6,
"deploymentTarget": "10.15"
},
"windows-x64": {
"qtVersion": 6,
"visualStudio": "Visual Studio 17 2022",
"platformSDK": "10.0.20348.0"
},
"windows-x86": {
"qtVersion": 6,
"visualStudio": "Visual Studio 17 2022",
"platformSDK": "10.0.20348.0"
},
"linux-x86_64": {
"qtVersion": 6
}
"prebuilt": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built obs-deps",
"hashes": {
"macos-x86_64": "7637e52305e6fc53014b5aabd583f1a4490b1d97450420e977cae9a336a29525",
"macos-arm64": "755e0fa69b17a3ae444e1befa9d91d77e3cafe628fbd1c6333686091826595cd",
"macos-universal": "de057e73e6fe0825664c258ca2dd6798c41ae580bf4d896e1647676a4941934a",
"windows-x64": "2192d8ce780c4281b807cd457994963669e5202659ecd92f19b54c3e7d0c1915",
"windows-x86": "9f8582ab5891b000869d6484ea591add9fbac9f1c91b56c7b85fdfd56a261c1b"
}
},
"name": "obs-composite-blur",
"version": "0.0.3"
}
"qt5": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built Qt5",
"hashes": {
"macos-x86_64": "3d0381a52b0e4d49967936c4357f79ac711f43564329304a6db5c90edadd2697",
"macos-arm64": "f4b32548c0530f121956bf0a9a70c36ecbbfca81073d39c396a1759baf2a05c3",
"macos-universal": "9a6cf3b9a6c9efee6ba10df649202e8075e99f3c54ae88dc9a36dbc9d7471c1e",
"windows-x64": "6488a33a474f750d5a4a268a5e20c78bb40799d99136a1b7ce3365a843cb2fd7",
"windows-x86": "a916e09b0a874036801deab2c8a7ec14fdf5d268aa5511eac5bf40727e0c4e33"
},
"pdb-hashes": {
"windows-x64": "e0e5070143fcad9311a68ce5685d8ba8f34f581ed6942b7a92d360f94ca1ba11",
"windows-x86": "36642d1052aa461964f46c17610477b0d9b9defbe2d745ccaacb85f805c1bec2"
}
},
"qt6": {
"version": "2022-08-02",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-built Qt6",
"hashes": {
"macos-x86_64": "a83f72a11023b03b6cb2dc365f0a66ad9df31163bbb4fe2df32d601856a9fad3",
"macos-arm64": "2f30af90c049670a5660656adbb440668aa1b0567f75a5f29e1def9108928403",
"macos-universal": "252e6684f43ab9c6f262c73af739e2296ce391b998da2c4ee04c254aaa07db18",
"windows-x64": "e5509b54196a3f935250cc4b9c54160c8e588fd0f92bc078a2a64f9d9e2e4e93",
"windows-x86": "24fc03bef153a0e027c1479e42eb08097a4ea1d70a4710825be0783d0626cb0d"
},
"pdb-hashes": {
"windows-x64": "60e5b1d2bc4d7c431bc05f14e3b1e85e088788c372fa85f58717cd6c49555a46",
"windows-x86": "f34d1a89fc85d92913bd6c7f75ec5c28471d74db708c98161100bc8b75f8fc63"
}
}
},
"platformConfig": {
"macos-x86_64": {
"qtVersion": 6,
"deploymentTarget": "10.15"
},
"macos-arm64": {
"qtVersion": 6,
"deploymentTarget": "11.0"
},
"macos-universal": {
"qtVersion": 6,
"deploymentTarget": "10.15"
},
"windows-x64": {
"qtVersion": 6,
"visualStudio": "Visual Studio 17 2022",
"platformSDK": "10.0.20348.0"
},
"windows-x86": {
"qtVersion": 6,
"visualStudio": "Visual Studio 17 2022",
"platformSDK": "10.0.20348.0"
},
"linux-x86_64": {
"qtVersion": 6
}
},
"name": "obs-composite-blur",
"version": "0.0.7"
}
40 changes: 39 additions & 1 deletion data/locale/en-US.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
CompositeBlurFilter="Composite Blur"
CompositeBlurFilter.Channel.Alpha="Alpha"
CompositeBlurFilter.Channel.Red="Red"
CompositeBlurFilter.Channel.Green="Green"
CompositeBlurFilter.Channel.Blue="Blue"
CompositeBlurFilter.BlurAlgorithm="Blur Algorithm"
CompositeBlurFilter.BlurType="Blur Type"
CompositeBlurFilter.Radius="Blur radius"
Expand Down Expand Up @@ -28,4 +32,38 @@ CompositeBlurFilter.Pixelate.Hexagonal="Hexagonal"
CompositeBlurFilter.Pixelate.Triakis="Triakis"
CompositeBlurFilter.Pixelate.Circle="Circle"
CompositeBlurFilter.Pixelate.Triangle="Triangle"
CompositeBlurFilter.DualKawase.Passes="Blur Radius"
CompositeBlurFilter.DualKawase.Passes="Blur Radius"
CompositeBlurFilter.EffectMask="Effect Mask"
CompositeBlurFilter.EffectMask.CropParameters="Crop Mask Parameters"
CompositeBlurFilter.EffectMask.None="None"
CompositeBlurFilter.EffectMask.Crop="Crop"
CompositeBlurFilter.EffectMask.Rectangle="Rectangle"
CompositeBlurFilter.EffectMask.Circle="Circle"
CompositeBlurFilter.EffectMask.Source="Source"
CompositeBlurFilter.EffectMask.Image="Image"
CompositeBlurFilter.EffectMask.Crop.Top="Top (%)"
CompositeBlurFilter.EffectMask.Crop.Bottom="Bottom (%)"
CompositeBlurFilter.EffectMask.Crop.Left="Left (%)"
CompositeBlurFilter.EffectMask.Crop.Right="Right (%)"
CompositeBlurFilter.EffectMask.CornerRadius="Corner Radius (%)"
CompositeBlurFilter.EffectMask.Invert="Invert Mask?"
CompositeBlurFilter.EffectMask.SourceParameters="Source Mask Parameters"
CompositeBlurFilter.EffectMask.ImageParameters="Image Mask Parameters"
CompositeBlurFilter.EffectMask.Source.Source="Source"
CompositeBlurFilter.EffectMask.Source.File="Image File"
CompositeBlurFilter.EffectMask.Source.Filter="Mask Using"
CompositeBlurFilter.EffectMask.Source.Alpha="Alpha Channel"
CompositeBlurFilter.EffectMask.Source.Grayscale="Grayscale Value"
CompositeBlurFilter.EffectMask.Source.Luminosity="Luminosity"
CompositeBlurFilter.EffectMask.Source.Sliders="Manual RGBA Sliders"
CompositeBlurFilter.EffectMask.Source.Multiplier="Multiplier"
CompositeBlurFilter.EffectMask.Circle.CenterX="Center X (%)"
CompositeBlurFilter.EffectMask.Circle.CenterY="Center Y (%)"
CompositeBlurFilter.EffectMask.Circle.Radius="Radius (%)"
CompositeBlurFilter.EffectMask.CircleParameters="Circle Mask Parameters"
CompositeBlurFilter.EffectMask.Rect.CenterX="Center X (%)"
CompositeBlurFilter.EffectMask.Rect.CenterY="Center Y (%)"
CompositeBlurFilter.EffectMask.Rect.Width="Width (%)"
CompositeBlurFilter.EffectMask.Rect.Height="Height (%)"
CompositeBlurFilter.EffectMask.Rect.CornerRadius="Corner Radius (%)"
CompositeBlurFilter.EffectMask.RectParameters="Rectangle Mask Parameters"
47 changes: 47 additions & 0 deletions data/shaders/effect_mask_circle.effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
uniform float4x4 ViewProj;
uniform texture2d image;
uniform texture2d filtered_image;

uniform float circle_radius;
uniform float2 center;
uniform float2 uv_scale;
uniform bool inv = false;

sampler_state textureSampler{
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
MinLOD = 0;
MaxLOD = 0;
};

struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};

VertData mainTransform(VertData v_in)
{
v_in.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
return v_in;
}

float4 mainImage(VertData v_in) : TARGET
{
float2 uv_prime = v_in.uv * uv_scale;
float2 center_prime = center * uv_scale;
float dist = distance(uv_prime, center_prime);
if (dist > circle_radius) {
return !inv ? image.Sample(textureSampler, v_in.uv) : filtered_image.Sample(textureSampler, v_in.uv);
}
return inv ? image.Sample(textureSampler, v_in.uv) : filtered_image.Sample(textureSampler, v_in.uv);
}

technique Draw
{
pass
{
vertex_shader = mainTransform(v_in);
pixel_shader = mainImage(v_in);
}
}
87 changes: 87 additions & 0 deletions data/shaders/effect_mask_crop.effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
uniform float4x4 ViewProj;
uniform texture2d image;
uniform texture2d filtered_image;

uniform float2 scale;
uniform float2 offset;
uniform float2 box_aspect_ratio;
uniform float corner_radius;
uniform bool inv = false;

sampler_state textureSampler{
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
MinLOD = 0;
MaxLOD = 0;
};

struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};

VertData mainTransform(VertData v_in)
{
v_in.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
return v_in;
}

float4 mainImage(VertData v_in) : TARGET
{
float2 transform_coord = (v_in.uv - offset) * scale;
if(transform_coord.x < 0.0f || transform_coord.y < 0.0f || transform_coord.x > 1.0f || transform_coord.y > 1.0f) {
// Outside
return inv ? filtered_image.Sample(textureSampler, v_in.uv) : image.Sample(textureSampler, v_in.uv);
}
// Inside
// 1. Scale to 1:1 ratio, shorten long side
float2 inner_coord = transform_coord * box_aspect_ratio;
if(
inner_coord.x > corner_radius && inner_coord.y > corner_radius &&
inner_coord.x < (box_aspect_ratio.x - corner_radius) && inner_coord.y < (box_aspect_ratio.y - corner_radius)
) {
return inv ? image.Sample(textureSampler, v_in.uv) : filtered_image.Sample(textureSampler, v_in.uv);
}
if(inner_coord.x < corner_radius && inner_coord.y < corner_radius) {
// top left
if (distance(inner_coord, float2(corner_radius, corner_radius)) > corner_radius) {
return inv ? filtered_image.Sample(textureSampler, v_in.uv) : image.Sample(textureSampler, v_in.uv);
}
} else if(inner_coord.x < corner_radius && inner_coord.y > (box_aspect_ratio.y - corner_radius)) {
// bot left
if (distance(inner_coord, float2(corner_radius, box_aspect_ratio.y - corner_radius)) > corner_radius) {
return inv ? filtered_image.Sample(textureSampler, v_in.uv) : image.Sample(textureSampler, v_in.uv);
}
} else if(inner_coord.x > (box_aspect_ratio.x - corner_radius) && inner_coord.y < corner_radius) {
// top right
if (distance(inner_coord, float2(box_aspect_ratio.x - corner_radius, corner_radius)) > corner_radius) {
return inv ? filtered_image.Sample(textureSampler, v_in.uv) : image.Sample(textureSampler, v_in.uv);
}
} else if(inner_coord.x > (box_aspect_ratio.x - corner_radius) && inner_coord.y > (box_aspect_ratio.y - corner_radius)) {
// bot right
if (distance(inner_coord, float2(box_aspect_ratio.x - corner_radius, box_aspect_ratio.y - corner_radius)) > corner_radius) {
return inv ? filtered_image.Sample(textureSampler, v_in.uv) : image.Sample(textureSampler, v_in.uv);
}
}

return inv ? image.Sample(textureSampler, v_in.uv) : filtered_image.Sample(textureSampler, v_in.uv);

// else if(
// transform_coord.x > corner_radius && transform_coord.x < 1.0f-corner_radius &&
// transform_coord.y > corner_radius && transform_coord.y < 1.0f-corner_radius
// ) {
// return inv ? image.Sample(textureSampler, v_in.uv) : filtered_image.Sample(textureSampler, v_in.uv);
// }
// return float4(1.0, 0.0, 1.0, 1.0);

}

technique Draw
{
pass
{
vertex_shader = mainTransform(v_in);
pixel_shader = mainImage(v_in);
}
}
Loading
Loading