Skip to content

Commit

Permalink
Update RGB Split Filterr
Browse files Browse the repository at this point in the history
  • Loading branch information
bbazukun123 committed Jan 1, 2024
1 parent bc22ce1 commit 2374fe9
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 50 deletions.
181 changes: 142 additions & 39 deletions filters/rgb-split/src/RGBSplitFilter.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
import { vertex } from '@tools/fragments';
import { vertex, wgslVertex } from '@tools/fragments';
import fragment from './rgb-split.frag';
import { Filter, GlProgram } from 'pixi.js';
import type { Point } from 'pixi.js';
import source from './rgb-split.wgsl';
import { Filter, GlProgram, GpuProgram, UniformGroup, Point } from 'pixi.js';

type Offset = [number, number] | Point;

export interface RGBSplitFilterOptions
{
/**
* The amount of offset for the red channel.
* @default [-10,0]
*/
red: Offset;
/**
* The amount of offset for the green channel.
* @default [0,10]
*/
green: Offset;
/**
* The amount of offset for the blue channel.
* @default [0,0]
*/
blue: Offset;
}

/**
* An RGB Split Filter.<br>
* ![original](../tools/screenshots/dist/original.png)![filter](../tools/screenshots/dist/rgb.png)
Expand All @@ -16,67 +35,151 @@ type Offset = [number, number] | Point;
*/
export class RGBSplitFilter extends Filter
{
/** Default values for options. */
public static readonly DEFAULT_OPTIONS: RGBSplitFilterOptions = {
red: [-10, 0],
green: [0, 10],
blue: [0, 0],
};

/**
* @param {Point | number[]} [red=[-10,0]] - Red channel offset
* @param {Point | number[]} [green=[0, 10]] - Green channel offset
* @param {Point | number[]} [blue=[0, 0]] - Blue channel offset
*/
constructor(red: Offset = [-10, 0], green: Offset = [0, 10], blue: Offset = [0, 0])
constructor(options?: RGBSplitFilterOptions)
{
options = { ...RGBSplitFilter.DEFAULT_OPTIONS, ...options };

const rgbSplitUniforms = new UniformGroup({
uRed: { value: new Float32Array(2), type: 'vec2<f32>' },
uGreen: { value: new Float32Array(2), type: 'vec2<f32>' },
uBlue: { value: new Float32Array(2), type: 'vec2<f32>' },
});

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

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

super({
gpuProgram,
glProgram,
resources: {},
resources: {
rgbSplitUniforms
},
});
// this.red = red;
// this.green = green;
// this.blue = blue;

this.red = options.red ?? [-10, 0];
this.green = options.green ?? [0, 10];
this.blue = options.blue ?? [0, 0];
}

/**
* Red channel offset.
*
* @member {Point | number[]}
* @default [-10,0]
*/
get red(): Offset { return this.resources.rgbSplitUniforms.uniforms.uRed; }
set red(value: Offset)
{
if (value instanceof Point)
{
this.redX = value.x;
this.redY = value.y;

return;
}

this.resources.rgbSplitUniforms.uniforms.uRed = value;
}

/**
* Amount of x-axis offset for the red channel.
* @default -10
*/
// get red(): Offset
// {
// return this.uniforms.red;
// }
// set red(value: Offset)
// {
// this.uniforms.red = value;
// }
get redX(): number { return this.resources.rgbSplitUniforms.uniforms.uRed[0]; }
set redX(value: number) { this.resources.rgbSplitUniforms.uniforms.uRed[0] = value; }

/**
* Amount of y-axis offset for the red channel.
* @default 0
*/
get redY(): number { return this.resources.rgbSplitUniforms.uniforms.uRed[1]; }
set redY(value: number) { this.resources.rgbSplitUniforms.uniforms.uRed[1] = value; }

/**
* Green channel offset.
*
* @member {Point | number[]}
* @default [0,10]
*/
get green(): Offset { return this.resources.rgbSplitUniforms.uniforms.uGreen; }
set green(value: Offset)
{
if (value instanceof Point)
{
this.greenX = value.x;
this.greenY = value.y;

return;
}

this.resources.rgbSplitUniforms.uniforms.uGreen = value;
}

/**
* Amount of x-axis offset for the green channel.
* @default 0
*/
get greenX(): number { return this.resources.rgbSplitUniforms.uniforms.uGreen[0]; }
set greenX(value: number) { this.resources.rgbSplitUniforms.uniforms.uGreen[0] = value; }

/**
* Amount of y-axis offset for the green channel.
* @default 10
*/
get greenY(): number { return this.resources.rgbSplitUniforms.uniforms.uGreen[1]; }
set greenY(value: number) { this.resources.rgbSplitUniforms.uniforms.uGreen[1] = value; }

/**
* Blue channel offset.
* @default [0,0]
*/
get blue(): Offset { return this.resources.rgbSplitUniforms.uniforms.uBlue; }
set blue(value: Offset)
{
if (value instanceof Point)
{
this.blueX = value.x;
this.blueY = value.y;

return;
}

this.resources.rgbSplitUniforms.uniforms.uBlue = value;
}

/**
* Amount of x-axis offset for the blue channel.
* @default 0
*/
// get green(): Offset
// {
// return this.uniforms.green;
// }
// set green(value: Offset)
// {
// this.uniforms.green = value;
// }
get blueX(): number { return this.resources.rgbSplitUniforms.uniforms.uBlue[0]; }
set blueX(value: number) { this.resources.rgbSplitUniforms.uniforms.uBlue[0] = value; }

/**
* Blue offset.
*
* @member {Point | number[]}
* Amount of y-axis offset for the blue channel.
* @default 0
*/
// get blue(): Offset
// {
// return this.uniforms.blue;
// }
// set blue(value: Offset)
// {
// this.uniforms.blue = value;
// }
get blueY(): number { return this.resources.rgbSplitUniforms.uniforms.uBlue[1]; }
set blueY(value: number) { this.resources.rgbSplitUniforms.uniforms.uBlue[1] = value; }
}
23 changes: 12 additions & 11 deletions filters/rgb-split/src/rgb-split.frag
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
precision mediump float;

