diff --git a/examples/src/filters/tilt-shift.mjs b/examples/src/filters/tilt-shift.mjs index d08db48c3..9063c7816 100644 --- a/examples/src/filters/tilt-shift.mjs +++ b/examples/src/filters/tilt-shift.mjs @@ -1,8 +1,19 @@ export default function () { - this.addFilter('TiltShiftFilter', function (folder) - { - folder.add(this, 'blur', 0, 200); - folder.add(this, 'gradientBlur', 0, 1000); + const app = this; + const height = app.initHeight; + const width = app.initWidth; + + this.addFilter('TiltShiftFilter', { + args: { start: { x: 0, y: height / 2 }, end: { x: width, y: height / 2 } }, + oncreate(folder) + { + folder.add(this, 'blur', 0, 200); + folder.add(this, 'gradientBlur', 0, 1000); + folder.add(this, 'startX', 0, width); + folder.add(this, 'startY', 0, height); + folder.add(this, 'endX', 0, width); + folder.add(this, 'endY', 0, height); + } }); } diff --git a/src/tilt-shift/TiltShiftAxisFilter.ts b/src/tilt-shift/TiltShiftAxisFilter.ts index abf16d25d..7b1498478 100644 --- a/src/tilt-shift/TiltShiftAxisFilter.ts +++ b/src/tilt-shift/TiltShiftAxisFilter.ts @@ -1,4 +1,4 @@ -import { Filter, GlProgram, GpuProgram, PointData } from 'pixi.js'; +import { Filter, GlProgram, GpuProgram, PointData, Texture, ViewSystem } from 'pixi.js'; import { vertex, wgslVertex } from '../defaults'; import fragment from './tilt-shift.frag'; import source from './tilt-shift.wgsl'; @@ -39,10 +39,6 @@ export class TiltShiftAxisFilter extends Filter blur: 100, /** The strength of the blur gradient */ gradientBlur: 600, - /** The position to start the effect at. */ - start: { x: 0, y: window.innerHeight / 2 }, - /** The position to end the effect at. */ - end: { x: 600, y: window.innerHeight / 2 }, }; public uniforms: { @@ -50,14 +46,23 @@ export class TiltShiftAxisFilter extends Filter uStart: PointData uEnd: PointData; uDelta: Float32Array; - uTexSize: Float32Array; + uDimensions: Float32Array; }; private _tiltAxis: TiltShiftAxisFilterOptions['axis']; constructor(options?: TiltShiftAxisFilterOptions) { - options = { ...TiltShiftAxisFilter.DEFAULT_OPTIONS, ...options } as TiltShiftAxisFilterOptions; + const { width, height } = ViewSystem.defaultOptions as { width: number, height: number }; + + options = { + ...TiltShiftAxisFilter.DEFAULT_OPTIONS, + /** The position to start the effect at. */ + start: { x: 0, y: height / 2 }, + /** The position to end the effect at. */ + end: { x: width, y: height / 2 }, + ...options, + } as TiltShiftAxisFilterOptions; const gpuProgram = GpuProgram.from({ vertex: { @@ -83,25 +88,39 @@ export class TiltShiftAxisFilter extends Filter tiltShiftUniforms: { uBlur: { value: new Float32Array([ - options.blur ?? 100, - options.gradientBlur ?? 600 + options.blur as number, + options.gradientBlur as number, ]), type: 'vec2' }, uStart: { value: options.start, type: 'vec2' }, uEnd: { value: options.end, type: 'vec2' }, - uDelta: { value: new Float32Array([30, 30]), type: 'vec2' }, - uTexSize: { value: new Float32Array([window.innerWidth, window.innerHeight]), type: 'vec2' }, + uDelta: { value: new Float32Array([0, 0]), type: 'vec2' }, + uDimensions: { value: new Float32Array([width, height]), type: 'vec2' }, }, }, }); this.uniforms = this.resources.tiltShiftUniforms.uniforms; this._tiltAxis = options.axis; - this.updateDelta(); } - /** Updates the filter delta values. */ - protected updateDelta(): void + /** + * Update the dimensions + * @ignore + */ + public updateDimensions(input: Texture): void + { + const { uDimensions } = this.uniforms; + + uDimensions[0] = input.frame.width; + uDimensions[1] = input.frame.height; + } + + /** + * Updates the filter delta values. + * @ignore + */ + public updateDelta(): void { this.uniforms.uDelta[0] = 0; this.uniforms.uDelta[1] = 0; @@ -120,60 +139,4 @@ export class TiltShiftAxisFilter extends Filter this.uniforms.uDelta[0] = !isVert ? dx / d : -dy / d; this.uniforms.uDelta[1] = !isVert ? dy / d : dx / d; } - - // /** The strength of the blur. */ - // get blur(): number { return this.uniforms.uBlur[0]; } - // set blur(value: number) { this.uniforms.uBlur[0] = value; } - - // /** The strength of the gradient blur. */ - // get gradientBlur(): number { return this.uniforms.uBlur[1]; } - // set gradientBlur(value: number) { this.uniforms.uBlur[1] = value; } - - // /** The start position of the effect. */ - // get start(): PointData { return this.uniforms.uStart; } - // set start(value: PointData) - // { - // this.uniforms.uStart = value; - // this.updateDelta(); - // } - - // /** The start position of the effect on the `x` axis. */ - // get startX(): number { return this.start.x; } - // set startX(value: number) - // { - // this.start.x = value; - // this.updateDelta(); - // } - - // /** The start position of the effect on the `y` axis. */ - // get startY(): number { return this.startY; } - // set startY(value: number) - // { - // this.start.y = value; - // this.updateDelta(); - // } - - // /** The end position of the effect. */ - // get end(): PointData { return this.uniforms.uEnd; } - // set end(value: PointData) - // { - // this.uniforms.uEnd = value; - // this.updateDelta(); - // } - - // /** The end position of the effect on the `x` axis. */ - // get endX(): number { return this.end.x; } - // set endX(value: number) - // { - // this.end.x = value; - // this.updateDelta(); - // } - - // /** The end position of the effect on the `y` axis. */ - // get endY(): number { return this.end.y; } - // set endY(value: number) - // { - // this.end.y = value; - // this.updateDelta(); - // } } diff --git a/src/tilt-shift/TiltShiftFilter.ts b/src/tilt-shift/TiltShiftFilter.ts index d33a9b670..b55ddfe74 100644 --- a/src/tilt-shift/TiltShiftFilter.ts +++ b/src/tilt-shift/TiltShiftFilter.ts @@ -41,6 +41,8 @@ export class TiltShiftFilter extends TiltShiftAxisFilter super({ ...options, axis: 'horizontal' }); this._tiltShiftYFilter = new TiltShiftAxisFilter({ ...options, axis: 'vertical' }); + this.updateDelta(); + Object.assign(this, options); } @@ -58,12 +60,22 @@ export class TiltShiftFilter extends TiltShiftAxisFilter { const renderTarget = TexturePool.getSameSizeTexture(input); + this.updateDimensions(input); + this._tiltShiftYFilter.updateDimensions(input); + filterManager.applyFilter(this, input, renderTarget, true); filterManager.applyFilter(this._tiltShiftYFilter, renderTarget, output, clearMode); TexturePool.returnTexture(renderTarget); } + /** @ignore */ + public override updateDelta(): void + { + super.updateDelta(); + this._tiltShiftYFilter.updateDelta(); + } + /** The strength of the blur. */ get blur(): number { return this.uniforms.uBlur[0]; } set blur(value: number) { this.uniforms.uBlur[0] = this._tiltShiftYFilter.uniforms.uBlur[0] = value; } @@ -74,26 +86,50 @@ export class TiltShiftFilter extends TiltShiftAxisFilter /** The position to start the effect at. */ get start(): PointData { return this.uniforms.uStart; } - set start(value: PointData) { this.uniforms.uStart = this._tiltShiftYFilter.uniforms.uStart = value; } + set start(value: PointData) + { + this.uniforms.uStart = this._tiltShiftYFilter.uniforms.uStart = value; + this.updateDelta(); + } /** The position to start the effect at on the `x` axis. */ get startX(): number { return this.start.x; } - set startX(value: number) { this.start.x = value; } + set startX(value: number) + { + this.start.x = value; + this.updateDelta(); + } /** The position to start the effect at on the `x` axis. */ get startY(): number { return this.start.y; } - set startY(value: number) { this.start.y = value; } + set startY(value: number) + { + this.start.y = value; + this.updateDelta(); + } /** The position to end the effect at. */ get end(): PointData { return this.uniforms.uEnd; } - set end(value: PointData) { this.uniforms.uEnd = this._tiltShiftYFilter.uniforms.uEnd = value; } + set end(value: PointData) + { + this.uniforms.uEnd = this._tiltShiftYFilter.uniforms.uEnd = value; + this.updateDelta(); + } /** The position to end the effect at on the `x` axis. */ get endX(): number { return this.end.x; } - set endX(value: number) { this.end.x = value; } + set endX(value: number) + { + this.end.x = value; + this.updateDelta(); + } /** The position to end the effect at on the `y` axis. */ get endY(): number { return this.end.y; } - set endY(value: number) { this.end.y = value; } + set endY(value: number) + { + this.end.y = value; + this.updateDelta(); + } } diff --git a/src/tilt-shift/tilt-shift.frag b/src/tilt-shift/tilt-shift.frag index cbaaad3ae..549503cf7 100644 --- a/src/tilt-shift/tilt-shift.frag +++ b/src/tilt-shift/tilt-shift.frag @@ -6,7 +6,7 @@ uniform vec2 uBlur; uniform vec2 uStart; uniform vec2 uEnd; uniform vec2 uDelta; -uniform vec2 uTexSize; +uniform vec2 uDimensions; float random(vec3 scale, float seed) { @@ -23,13 +23,13 @@ void main(void) float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); vec2 normal = normalize(vec2(uStart.y - uEnd.y, uEnd.x - uStart.x)); - float radius = smoothstep(0.0, 1.0, abs(dot(vTextureCoord * uTexSize - uStart, normal)) / gradientBlur) * blur; + float radius = smoothstep(0.0, 1.0, abs(dot(vTextureCoord * uDimensions - uStart, normal)) / gradientBlur) * blur; for (float t = -30.0; t <= 30.0; t++) { float percent = (t + offset - 0.5) / 30.0; float weight = 1.0 - abs(percent); - vec4 sample = texture(uTexture, vTextureCoord + uDelta / uTexSize * percent * radius); + vec4 sample = texture(uTexture, vTextureCoord + uDelta / uDimensions * percent * radius); sample.rgb *= sample.a; color += sample * weight; total += weight; diff --git a/src/tilt-shift/tilt-shift.wgsl b/src/tilt-shift/tilt-shift.wgsl index e6f136f96..b6707a555 100644 --- a/src/tilt-shift/tilt-shift.wgsl +++ b/src/tilt-shift/tilt-shift.wgsl @@ -3,7 +3,7 @@ struct TiltShiftUniforms { uStart: vec2, uEnd: vec2, uDelta: vec2, - uTexSize: vec2, + uDimensions: vec2, }; @group(0) @binding(1) var uTexture: texture_2d; @@ -20,20 +20,20 @@ fn mainFragment( let uStart = tiltShiftUniforms.uStart; let uEnd = tiltShiftUniforms.uEnd; let uDelta = tiltShiftUniforms.uDelta; - let uTexSize = tiltShiftUniforms.uTexSize; + let uDimensions = tiltShiftUniforms.uDimensions; var color: vec4 = vec4(0.0); var total: f32 = 0.0; let offset: f32 = random(position, vec3(12.9898, 78.233, 151.7182), 0.0); let normal: vec2 = normalize(vec2(uStart.y - uEnd.y, uEnd.x - uStart.x)); - let radius: f32 = smoothstep(0.0, 1.0, abs(dot(uv * uTexSize - uStart, normal)) / uBlurGradient) * uBlur; + let radius: f32 = smoothstep(0.0, 1.0, abs(dot(uv * uDimensions - uStart, normal)) / uBlurGradient) * uBlur; for (var t: f32 = -30.0; t <= 30.0; t += 1.0) { var percent: f32 = (t + offset - 0.5) / 30.0; var weight: f32 = 1.0 - abs(percent); - var sample: vec4 = textureSample(uTexture, uSampler, uv + uDelta / uTexSize * percent * radius); + var sample: vec4 = textureSample(uTexture, uSampler, uv + uDelta / uDimensions * percent * radius); sample = vec4(sample.xyz * sample.a, sample.a); // multiply sample.rgb with sample.a color += sample * weight; total += weight;