Skip to content

Commit

Permalink
Update Pixelate Filter
Browse files Browse the repository at this point in the history
  • Loading branch information
bbazukun123 committed Dec 30, 2023
1 parent bc896d2 commit a287d90
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 42 deletions.
85 changes: 62 additions & 23 deletions filters/pixelate/src/PixelateFilter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { vertex } from '@tools/fragments';
import { vertex, wgslVertex } from '@tools/fragments';
import fragment from './pixelate.frag';
import { Filter, GlProgram } from 'pixi.js';
import type { Point } from 'pixi.js';
import source from './pixelate.wgsl';
import { Filter, GlProgram, GpuProgram, UniformGroup, Point } from 'pixi.js';

type Size = number | number[] | Point;

Expand All @@ -16,42 +16,81 @@ type Size = number | number[] | Point;
*/
export class PixelateFilter extends Filter
{
/** Default values for options. */
public static readonly DEFAULT_SIZE: Size = 10;

/**
* @param {Point|Array<number>|number} [size=10] - Either the width/height of the size of the pixels, or square size
*/
constructor(size: Size = 10)
constructor(size: Size)
{
size = size ?? PixelateFilter.DEFAULT_SIZE;

const pixelateUniforms = new UniformGroup({
uSize: { 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: 'pixelate-filter',
});

super({
gpuProgram,
glProgram,
resources: {},
resources: {
pixelateUniforms,
},
});

// this.size = size;
this.size = size;
}

/**
* This a point that describes the size of the blocks.
* x is the width of the block and y is the height.
*
* @member {Point|Array<number>|number}
* @default 10
* The size of the pixels
* @default [10,10]
*/
// get size(): Size
// {
// return this.uniforms.size;
// }
// set size(value: Size)
// {
// if (typeof value === 'number')
// {
// value = [value, value];
// }
// this.uniforms.size = value;
// }
get size(): Size { return this.resources.pixelateUniforms.uniforms.uSize; }
set size(value: Size)
{
if (value instanceof Point)
{
this.sizeX = value.x;
this.sizeY = value.y;
}
else if (Array.isArray(value))
{
this.resources.pixelateUniforms.uniforms.uSize = value;
}
else
{
this.sizeX = this.sizeY = value;
}
}

/**
* The size of the pixels on the `x` axis
* @default 10
*/
get sizeX(): number { return this.resources.pixelateUniforms.uniforms.uSize[0]; }
set sizeX(value: number) { this.resources.pixelateUniforms.uniforms.uSize[0] = value; }

/**
* The size of the pixels on the `y` axis
* @default 10
*/
get sizeY(): number { return this.resources.pixelateUniforms.uniforms.uSize[1]; }
set sizeY(value: number) { this.resources.pixelateUniforms.uniforms.uSize[1] = value; }
}
30 changes: 13 additions & 17 deletions filters/pixelate/src/pixelate.frag
Original file line number Diff line number Diff line change
@@ -1,40 +1,36 @@
precision mediump float;
precision highp float;
in vec2 vTextureCoord;
out vec4 finalColor;

varying vec2 vTextureCoord;

uniform vec2 size;
uniform vec2 uSize;
uniform sampler2D uSampler;

uniform vec4 filterArea;
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 pixelate(vec2 coord, vec2 size)
vec2 pixelate(vec2 coord, vec2 uSize)
{
return floor( coord / size ) * size;
return floor( coord / uSize ) * uSize;
}

void main(void)
{
vec2 coord = mapCoord(vTextureCoord);

coord = pixelate(coord, size);

coord = pixelate(coord, uSize);
coord = unmapCoord(coord);

gl_FragColor = texture2D(uSampler, coord);
finalColor = texture(uSampler, coord);
}
53 changes: 53 additions & 0 deletions filters/pixelate/src/pixelate.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
struct PixelateUniforms {
uSize:vec2<f32>,
};

struct GlobalFilterUniforms {
uInputSize:vec4<f32>,
uInputPixel:vec4<f32>,
uInputClamp: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> pixelateUniforms : PixelateUniforms;

@fragment
fn mainFragment(
@location(0) uv: vec2<f32>,
@builtin(position) position: vec4<f32>
) -> @location(0) vec4<f32> {
let pixelSize: vec2<f32> = pixelateUniforms.uSize;
let coord: vec2<f32> = mapCoord(uv);

var pixCoord: vec2<f32> = pixelate(coord, pixelSize);
pixCoord = unmapCoord(pixCoord);

return textureSample(uSampler, uSampler, pixCoord);
}

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

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

fn pixelate(coord: vec2<f32>, size: vec2<f32>) -> vec2<f32>
{
return floor( coord / size ) * size;
}

19 changes: 19 additions & 0 deletions filters/twist/src/twist.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ struct TwistUniforms {
uOffset:vec2<f32>,
};

struct GlobalFilterUniforms {
uInputSize:vec4<f32>,
uInputPixel:vec4<f32>,
uInputClamp: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> twistUniforms : TwistUniforms;

Expand All @@ -14,6 +25,14 @@ fn mainFragment(
return textureSample(uSampler, uSampler, unmapCoord(twist(mapCoord(uv))));
}

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

fn unmapCoord(coord: vec2<f32> ) -> vec2<f32>
{
var mappedCoord: vec2<f32> = coord;
Expand Down
4 changes: 2 additions & 2 deletions tools/demo/src/filters/pixelate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export default function ()
{
this.addFilter('PixelateFilter', function (folder)
{
folder.add(this.size, '0', 4, 40).name('size.x');
folder.add(this.size, '1', 4, 40).name('size.y');
folder.add(this, 'sizeX', 4, 40).name('size.x');
folder.add(this, 'sizeY', 4, 40).name('size.y');
});
}
1 change: 1 addition & 0 deletions tools/demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const main = async () =>
filters.bloom.call(app);
filters.grayscale.call(app);
filters.twist.call(app);
filters.pixelate.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 a287d90

Please sign in to comment.