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

[New] Add Two Filter , Which are Distorted Effect and Water Effect #131

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
49 changes: 35 additions & 14 deletions examples/Mac/FilterShowcase/FilterShowcase/FilterOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@ import GPUImage
import QuartzCore

let filterOperations: Array<FilterOperationInterface> = [

FilterOperation (
filter:{DistortedEffect()},
listName:"DistortedEffect",
titleName:"DistortedEffect",
sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:2.0, initialValue:1.0),
sliderUpdateCallback: {(filter, sliderValue) in
filter.time = sliderValue
},
filterOperationType:.singleInput
),

FilterOperation (
filter:{WaterEffect()},
listName:"WaterEffect",
titleName:"WaterEffect",
sliderConfiguration:.enabled(minimumValue:0.1, maximumValue:0.3, initialValue:1.0),
sliderUpdateCallback: {(filter, sliderValue) in
filter.time = sliderValue
},
filterOperationType:.singleInput
),

FilterOperation (
filter:{SaturationAdjustment()},
listName:"Saturation",
Expand Down Expand Up @@ -1165,20 +1188,18 @@ let filterOperations: Array<FilterOperationInterface> = [
filterOperationType:.blend
),

FilterOperation(
filter:{GammaAdjustment()},
listName:"Solid color",
titleName:"Solid color",
sliderConfiguration:.disabled,
sliderUpdateCallback: nil,
filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in
let solidColorGenerator = SolidColorGenerator(size:Size(width: 400, height: 400))
solidColorGenerator --> outputView
solidColorGenerator.renderColor(Color.red)
// solidColorGenerator --> (filter as! GammaAdjustment) --> outputView
return nil
})
),


// FilterOperation(
//
// filterOperationType:.singleInput
// filter:{waterEffect()},
// listName:"Water Effect",
// titleName:"Water Effect",
// sliderConfiguration:.enabled(minimumValue: 0, maximumValue: 1, initialValue: 0),
// sliderUpdateCallback: nil,
// filterOperationType:.singleInput
// ),

