Skip to content

Commit

Permalink
Update Twist Filterr
Browse files Browse the repository at this point in the history
  • Loading branch information
bbazukun123 committed Dec 30, 2023
1 parent aa0869e commit bc896d2
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 85 deletions.
11 changes: 0 additions & 11 deletions filters/adjustment/src/AdjustmentFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,6 @@ export class AdjustmentFilter extends Filter
alpha: 1,
};

/**
* @param {object|number} [options] - The optional parameters of the filter.
* @param {number} [options.gamma=1] - The amount of luminance
* @param {number} [options.saturation=1] - The amount of color saturation
* @param {number} [options.contrast=1] - The amount of contrast
* @param {number} [options.brightness=1] - The overall brightness
* @param {number} [options.red=1] - The multipled red channel
* @param {number} [options.green=1] - The multipled green channel
* @param {number} [options.blue=1] - The multipled blue channel
* @param {number} [options.alpha=1] - The overall alpha amount
*/
constructor(options?: AdjustmentFilterOptions)
{
options = { ...AdjustmentFilter.DEFAULT_OPTIONS, ...options };
Expand Down
126 changes: 77 additions & 49 deletions filters/twist/src/TwistFilter.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
import { vertex } from '@tools/fragments';
import { vertex, wgslVertex } from '@tools/fragments';
import fragment from './twist.frag';
import { Filter, GlProgram, Point } from 'pixi.js';
import source from './twist.wgsl';
import { Filter, GlProgram, GpuProgram, Point, UniformGroup } from 'pixi.js';

interface TwistFilterOptions
export interface TwistFilterOptions
{
radius: number;
angle: number;
padding: number;
offset: Point;
/**
* Padding for the filter area
* @default 20
*/
padding?: number;
/**
* The radius of the twist
* @default 200
*/
radius?: number;
/**
* The angle of the twist
* @default 4
*/
angle?: number;
/**
* The `x` and `y` offset coordinates to change the position of the center of the circle of effect.
* This should be a size 2 array or an object containing `x` and `y` values, you cannot change types
* once defined in the constructor
* @default { x: 0, y: 0}
*/
offset?: Point;
}

/**
Expand All @@ -21,72 +40,81 @@ interface TwistFilterOptions
*/
export class TwistFilter extends Filter
{
/** Default constructor options. */
public static readonly defaults: TwistFilterOptions = {
/** Default values for options. */
public static readonly DEFAULT_OPTIONS: TwistFilterOptions = {
padding: 20,
radius: 200,
angle: 4,
padding: 20,
offset: new Point(),
};

/**
* @param {object} [options] - Object object to use.
* @param {number} [options.radius=200] - The radius of the twist.
* @param {number} [options.angle=4] - The angle of the twist.
* @param {number} [options.padding=20] - Padding for filter area.
* @param {Point} [options.offset] - Center of twist, in local, pixel coordinates.
*/
constructor(options?: Partial<TwistFilterOptions>)
{
options = { ...TwistFilter.DEFAULT_OPTIONS, ...options };

const twistUniforms = new UniformGroup({
uTwist: {
value: [options.radius ?? 0, options.angle ?? 0],
type: 'vec2<f32>'
},
uOffset: {
value: [options.offset?.x ?? 0, options.offset?.y ?? 0],
type: 'vec2<f32>'
},
});

const gpuProgram = new GpuProgram({
vertex: {
source: wgslVertex,
entryPoint: 'mainVertex',
},
fragment: {
source,
entryPoint: 'mainFragment',
},
});

const glProgram = new GlProgram({
vertex,
fragment,
name: 'twist-filter',
});

super({
gpuProgram,
glProgram,
resources: {},
resources: {
twistUniforms
},
...options,
});

Object.assign(this, TwistFilter.defaults, options);
}

/**
* This point describes the the offset of the twist.
*
* @member {Point}
* The radius of the twist
* @default 200
*/
get radius(): number { return this.resources.twistUniforms.uniforms.uTwist[0]; }
set radius(value: number) { this.resources.twistUniforms.uniforms.uTwist[0] = value; }

/**
* The angle of the twist
* @default 4
*/
// get offset(): Point
// {
// return this.uniforms.offset;
// }
// set offset(value: Point)
// {
// this.uniforms.offset = value;
// }
get angle(): number { return this.resources.twistUniforms.uniforms.uTwist[1]; }
set angle(value: number) { this.resources.twistUniforms.uniforms.uTwist[1] = value; }

/**
* The radius of the twist.
* The `x` offset coordinate to change the position of the center of the circle of effect
* @default 0
*/
// get radius(): number
// {
// return this.uniforms.radius;
// }
// set radius(value: number)
// {
// this.uniforms.radius = value;
// }
get offsetX(): number { return this.resources.twistUniforms.uniforms.uOffset[0]; }
set offsetX(value: number) { this.resources.twistUniforms.uniforms.uOffset[0] = value; }

/**
* The angle of the twist.
* The `y` offset coordinate to change the position of the center of the circle of effect
* @default 0
*/
// get angle(): number
// {
// return this.uniforms.angle;
// }
// set angle(value: number)
// {
// this.uniforms.angle = value;
// }
get offsetY(): number { return this.resources.twistUniforms.uniforms.uOffset[1]; }
set offsetY(value: number) { this.resources.twistUniforms.uniforms.uOffset[1] = value; }
}
38 changes: 18 additions & 20 deletions filters/twist/src/twist.frag
Original file line number Diff line number Diff line change
@@ -1,56 +1,54 @@
varying vec2 vTextureCoord;
precision highp float;
in vec2 vTextureCoord;
out vec4 finalColor;

uniform sampler2D uSampler;
uniform float radius;
uniform float angle;
uniform vec2 offset;
uniform vec4 filterArea;
uniform vec2 uTwist;
uniform vec2 uOffset;
uniform vec4 uInputSize;

vec2 mapCoord( vec2 coord )
{
coord *= filterArea.xy;
coord += filterArea.zw;
coord *= uInputSize.xy;
coord += uInputSize.zw;

return coord;
}

vec2 unmapCoord( vec2 coord )
{
coord -= filterArea.zw;
coord /= filterArea.xy;
coord -= uInputSize.zw;
coord /= uInputSize.xy;

return coord;
}

vec2 twist(vec2 coord)
{
coord -= offset;
coord -= uOffset;

float dist = length(coord);
float uRadius = uTwist[0];
float uAngle = uTwist[1];

if (dist < radius)
if (dist < uRadius)
{
float ratioDist = (radius - dist) / radius;
float angleMod = ratioDist * ratioDist * angle;
float ratioDist = (uRadius - dist) / uRadius;
float angleMod = ratioDist * ratioDist * uAngle;
float s = sin(angleMod);
float c = cos(angleMod);
coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);
}

coord += offset;
coord += uOffset;

return coord;
}

void main(void)
{

vec2 coord = mapCoord(vTextureCoord);

coord = twist(coord);

coord = unmapCoord(coord);

gl_FragColor = texture2D(uSampler, coord );

finalColor = texture(uSampler, coord);
}
47 changes: 47 additions & 0 deletions filters/twist/src/twist.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
struct TwistUniforms {
uTwist:vec2<f32>,
uOffset:vec2<f32>,
};

@group(0) @binding(1) var uSampler: texture_2d<f32>;
@group(1) @binding(0) var<uniform> twistUniforms : TwistUniforms;

@fragment
fn mainFragment(
@location(0) uv: vec2<f32>,
@builtin(position) position: vec4<f32>
) -> @location(0) vec4<f32> {
return textureSample(uSampler, uSampler, unmapCoord(twist(mapCoord(uv))));
}

fn unmapCoord(coord: vec2<f32> ) -> vec2<f32>
{
var mappedCoord: vec2<f32> = coord;
mappedCoord -= gfu.outputFrame.xy;
mappedCoord /= gfu.inputSize.xy;
return mappedCoord;
}

fn twist(coord: vec2<f32>) -> vec2<f32>
{
var twistedCoord: vec2<f32> = coord;
let uRadius = twistUniforms.uTwist[0];
let uAngle = twistUniforms.uTwist[1];
let uOffset = twistUniforms.uOffset;

twistedCoord -= uOffset;

let dist = length(twistedCoord);

if (dist < uRadius)
{
let ratioDist: f32 = (uRadius - dist) / uRadius;
let angleMod: f32 = ratioDist * ratioDist * uAngle;
let s: f32 = sin(angleMod);
let c: f32 = cos(angleMod);
twistedCoord = vec2<f32>(twistedCoord.x * c - twistedCoord.y * s, twistedCoord.x * s + twistedCoord.y * c);
}

twistedCoord += uOffset;
return twistedCoord;
}
9 changes: 4 additions & 5 deletions tools/demo/src/filters/twist.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { Point } from 'pixi.js';

export default function ()
{
const app = this;

this.addFilter('TwistFilter', function (folder)
{
this.offset = new Point(app.initWidth / 2, app.initHeight / 2);
this.offsetX = app.initWidth / 2;
this.offsetY = app.initHeight / 2;
folder.add(this, 'angle', -10, 10);
folder.add(this, 'radius', 0, app.initWidth);
folder.add(this.offset, 'x', 0, app.initWidth);
folder.add(this.offset, 'y', 0, app.initHeight);
folder.add(this, 'offsetX', 0, app.initWidth);
folder.add(this, 'offsetY', 0, app.initHeight);
});
}
1 change: 1 addition & 0 deletions tools/demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const main = async () =>
filters.adjustment.call(app);
filters.bloom.call(app);
filters.grayscale.call(app);
filters.twist.call(app);
// filters.kawaseBlur.call(app);

// TODO: Re-enable this in place of the above once v8 conversion is complete
Expand Down

0 comments on commit bc896d2

Please sign in to comment.