Compare commits
8 Commits
420756d744
...
40e35c051a
| Author | SHA1 | Date |
|---|---|---|
|
|
40e35c051a | |
|
|
b93717be33 | |
|
|
fe805fb7f0 | |
|
|
e9af9d4451 | |
|
|
ce90fee586 | |
|
|
5bec8ba6b0 | |
|
|
3dbfd80d65 | |
|
|
b33eeb1366 |
|
|
@ -1,11 +1,12 @@
|
|||
## 2025.6.1
|
||||
|
||||
### Note
|
||||
- Misskey Webプラグインのnote_view_interruptorは不具合の影響により現在一時的に無効化されています。
|
||||
- AiScript Misskey拡張API(Misskey Webプラグイン)の[note_view_interruptor](https://misskey-hub.net/ja/docs/for-developers/plugin/plugin-api-reference/#pluginregister_note_view_interruptorfn)は不具合の影響により現在一時的に無効化されています。
|
||||
- Misskey Web投稿フォームのプレビュー切り替えは「...」メニュー内に配置されました
|
||||
|
||||
### Client
|
||||
- Feat: 画像にウォーターマークを付与できるようになりました
|
||||
- Feat: 画像の加工ができるようになりました(実験的)
|
||||
- Enhance: ノートのリアクション一覧で、押せるリアクションを優先して表示できるようにするオプションを追加
|
||||
- Enhance: 全てのチャットメッセージを既読にできるように(設定→その他)
|
||||
- Enhance: ミュートした絵文字をデバイス間で同期できるように
|
||||
|
|
|
|||
|
|
@ -12220,6 +12220,14 @@ export interface Locale extends ILocale {
|
|||
* チェッカー
|
||||
*/
|
||||
"checker": string;
|
||||
/**
|
||||
* ブロックノイズ
|
||||
*/
|
||||
"blockNoise": string;
|
||||
/**
|
||||
* ティアリング
|
||||
*/
|
||||
"tearing": string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3273,3 +3273,5 @@ _imageEffector:
|
|||
stripe: "ストライプ"
|
||||
polkadot: "ポルカドット"
|
||||
checker: "チェッカー"
|
||||
blockNoise: "ブロックノイズ"
|
||||
tearing: "ティアリング"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
v-if="v.type === 'boolean'"
|
||||
v-model="layer.params[k]"
|
||||
>
|
||||
<template #label>{{ k }}</template>
|
||||
<template #label>{{ fx.params[k].label ?? k }}</template>
|
||||
</MkSwitch>
|
||||
<MkRange
|
||||
v-else-if="v.type === 'number'"
|
||||
|
|
@ -29,6 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
:min="v.min"
|
||||
:max="v.max"
|
||||
:step="v.step"
|
||||
:textConverter="fx.params[k].toViewValue"
|
||||
@thumbDoubleClicked="() => {
|
||||
if (fx.params[k].default != null) {
|
||||
layer.params[k] = fx.params[k].default;
|
||||
|
|
@ -37,13 +38,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
}
|
||||
}"
|
||||
>
|
||||
<template #label>{{ k }}</template>
|
||||
<template #label>{{ fx.params[k].label ?? k }}</template>
|
||||
</MkRange>
|
||||
<MkRadios
|
||||
v-else-if="v.type === 'number:enum'"
|
||||
v-model="layer.params[k]"
|
||||
>
|
||||
<template #label>{{ k }}</template>
|
||||
<template #label>{{ fx.params[k].label ?? k }}</template>
|
||||
<option v-for="item in v.enum" :value="item.value">{{ item.label }}</option>
|
||||
</MkRadios>
|
||||
<div v-else-if="v.type === 'seed'">
|
||||
|
|
@ -55,7 +56,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
:max="10000"
|
||||
:step="1"
|
||||
>
|
||||
<template #label>{{ k }}</template>
|
||||
<template #label>{{ fx.params[k].label ?? k }}</template>
|
||||
</MkRange>
|
||||
</div>
|
||||
<MkInput
|
||||
|
|
@ -64,7 +65,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
type="color"
|
||||
@update:modelValue="v => { const c = getRgb(v); if (c != null) layer.params[k] = c; }"
|
||||
>
|
||||
<template #label>{{ k }}</template>
|
||||
<template #label>{{ fx.params[k].label ?? k }}</template>
|
||||
</MkInput>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ watch(layers, async () => {
|
|||
}, { deep: true });
|
||||
|
||||
function addEffect(ev: MouseEvent) {
|
||||
os.popupMenu(FXS.filter(fx => fx.id !== 'watermarkPlacement').map((fx) => ({
|
||||
os.popupMenu(FXS.map((fx) => ({
|
||||
text: fx.name,
|
||||
action: () => {
|
||||
layers.push({
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ type ParamTypeToPrimitive = {
|
|||
type ImageEffectorFxParamDefs = Record<string, {
|
||||
type: keyof ParamTypeToPrimitive;
|
||||
default: any;
|
||||
label?: string;
|
||||
toViewValue?: (v: any) => string;
|
||||
}>;
|
||||
|
||||
export function defineImageEffectorFx<ID extends string, PS extends ImageEffectorFxParamDefs, US extends string[]>(fx: ImageEffectorFx<ID, PS, US>) {
|
||||
|
|
|
|||
|
|
@ -10,20 +10,17 @@ import { FX_colorClamp } from './fxs/colorClamp.js';
|
|||
import { FX_colorClampAdvanced } from './fxs/colorClampAdvanced.js';
|
||||
import { FX_distort } from './fxs/distort.js';
|
||||
import { FX_polkadot } from './fxs/polkadot.js';
|
||||
import { FX_glitch } from './fxs/glitch.js';
|
||||
import { FX_tearing } from './fxs/tearing.js';
|
||||
import { FX_grayscale } from './fxs/grayscale.js';
|
||||
import { FX_invert } from './fxs/invert.js';
|
||||
import { FX_mirror } from './fxs/mirror.js';
|
||||
import { FX_stripe } from './fxs/stripe.js';
|
||||
import { FX_threshold } from './fxs/threshold.js';
|
||||
import { FX_watermarkPlacement } from './fxs/watermarkPlacement.js';
|
||||
import { FX_zoomLines } from './fxs/zoomLines.js';
|
||||
import { FX_blockNoise } from './fxs/blockNoise.js';
|
||||
import type { ImageEffectorFx } from './ImageEffector.js';
|
||||
|
||||
export const FXS = [
|
||||
FX_watermarkPlacement,
|
||||
FX_chromaticAberration,
|
||||
FX_glitch,
|
||||
FX_mirror,
|
||||
FX_invert,
|
||||
FX_grayscale,
|
||||
|
|
@ -36,4 +33,7 @@ export const FXS = [
|
|||
FX_stripe,
|
||||
FX_polkadot,
|
||||
FX_checker,
|
||||
FX_chromaticAberration,
|
||||
FX_tearing,
|
||||
FX_blockNoise,
|
||||
] as const satisfies ImageEffectorFx<string, any>[];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import seedrandom from 'seedrandom';
|
||||
import { defineImageEffectorFx } from '../ImageEffector.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
const shader = `#version 300 es
|
||||
precision mediump float;
|
||||
|
||||
in vec2 in_uv;
|
||||
uniform sampler2D in_texture;
|
||||
uniform vec2 in_resolution;
|
||||
uniform int u_amount;
|
||||
uniform float u_shiftStrengths[128];
|
||||
uniform vec2 u_shiftOrigins[128];
|
||||
uniform vec2 u_shiftSizes[128];
|
||||
uniform float u_channelShift;
|
||||
out vec4 out_color;
|
||||
|
||||
void main() {
|
||||
// TODO: ピクセル毎に計算する必要はないのでuniformにする
|
||||
float aspect_ratio = min(in_resolution.x, in_resolution.y) / max(in_resolution.x, in_resolution.y);
|
||||
float aspect_ratio_x = in_resolution.x > in_resolution.y ? 1.0 : aspect_ratio;
|
||||
float aspect_ratio_y = in_resolution.x < in_resolution.y ? 1.0 : aspect_ratio;
|
||||
|
||||
float v = 0.0;
|
||||
|
||||
for (int i = 0; i < u_amount; i++) {
|
||||
if (
|
||||
in_uv.x * aspect_ratio_x > ((u_shiftOrigins[i].x * aspect_ratio_x) - u_shiftSizes[i].x) &&
|
||||
in_uv.x * aspect_ratio_x < ((u_shiftOrigins[i].x * aspect_ratio_x) + u_shiftSizes[i].x) &&
|
||||
in_uv.y * aspect_ratio_y > ((u_shiftOrigins[i].y * aspect_ratio_y) - u_shiftSizes[i].y) &&
|
||||
in_uv.y * aspect_ratio_y < ((u_shiftOrigins[i].y * aspect_ratio_y) + u_shiftSizes[i].y)
|
||||
) {
|
||||
v += u_shiftStrengths[i];
|
||||
}
|
||||
}
|
||||
|
||||
float r = texture(in_texture, vec2(in_uv.x + (v * (1.0 + u_channelShift)), in_uv.y)).r;
|
||||
float g = texture(in_texture, vec2(in_uv.x + v, in_uv.y)).g;
|
||||
float b = texture(in_texture, vec2(in_uv.x + (v * (1.0 + (u_channelShift / 2.0))), in_uv.y)).b;
|
||||
float a = texture(in_texture, vec2(in_uv.x + v, in_uv.y)).a;
|
||||
out_color = vec4(r, g, b, a);
|
||||
}
|
||||
`;
|
||||
|
||||
export const FX_blockNoise = defineImageEffectorFx({
|
||||
id: 'blockNoise' as const,
|
||||
name: i18n.ts._imageEffector._fxs.glitch + ': ' + i18n.ts._imageEffector._fxs.blockNoise,
|
||||
shader,
|
||||
uniforms: ['amount', 'channelShift'] as const,
|
||||
params: {
|
||||
amount: {
|
||||
type: 'number' as const,
|
||||
default: 50,
|
||||
min: 1,
|
||||
max: 100,
|
||||
step: 1,
|
||||
},
|
||||
strength: {
|
||||
type: 'number' as const,
|
||||
default: 0.05,
|
||||
min: -1,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
width: {
|
||||
type: 'number' as const,
|
||||
default: 0.05,
|
||||
min: 0.01,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
height: {
|
||||
type: 'number' as const,
|
||||
default: 0.01,
|
||||
min: 0.01,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
channelShift: {
|
||||
type: 'number' as const,
|
||||
default: 0,
|
||||
min: 0,
|
||||
max: 10,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
seed: {
|
||||
type: 'seed' as const,
|
||||
default: 100,
|
||||
},
|
||||
},
|
||||
main: ({ gl, program, u, params }) => {
|
||||
gl.uniform1i(u.amount, params.amount);
|
||||
gl.uniform1f(u.channelShift, params.channelShift);
|
||||
|
||||
const margin = 0;
|
||||
|
||||
const rnd = seedrandom(params.seed.toString());
|
||||
|
||||
for (let i = 0; i < params.amount; i++) {
|
||||
const o = gl.getUniformLocation(program, `u_shiftOrigins[${i.toString()}]`);
|
||||
gl.uniform2f(o, (rnd() * (1 + (margin * 2))) - margin, (rnd() * (1 + (margin * 2))) - margin);
|
||||
|
||||
const s = gl.getUniformLocation(program, `u_shiftStrengths[${i.toString()}]`);
|
||||
gl.uniform1f(s, (1 - (rnd() * 2)) * params.strength);
|
||||
|
||||
const sizes = gl.getUniformLocation(program, `u_shiftSizes[${i.toString()}]`);
|
||||
gl.uniform2f(sizes, params.width, params.height);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
@ -58,6 +58,7 @@ export const FX_checker = defineImageEffectorFx({
|
|||
min: -1.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 90) + '°',
|
||||
},
|
||||
scale: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -76,6 +77,7 @@ export const FX_checker = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
},
|
||||
main: ({ gl, u, params }) => {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ void main() {
|
|||
vec3 color = in_color.rgb;
|
||||
|
||||
color = color * u_brightness;
|
||||
color += vec3(clamp(u_lightness, 0.0, 2.0) - 1.0);
|
||||
color += vec3(u_lightness);
|
||||
color = (color - 0.5) * u_contrast + 0.5;
|
||||
|
||||
vec3 hsl = rgb2hsl(color);
|
||||
|
|
@ -92,45 +92,50 @@ export const FX_colorAdjust = defineImageEffectorFx({
|
|||
params: {
|
||||
lightness: {
|
||||
type: 'number' as const,
|
||||
default: 100,
|
||||
min: 0,
|
||||
max: 200,
|
||||
step: 1,
|
||||
default: 0,
|
||||
min: -1,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
contrast: {
|
||||
type: 'number' as const,
|
||||
default: 100,
|
||||
default: 1,
|
||||
min: 0,
|
||||
max: 200,
|
||||
step: 1,
|
||||
max: 4,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
hue: {
|
||||
type: 'number' as const,
|
||||
default: 0,
|
||||
min: -360,
|
||||
max: 360,
|
||||
step: 1,
|
||||
min: -1,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 180) + '°',
|
||||
},
|
||||
brightness: {
|
||||
type: 'number' as const,
|
||||
default: 100,
|
||||
default: 1,
|
||||
min: 0,
|
||||
max: 200,
|
||||
step: 1,
|
||||
max: 4,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
saturation: {
|
||||
type: 'number' as const,
|
||||
default: 100,
|
||||
default: 1,
|
||||
min: 0,
|
||||
max: 200,
|
||||
step: 1,
|
||||
max: 4,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
},
|
||||
main: ({ gl, u, params }) => {
|
||||
gl.uniform1f(u.brightness, params.brightness / 100);
|
||||
gl.uniform1f(u.contrast, params.contrast / 100);
|
||||
gl.uniform1f(u.hue, params.hue / 360);
|
||||
gl.uniform1f(u.lightness, params.lightness / 100);
|
||||
gl.uniform1f(u.saturation, params.saturation / 100);
|
||||
gl.uniform1f(u.brightness, params.brightness);
|
||||
gl.uniform1f(u.contrast, params.contrast);
|
||||
gl.uniform1f(u.hue, params.hue / 2);
|
||||
gl.uniform1f(u.lightness, params.lightness);
|
||||
gl.uniform1f(u.saturation, params.saturation);
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ export const FX_colorClamp = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
min: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -44,6 +45,7 @@ export const FX_colorClamp = defineImageEffectorFx({
|
|||
min: -1.0,
|
||||
max: 0.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
},
|
||||
main: ({ gl, u, params }) => {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export const FX_colorClampAdvanced = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
rMin: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -48,6 +49,7 @@ export const FX_colorClampAdvanced = defineImageEffectorFx({
|
|||
min: -1.0,
|
||||
max: 0.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
gMax: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -55,6 +57,7 @@ export const FX_colorClampAdvanced = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
gMin: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -62,6 +65,7 @@ export const FX_colorClampAdvanced = defineImageEffectorFx({
|
|||
min: -1.0,
|
||||
max: 0.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
bMax: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -69,6 +73,7 @@ export const FX_colorClampAdvanced = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
bMin: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -76,6 +81,7 @@ export const FX_colorClampAdvanced = defineImageEffectorFx({
|
|||
min: -1.0,
|
||||
max: 0.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
},
|
||||
main: ({ gl, u, params }) => {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ import { i18n } from '@/i18n.js';
|
|||
const shader = `#version 300 es
|
||||
precision mediump float;
|
||||
|
||||
const float PI = 3.141592653589793;
|
||||
const float TWO_PI = 6.283185307179586;
|
||||
const float HALF_PI = 1.5707963267948966;
|
||||
|
||||
in vec2 in_uv;
|
||||
uniform sampler2D in_texture;
|
||||
uniform vec2 in_resolution;
|
||||
|
|
@ -20,8 +24,8 @@ out vec4 out_color;
|
|||
|
||||
void main() {
|
||||
float v = u_direction == 0 ?
|
||||
sin(u_phase + in_uv.y * u_frequency) * u_strength :
|
||||
sin(u_phase + in_uv.x * u_frequency) * u_strength;
|
||||
sin((HALF_PI + (u_phase * PI) - (u_frequency / 2.0)) + in_uv.y * u_frequency) * u_strength :
|
||||
sin((HALF_PI + (u_phase * PI) - (u_frequency / 2.0)) + in_uv.x * u_frequency) * u_strength;
|
||||
vec4 in_color = u_direction == 0 ?
|
||||
texture(in_texture, vec2(in_uv.x + v, in_uv.y)) :
|
||||
texture(in_texture, vec2(in_uv.x, in_uv.y + v));
|
||||
|
|
@ -38,32 +42,34 @@ export const FX_distort = defineImageEffectorFx({
|
|||
direction: {
|
||||
type: 'number:enum' as const,
|
||||
enum: [{ value: 0, label: 'v' }, { value: 1, label: 'h' }],
|
||||
default: 0,
|
||||
default: 1,
|
||||
},
|
||||
phase: {
|
||||
type: 'number' as const,
|
||||
default: 50.0,
|
||||
min: 0.0,
|
||||
max: 100,
|
||||
default: 0.0,
|
||||
min: -1.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
frequency: {
|
||||
type: 'number' as const,
|
||||
default: 50,
|
||||
default: 30,
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 0.1,
|
||||
},
|
||||
strength: {
|
||||
type: 'number' as const,
|
||||
default: 0.1,
|
||||
default: 0.05,
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
},
|
||||
main: ({ gl, u, params }) => {
|
||||
gl.uniform1f(u.phase, params.phase / 10);
|
||||
gl.uniform1f(u.phase, params.phase);
|
||||
gl.uniform1f(u.frequency, params.frequency);
|
||||
gl.uniform1f(u.strength, params.strength);
|
||||
gl.uniform1i(u.direction, params.direction);
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ export const FX_polkadot = defineImageEffectorFx({
|
|||
min: -1.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 90) + '°',
|
||||
},
|
||||
scale: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -111,6 +112,7 @@ export const FX_polkadot = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
minorDivisions: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -132,6 +134,7 @@ export const FX_polkadot = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
color: {
|
||||
type: 'color' as const,
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ export const FX_stripe = defineImageEffectorFx({
|
|||
min: -1.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 90) + '°',
|
||||
},
|
||||
frequency: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -74,6 +75,7 @@ export const FX_stripe = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
color: {
|
||||
type: 'color' as const,
|
||||
|
|
@ -85,6 +87,7 @@ export const FX_stripe = defineImageEffectorFx({
|
|||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
},
|
||||
main: ({ gl, u, params }) => {
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ void main() {
|
|||
}
|
||||
`;
|
||||
|
||||
export const FX_glitch = defineImageEffectorFx({
|
||||
id: 'glitch' as const,
|
||||
name: i18n.ts._imageEffector._fxs.glitch,
|
||||
export const FX_tearing = defineImageEffectorFx({
|
||||
id: 'tearing' as const,
|
||||
name: i18n.ts._imageEffector._fxs.glitch + ': ' + i18n.ts._imageEffector._fxs.tearing,
|
||||
shader,
|
||||
uniforms: ['amount', 'channelShift'] as const,
|
||||
params: {
|
||||
|
|
@ -52,17 +52,19 @@ export const FX_glitch = defineImageEffectorFx({
|
|||
},
|
||||
strength: {
|
||||
type: 'number' as const,
|
||||
default: 5,
|
||||
min: -100,
|
||||
max: 100,
|
||||
default: 0.05,
|
||||
min: -1,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
size: {
|
||||
type: 'number' as const,
|
||||
default: 20,
|
||||
default: 0.2,
|
||||
min: 0,
|
||||
max: 100,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
channelShift: {
|
||||
type: 'number' as const,
|
||||
|
|
@ -70,6 +72,7 @@ export const FX_glitch = defineImageEffectorFx({
|
|||
min: 0,
|
||||
max: 10,
|
||||
step: 0.01,
|
||||
toViewValue: v => Math.round(v * 100) + '%',
|
||||
},
|
||||
seed: {
|
||||
type: 'seed' as const,
|
||||
|
|
@ -87,10 +90,10 @@ export const FX_glitch = defineImageEffectorFx({
|
|||
gl.uniform1f(o, rnd());
|
||||
|
||||
const s = gl.getUniformLocation(program, `u_shiftStrengths[${i.toString()}]`);
|
||||
gl.uniform1f(s, (1 - (rnd() * 2)) * (params.strength / 100));
|
||||
gl.uniform1f(s, (1 - (rnd() * 2)) * params.strength);
|
||||
|
||||
const h = gl.getUniformLocation(program, `u_shiftHeights[${i.toString()}]`);
|
||||
gl.uniform1f(h, rnd() * (params.size / 100));
|
||||
gl.uniform1f(h, rnd() * params.size);
|
||||
}
|
||||
},
|
||||
});
|
||||
Loading…
Reference in New Issue