varying vec2 vTextureCoord;
precision highp float;
in vec2 vTextureCoord;
out vec4 finalColor;

uniform sampler2D uSampler;
uniform vec4 filterArea;
uniform vec2 red;
uniform vec2 green;
uniform vec2 blue;
uniform vec4 uInputSize;
uniform vec2 uRed;
uniform vec2 uGreen;
uniform vec2 uBlue;

void main(void)
{
gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/filterArea.xy).r;
gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/filterArea.xy).g;
gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/filterArea.xy).b;
gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;
float r = texture2D(uSampler, vTextureCoord + uRed/uInputSize.xy).r;
float g = texture2D(uSampler, vTextureCoord + uGreen/uInputSize.xy).g;
float b = texture2D(uSampler, vTextureCoord + uBlue/uInputSize.xy).b;
float a = texture2D(uSampler, vTextureCoord).a;
finalColor = vec4(r, g, b, a);
}
31 changes: 31 additions & 0 deletions filters/rgb-split/src/rgb-split.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
struct RgbSplitUniforms {
uRed: vec2<f32>,
uGreen: vec2<f32>,
uBlue: vec3<f32>,
};

struct GlobalFilterUniforms {
uInputSize:vec4<f32>,
uInputPixel:vec4<f32>,
uuInputClamp:vec4<f32>,
uOutputFrame:vec4<f32>,
uGlobalFrame:vec4<f32>,
uOutputTexture:vec4<f32>,
};

@group(0) @binding(0) var<uniform> gfu: GlobalFilterUniforms;

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

@fragment
fn mainFragment(
@builtin(position) position: vec4<f32>,
@location(0) uv : vec2<f32>
) -> @location(0) vec4<f32> {
let r = textureSample(uSampler, uSampler, vTextureCoord + rgbSplitUniforms.uRed/uInputSize.xy).r;
let g = textureSample(uSampler, uSampler, vTextureCoord + rgbSplitUniforms.uGreen/uInputSize.xy).g;
let b = textureSample(uSampler, uSampler, vTextureCoord + rgbSplitUniforms.uBlue/uInputSize.xy).b;
let a = textureSample(uSampler, uSampler, vTextureCoord).a;
return vec4<f32>(r, g, b, a);
}
1 change: 1 addition & 0 deletions tools/demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const main = async () =>
filters.pixelate.call(app);
filters.glow.call(app);
filters.hslAdjustment.call(app);
filters.rgb.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 2374fe9

Please sign in to comment.