diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-06-05 12:58:32 +0900 |
|---|---|---|
| committer | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-06-05 12:58:32 +0900 |
| commit | c6808f1eb6ab3a3f0a5bb6f1931c908dc87eeeac (patch) | |
| tree | ccb6e519d7bd85578d0e74ad1eaa64d4351a81f7 /packages/frontend/src/utility/image-effector | |
| parent | refactor(frontend): refactor ImageEffector (diff) | |
| download | misskey-c6808f1eb6ab3a3f0a5bb6f1931c908dc87eeeac.tar.gz misskey-c6808f1eb6ab3a3f0a5bb6f1931c908dc87eeeac.tar.bz2 misskey-c6808f1eb6ab3a3f0a5bb6f1931c908dc87eeeac.zip | |
refactor(frontend): refactor ImageEffector
Diffstat (limited to 'packages/frontend/src/utility/image-effector')
| -rw-r--r-- | packages/frontend/src/utility/image-effector/ImageEffector.ts | 109 |
1 files changed, 25 insertions, 84 deletions
diff --git a/packages/frontend/src/utility/image-effector/ImageEffector.ts b/packages/frontend/src/utility/image-effector/ImageEffector.ts index c65346f848..1f5135a647 100644 --- a/packages/frontend/src/utility/image-effector/ImageEffector.ts +++ b/packages/frontend/src/utility/image-effector/ImageEffector.ts @@ -61,8 +61,6 @@ function getValue<T extends keyof ParamTypeToPrimitive>(params: Record<string, a export class ImageEffector<IEX extends ReadonlyArray<ImageEffectorFx<any, any, any>>> { private gl: WebGL2RenderingContext; private canvas: HTMLCanvasElement | null = null; - private renderTextureProgram: WebGLProgram; - private renderInvertedTextureProgram: WebGLProgram; private renderWidth: number; private renderHeight: number; private originalImage: ImageData | ImageBitmap | HTMLImageElement | HTMLCanvasElement; @@ -114,50 +112,9 @@ export class ImageEffector<IEX extends ReadonlyArray<ImageEffectorFx<any, any, a gl.bindTexture(gl.TEXTURE_2D, this.originalImageTexture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.originalImage.width, this.originalImage.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.originalImage); gl.bindTexture(gl.TEXTURE_2D, null); - - this.renderTextureProgram = initShaderProgram(this.gl, `#version 300 es - in vec2 position; - out vec2 in_uv; - - void main() { - in_uv = (position + 1.0) / 2.0; - gl_Position = vec4(position, 0.0, 1.0); - } - `, `#version 300 es - precision mediump float; - - in vec2 in_uv; - uniform sampler2D u_texture; - out vec4 out_color; - - void main() { - out_color = texture(u_texture, in_uv); - } - `); - - this.renderInvertedTextureProgram = initShaderProgram(this.gl, `#version 300 es - in vec2 position; - out vec2 in_uv; - - void main() { - in_uv = (position + 1.0) / 2.0; - in_uv.y = 1.0 - in_uv.y; - gl_Position = vec4(position, 0.0, 1.0); - } - `, `#version 300 es - precision mediump float; - - in vec2 in_uv; - uniform sampler2D u_texture; - out vec4 out_color; - - void main() { - out_color = texture(u_texture, in_uv); - } - `); } - private renderLayer(layer: ImageEffectorLayer, preTexture: WebGLTexture) { + private renderLayer(layer: ImageEffectorLayer, preTexture: WebGLTexture, invert = false) { const gl = this.gl; const fx = this.fxs.find(fx => fx.id === layer.fxId); @@ -166,11 +123,12 @@ export class ImageEffector<IEX extends ReadonlyArray<ImageEffectorFx<any, any, a const cachedShader = this.shaderCache.get(fx.id); const shaderProgram = cachedShader ?? initShaderProgram(this.gl, `#version 300 es in vec2 position; + uniform bool u_invert; out vec2 in_uv; void main() { in_uv = (position + 1.0) / 2.0; - gl_Position = vec4(position, 0.0, 1.0); + gl_Position = u_invert ? vec4(position * vec2(1.0, -1.0), 0.0, 1.0) : vec4(position, 0.0, 1.0); } `, fx.shader); if (cachedShader == null) { @@ -179,9 +137,16 @@ export class ImageEffector<IEX extends ReadonlyArray<ImageEffectorFx<any, any, a gl.useProgram(shaderProgram); + const positionLocation = gl.getAttribLocation(shaderProgram, 'position'); + gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(positionLocation); + const in_resolution = gl.getUniformLocation(shaderProgram, 'in_resolution'); gl.uniform2fv(in_resolution, [this.renderWidth, this.renderHeight]); + const u_invert = gl.getUniformLocation(shaderProgram, 'u_invert'); + gl.uniform1i(u_invert, invert ? 1 : 0); + gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, preTexture); const in_texture = gl.getUniformLocation(shaderProgram, 'in_texture'); @@ -214,27 +179,13 @@ export class ImageEffector<IEX extends ReadonlyArray<ImageEffectorFx<any, any, a public render() { const gl = this.gl; - { - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.originalImageTexture); - - gl.useProgram(this.renderTextureProgram); - const u_texture = gl.getUniformLocation(this.renderTextureProgram, 'u_texture'); - gl.uniform1i(u_texture, 0); - const u_resolution = gl.getUniformLocation(this.renderTextureProgram, 'u_resolution'); - gl.uniform2fv(u_resolution, [this.renderWidth, this.renderHeight]); - const positionLocation = gl.getAttribLocation(this.renderTextureProgram, 'position'); - gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(positionLocation); - - gl.drawArrays(gl.TRIANGLES, 0, 6); - } - - // -------------------- - let preTexture = this.originalImageTexture; + // TODO: layersが0の場合にoriginalImageTextureをそのまま描画する + for (const layer of this.layers) { + const isLast = layer === this.layers.at(-1); + const cachedResultTexture = this.perLayerResultTextures.get(layer.id); const resultTexture = cachedResultTexture ?? createTexture(gl); if (cachedResultTexture == null) { @@ -244,30 +195,22 @@ export class ImageEffector<IEX extends ReadonlyArray<ImageEffectorFx<any, any, a gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.renderWidth, this.renderHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.bindTexture(gl.TEXTURE_2D, null); - const cachedResultFrameBuffer = this.perLayerResultFrameBuffers.get(layer.id); - const resultFrameBuffer = cachedResultFrameBuffer ?? gl.createFramebuffer()!; - if (cachedResultFrameBuffer == null) { - this.perLayerResultFrameBuffers.set(layer.id, resultFrameBuffer); + if (isLast) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } else { + const cachedResultFrameBuffer = this.perLayerResultFrameBuffers.get(layer.id); + const resultFrameBuffer = cachedResultFrameBuffer ?? gl.createFramebuffer()!; + if (cachedResultFrameBuffer == null) { + this.perLayerResultFrameBuffers.set(layer.id, resultFrameBuffer); + } + gl.bindFramebuffer(gl.FRAMEBUFFER, resultFrameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, resultTexture, 0); } - gl.bindFramebuffer(gl.FRAMEBUFFER, resultFrameBuffer); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, resultTexture, 0); - - this.renderLayer(layer, preTexture); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); + this.renderLayer(layer, preTexture, isLast); preTexture = resultTexture; } - - // -------------------- - - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.useProgram(this.renderInvertedTextureProgram); - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, preTexture); - - gl.drawArrays(gl.TRIANGLES, 0, 6); } public async setLayers(layers: ImageEffectorLayer[]) { @@ -347,8 +290,6 @@ export class ImageEffector<IEX extends ReadonlyArray<ImageEffectorFx<any, any, a } this.paramTextures.clear(); - this.gl.deleteProgram(this.renderTextureProgram); - this.gl.deleteProgram(this.renderInvertedTextureProgram); this.gl.deleteTexture(this.originalImageTexture); if (disposeCanvas) { |