This commit is contained in:
syuilo 2025-09-20 14:15:31 +09:00
parent b4c622971f
commit 4d084d4479
4 changed files with 36 additions and 4 deletions

4
locales/index.d.ts vendored
View File

@ -12536,6 +12536,10 @@ export interface Locale extends ILocale {
*
*/
"zoomLinesBlack": string;
/**
*
*/
"circle": string;
};
};
/**

View File

@ -3355,6 +3355,7 @@ _imageEffector:
zoomLinesThreshold: "集中線の幅"
zoomLinesMaskSize: "中心径"
zoomLinesBlack: "黒色にする"
circle: "円形"
drafts: "下書き"
_drafts:

View File

@ -18,6 +18,7 @@ uniform sampler2D in_texture;
uniform vec2 in_resolution;
uniform vec2 u_offset;
uniform vec2 u_scale;
uniform bool u_ellipse;
uniform float u_angle;
uniform float u_radius;
uniform int u_samples;
@ -31,7 +32,14 @@ void main() {
centeredUv.x * sin(angle) + centeredUv.y * cos(angle)
) + u_offset;
bool isInside = rotatedUV.x > u_offset.x - u_scale.x && rotatedUV.x < u_offset.x + u_scale.x && rotatedUV.y > u_offset.y - u_scale.y && rotatedUV.y < u_offset.y + u_scale.y;
bool isInside = false;
if (u_ellipse) {
vec2 norm = (rotatedUV - u_offset) / u_scale;
isInside = dot(norm, norm) <= 1.0;
} else {
isInside = rotatedUV.x > u_offset.x - u_scale.x && rotatedUV.x < u_offset.x + u_scale.x && rotatedUV.y > u_offset.y - u_scale.y && rotatedUV.y < u_offset.y + u_scale.y;
}
if (!isInside) {
out_color = texture(in_texture, in_uv);
return;
@ -77,7 +85,7 @@ export const FX_blur = defineImageEffectorFx({
id: 'blur',
name: i18n.ts._imageEffector._fxs.blur,
shader,
uniforms: ['offset', 'scale', 'angle', 'radius', 'samples'] as const,
uniforms: ['offset', 'scale', 'ellipse', 'angle', 'radius', 'samples'] as const,
params: {
offsetX: {
label: i18n.ts._imageEffector._fxProps.offset + ' X',
@ -115,6 +123,11 @@ export const FX_blur = defineImageEffectorFx({
step: 0.01,
toViewValue: v => Math.round(v * 100) + '%',
},
ellipse: {
label: i18n.ts._imageEffector._fxProps.circle,
type: 'boolean',
default: false,
},
angle: {
label: i18n.ts._imageEffector._fxProps.angle,
type: 'number',
@ -136,6 +149,7 @@ export const FX_blur = defineImageEffectorFx({
main: ({ gl, u, params }) => {
gl.uniform2f(u.offset, params.offsetX / 2, params.offsetY / 2);
gl.uniform2f(u.scale, params.scaleX / 2, params.scaleY / 2);
gl.uniform1i(u.ellipse, params.ellipse ? 1 : 0);
gl.uniform1f(u.angle, params.angle / 2);
gl.uniform1f(u.radius, params.radius);
gl.uniform1i(u.samples, 256);

View File

@ -18,6 +18,7 @@ uniform sampler2D in_texture;
uniform vec2 in_resolution;
uniform vec2 u_offset;
uniform vec2 u_scale;
uniform bool u_ellipse;
uniform float u_angle;
uniform vec3 u_color;
uniform float u_opacity;
@ -35,7 +36,13 @@ void main() {
centeredUv.x * sin(angle) + centeredUv.y * cos(angle)
) + u_offset;
bool isInside = rotatedUV.x > u_offset.x - u_scale.x && rotatedUV.x < u_offset.x + u_scale.x && rotatedUV.y > u_offset.y - u_scale.y && rotatedUV.y < u_offset.y + u_scale.y;
bool isInside = false;
if (u_ellipse) {
vec2 norm = (rotatedUV - u_offset) / u_scale;
isInside = dot(norm, norm) <= 1.0;
} else {
isInside = rotatedUV.x > u_offset.x - u_scale.x && rotatedUV.x < u_offset.x + u_scale.x && rotatedUV.y > u_offset.y - u_scale.y && rotatedUV.y < u_offset.y + u_scale.y;
}
out_color = isInside ? vec4(
mix(in_color.r, u_color.r, u_opacity),
@ -50,7 +57,7 @@ export const FX_fill = defineImageEffectorFx({
id: 'fill',
name: i18n.ts._imageEffector._fxs.fill,
shader,
uniforms: ['offset', 'scale', 'angle', 'color', 'opacity'] as const,
uniforms: ['offset', 'scale', 'ellipse', 'angle', 'color', 'opacity'] as const,
params: {
offsetX: {
label: i18n.ts._imageEffector._fxProps.offset + ' X',
@ -88,6 +95,11 @@ export const FX_fill = defineImageEffectorFx({
step: 0.01,
toViewValue: v => Math.round(v * 100) + '%',
},
ellipse: {
label: i18n.ts._imageEffector._fxProps.circle,
type: 'boolean',
default: false,
},
angle: {
label: i18n.ts._imageEffector._fxProps.angle,
type: 'number',
@ -115,6 +127,7 @@ export const FX_fill = defineImageEffectorFx({
main: ({ gl, u, params }) => {
gl.uniform2f(u.offset, params.offsetX / 2, params.offsetY / 2);
gl.uniform2f(u.scale, params.scaleX / 2, params.scaleY / 2);
gl.uniform1i(u.ellipse, params.ellipse ? 1 : 0);
gl.uniform1f(u.angle, params.angle / 2);
gl.uniform3f(u.color, params.color[0], params.color[1], params.color[2]);
gl.uniform1f(u.opacity, params.opacity);