// TODO: Poisson blend
]
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
TargetAttributes = {
BC0037B6195CA11B00B9D651 = {
CreatedOnToolsVersion = 6.0;
DevelopmentTeam = J2U2U9GBML;
DevelopmentTeam = 92L57X7YGH;
LastSwiftMigration = 0940;
ProvisioningStyle = Automatic;
};
Expand All @@ -204,6 +204,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
Expand Down Expand Up @@ -413,7 +414,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = J2U2U9GBML;
DEVELOPMENT_TEAM = 92L57X7YGH;
INFOPLIST_FILE = FilterShowcaseSwift/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.redqueencoder.FilterShowcase;
Expand All @@ -431,7 +432,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = J2U2U9GBML;
DEVELOPMENT_TEAM = 92L57X7YGH;
INFOPLIST_FILE = FilterShowcaseSwift/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.redqueencoder.FilterShowcase;
Expand Down
24 changes: 24 additions & 0 deletions framework/GPUImage.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,14 @@
BCFCD46720FCE91200560BC9 /* DissolveBlend.metal in Sources */ = {isa = PBXBuildFile; fileRef = BCFCD46620FCE91200560BC9 /* DissolveBlend.metal */; };
BCFCD46820FCE91200560BC9 /* DissolveBlend.metal in Sources */ = {isa = PBXBuildFile; fileRef = BCFCD46620FCE91200560BC9 /* DissolveBlend.metal */; };
BCFCD46920FCE91800560BC9 /* DissolveBlend.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCFCD46420FCE83500560BC9 /* DissolveBlend.swift */; };
E01E90112A15E17C00FE7578 /* WaterEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = E01E90102A15E17C00FE7578 /* WaterEffect.swift */; };
E01E90122A15E17C00FE7578 /* WaterEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = E01E90102A15E17C00FE7578 /* WaterEffect.swift */; };
E01E90172A15E1AA00FE7578 /* WaterEffect.metal in Sources */ = {isa = PBXBuildFile; fileRef = E01E90162A15E1AA00FE7578 /* WaterEffect.metal */; };
E01E90182A15E1AA00FE7578 /* WaterEffect.metal in Sources */ = {isa = PBXBuildFile; fileRef = E01E90162A15E1AA00FE7578 /* WaterEffect.metal */; };
E01E901A2A15FB6B00FE7578 /* DistortedEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = E01E90192A15FB6B00FE7578 /* DistortedEffect.swift */; };
E01E901B2A15FB6B00FE7578 /* DistortedEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = E01E90192A15FB6B00FE7578 /* DistortedEffect.swift */; };
E01E90202A15FBA700FE7578 /* DistortedEffect.metal in Sources */ = {isa = PBXBuildFile; fileRef = E01E901F2A15FBA700FE7578 /* DistortedEffect.metal */; };
E01E90212A15FBA700FE7578 /* DistortedEffect.metal in Sources */ = {isa = PBXBuildFile; fileRef = E01E901F2A15FBA700FE7578 /* DistortedEffect.metal */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -619,6 +627,10 @@
BCE0BE9D20D6E3C80006E120 /* ImageOrientation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageOrientation.swift; path = Source/ImageOrientation.swift; sourceTree = "<group>"; };
BCFCD46420FCE83500560BC9 /* DissolveBlend.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DissolveBlend.swift; path = Source/Operations/DissolveBlend.swift; sourceTree = "<group>"; };
BCFCD46620FCE91200560BC9 /* DissolveBlend.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; name = DissolveBlend.metal; path = Source/Operations/DissolveBlend.metal; sourceTree = "<group>"; };
E01E90102A15E17C00FE7578 /* WaterEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WaterEffect.swift; path = Source/Operations/WaterEffect.swift; sourceTree = "<group>"; };
E01E90162A15E1AA00FE7578 /* WaterEffect.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; name = WaterEffect.metal; path = Source/Operations/WaterEffect.metal; sourceTree = "<group>"; };
E01E90192A15FB6B00FE7578 /* DistortedEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DistortedEffect.swift; path = Source/Operations/DistortedEffect.swift; sourceTree = "<group>"; };
E01E901F2A15FBA700FE7578 /* DistortedEffect.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; name = DistortedEffect.metal; path = Source/Operations/DistortedEffect.metal; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -642,6 +654,10 @@
4C280F6E21342447001A985C /* Effects */ = {
isa = PBXGroup;
children = (
E01E90192A15FB6B00FE7578 /* DistortedEffect.swift */,
E01E901F2A15FBA700FE7578 /* DistortedEffect.metal */,
E01E90102A15E17C00FE7578 /* WaterEffect.swift */,
E01E90162A15E1AA00FE7578 /* WaterEffect.metal */,
79DD50BD21344C28004EF308 /* BulgeDistortion.swift */,
79DD50C021344C38004EF308 /* BulgeDistortion.metal */,
795ECA8521E91B38000EF927 /* CGAColorspace.swift */,
Expand Down Expand Up @@ -1120,7 +1136,9 @@
BC101ECB22458B7B0020D74D /* MovieInput.swift in Sources */,
79CB6DED210926300042F87B /* ExclusionBlend.metal in Sources */,
7999997D2226EC05007404F2 /* KuwaharaFilter.swift in Sources */,
E01E90172A15E1AA00FE7578 /* WaterEffect.metal in Sources */,
795ECA7721E903F1000EF927 /* ToonFilter.metal in Sources */,
E01E90112A15E17C00FE7578 /* WaterEffect.swift in Sources */,
7957437520FBF453001EAE0A /* Haze.swift in Sources */,
BC25F89E22C15D3A00CBBD15 /* SmoothToonFilter.swift in Sources */,
79CB6E0B21092E3E0042F87B /* LuminosityBlend.metal in Sources */,
Expand Down Expand Up @@ -1152,6 +1170,7 @@
BC7FC40C212B2B3800B37FB6 /* OperationGroup.swift in Sources */,
79DD50CA21345492004EF308 /* Vignette.swift in Sources */,
793D933520F68C1B008A7A6E /* ContrastAdjustment.swift in Sources */,
E01E90202A15FBA700FE7578 /* DistortedEffect.metal in Sources */,
79A81CA321010A2E00A3B43A /* Vibrance.metal in Sources */,
79CB6DF3210927180042F87B /* HardLightBlend.metal in Sources */,
4CC48BEE213433CB00817C34 /* StretchDistortion.metal in Sources */,
Expand Down Expand Up @@ -1241,6 +1260,7 @@
BC25F8AF22C2B3F700CBBD15 /* HighPassFilter.swift in Sources */,
795ECAC021EF95EB000EF927 /* LocalBinaryPattern.swift in Sources */,
799999832226FE8F007404F2 /* KuwaharaRadius3Filter.swift in Sources */,
E01E901A2A15FB6B00FE7578 /* DistortedEffect.swift in Sources */,
79CB6DE42108CC460042F87B /* DivideBlend.swift in Sources */,
BCE0BEA420D6E3C80006E120 /* Pipeline.swift in Sources */,
);
Expand Down Expand Up @@ -1325,7 +1345,9 @@
BC101ECC22458B7C0020D74D /* MovieInput.swift in Sources */,
79CB6DEE210926300042F87B /* ExclusionBlend.metal in Sources */,
7999997E2226EC05007404F2 /* KuwaharaFilter.swift in Sources */,
E01E90182A15E1AA00FE7578 /* WaterEffect.metal in Sources */,
795ECA7821E903F1000EF927 /* ToonFilter.metal in Sources */,
E01E90122A15E17C00FE7578 /* WaterEffect.swift in Sources */,
BCFCD46820FCE91200560BC9 /* DissolveBlend.metal in Sources */,
BC25F89F22C15D3A00CBBD15 /* SmoothToonFilter.swift in Sources */,
79CB6E0C21092E3E0042F87B /* LuminosityBlend.metal in Sources */,
Expand Down Expand Up @@ -1357,6 +1379,7 @@
BC7FC40D212B2B3800B37FB6 /* OperationGroup.swift in Sources */,
79DD50CB21345492004EF308 /* Vignette.swift in Sources */,
793D933320F68A32008A7A6E /* ExposureAdjustment.metal in Sources */,
E01E90212A15FBA700FE7578 /* DistortedEffect.metal in Sources */,
79A81CA421010A2E00A3B43A /* Vibrance.metal in Sources */,
79CB6DF4210927180042F87B /* HardLightBlend.metal in Sources */,
4CC48BEF213433CB00817C34 /* StretchDistortion.metal in Sources */,
Expand Down Expand Up @@ -1446,6 +1469,7 @@
BC25F8B022C2B3F700CBBD15 /* HighPassFilter.swift in Sources */,
795ECAC121EF95EB000EF927 /* LocalBinaryPattern.swift in Sources */,
799999842226FE8F007404F2 /* KuwaharaRadius3Filter.swift in Sources */,
E01E901B2A15FB6B00FE7578 /* DistortedEffect.swift in Sources */,
79CB6DE52108CC460042F87B /* DivideBlend.swift in Sources */,
BCE0BEA520D6E3C80006E120 /* Pipeline.swift in Sources */,
);
Expand Down
1 change: 1 addition & 0 deletions framework/Source/Operations/BulgeDistortion.metal
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ fragment half4 bulgeDistortionFragment(SingleInputVertexIO fragmentInput [[stage
constant BulgeDistortionUniform& uniform [[buffer(1)]])
{
float2 textureCoordinateToUse = float2(fragmentInput.textureCoordinate.x, ((fragmentInput.textureCoordinate.y - uniform.center.y) * uniform.aspectRatio) + uniform.center.y);

float dist = distance(uniform.center, textureCoordinateToUse);
textureCoordinateToUse = fragmentInput.textureCoordinate;

Expand Down
140 changes: 140 additions & 0 deletions framework/Source/Operations/DistortedEffect.metal
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//
// distortedEffect.metal
// GPUImage
//
// Created by Mehedi Hasan on 18/5/23.
// Copyright © 2023 Red Queen Coder, LLC. All rights reserved.
//

#include <metal_stdlib>
#include "OperationShaderTypes.h"
#include "BlendShaderTypes.h"
using namespace metal;


float3 mod289(float3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}

float2 mod289(float2 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}

float3 permute(float3 x) {
return mod289(((x*34.0)+1.0)*x);
}

float snoise(float2 v)
{
const float4 C = float4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
-0.577350269189626, // -1.0 + 2.0 * C.x
0.024390243902439); // 1.0 / 41.0
// First corner
float2 i = floor(v + dot(v, C.yy) );
float2 x0 = v - i + dot(i, C.xx);

// Other corners
float2 i1;
//i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
//i1.y = 1.0 - i1.x;
i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
// x0 = x0 - 0.0 + 0.0 * C.xx ;
// x1 = x0 - i1 + 1.0 * C.xx ;
// x2 = x0 - 1.0 + 2.0 * C.xx ;
float4 x12 = x0.xyxy + C.xxzz;
x12.xy -= i1;

// Permutations
i = mod289(i); // Avoid truncation effects in permutation
float3 p = permute( permute( i.y + float3(0.0, i1.y, 1.0 ))
+ i.x + float3(0.0, i1.x, 1.0 ));

float3 m = max(0.5 - float3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
m = m*m ;
m = m*m ;

// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)

float3 x = 2.0 * fract(p * C.www) - 1.0;
float3 h = abs(x) - 0.5;
float3 ox = floor(x + 0.5);
float3 a0 = x - ox;

// Normalise gradients implicitly by scaling m
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );

// Compute final noise value at P
float3 g;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * x12.xz + h.yz * x12.yw;

return 130.0 * dot(m, g);
}

float rand(float2 co) {
return fract(sin(dot(co.xy,float2(12.9898,78.233))) * 43758.5453);
}




typedef struct {
float time;
} TimeUniform;


fragment half4 distortedEffectFragment(SingleInputVertexIO fragmentInput [[stage_in]],
texture2d<half> inputTexture [[texture(0)]],
constant TimeUniform& uniform [[buffer(1)]])
{

// constexpr sampler quadSampler(mag_filter::linear, min_filter::linear);

// constexpr sampler quadSampler(coord::normalized,
// address::repeat,
// min_filter::linear,
// mag_filter::linear,
// mip_filter::linear );
//
constexpr sampler quadSampler(mag_filter::linear, min_filter::linear);

float2 pos = fragmentInput.textureCoordinate.xy;// / float2(inputTexture.get_width(), inputTexture.get_height());

float time = uniform.time * 20.0;

float2 uv = pos;

// Create large, incidental noise waves
float noise = max(0.0, snoise(float2(time, uv.y * 0.3)) - 0.3) * (1.0 / 0.7);

// Offset by smaller, constant noise waves
noise = noise + (snoise(float2(time*10.0, uv.y * 2.4)) - 0.5) * 0.15;

// Apply the noise as x displacement for every line
float xpos = uv.x - noise * noise * 0.25;

half4 fragColor = inputTexture.sample(quadSampler, float2(xpos, pos.y));
//texture(iChannel0, float2(xpos, uv.y));

// Mix in some random interference for lines
fragColor.rgb = mix(fragColor.rgb, half3(rand(float2(uv.y * time))), noise * 0.3).rgb;

// Apply a line pattern every 4 pixels
if (floor(mod(pos.y * 0.25, 2.0)) == 0.0) {
fragColor.rgb *= 1.0 - (0.15 * noise);
}

// Shift green/blue channels (using the red channel)

float c1 = float(inputTexture.sample( quadSampler, float2(float(xpos + noise * 0.05), uv.y) ).g);

float c2 = float(inputTexture.sample( quadSampler, float2(float(xpos - noise * 0.05), uv.y) ).b);

fragColor.g = mix(float(fragColor.r), c1, 0.25);
fragColor.b = mix(float(fragColor.r), c2, 0.25);

return fragColor;
}
19 changes: 19 additions & 0 deletions framework/Source/Operations/DistortedEffect.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// DistortedEffect.swift
// GPUImage
//
// Created by Mehedi Hasan on 18/5/23.
// Copyright © 2023 Red Queen Coder, LLC. All rights reserved.
//

import Foundation

public class DistortedEffect: BasicOperation {
public var time: Float = 0 { didSet { uniformSettings["time"] = time } }

public init() {
super.init(fragmentFunctionName:"distortedEffectFragment", numberOfInputs: 1)
({time = 1})()
}
}

Loading