diff --git a/packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue b/packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue
index 2648e234a2..705d2f62ab 100644
--- a/packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue
+++ b/packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue
@@ -29,6 +29,16 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._watermarkEditor.scale }}
+
+ {{ i18n.ts._watermarkEditor.angle }}
+
+
{{ i18n.ts._watermarkEditor.scale }}
+
+ {{ i18n.ts._watermarkEditor.angle }}
+
+
x_offset - (x_scale / 2.0) && in_uv.x < x_offset + (x_scale / 2.0) &&
- in_uv.y > y_offset - (y_scale / 2.0) && in_uv.y < y_offset + (y_scale / 2.0);
+ bool isInside = rotatedUV.x > x_offset - (x_scale / 2.0) && rotatedUV.x < x_offset + (x_scale / 2.0) &&
+ rotatedUV.y > y_offset - (y_scale / 2.0) && rotatedUV.y < y_offset + (y_scale / 2.0);
if (!isInside) {
out_color = in_color;
return;
@@ -55,8 +70,8 @@ void main() {
}
vec4 watermark_color = texture(u_texture_watermark, vec2(
- (in_uv.x - (x_offset - (x_scale / 2.0))) / x_scale,
- (in_uv.y - (y_offset - (y_scale / 2.0))) / y_scale
+ (rotatedUV.x - (x_offset - (x_scale / 2.0))) / x_scale,
+ (rotatedUV.y - (y_offset - (y_scale / 2.0))) / y_scale
));
out_color.r = mix(in_color.r, watermark_color.r, u_opacity * watermark_color.a);
@@ -87,6 +102,13 @@ export const FX_watermarkPlacement = defineImageEffectorFx({
max: 1.0,
step: 0.01,
},
+ angle: {
+ type: 'number' as const,
+ default: 0,
+ min: -1.0,
+ max: 1.0,
+ step: 0.01,
+ },
align: {
type: 'align' as const,
default: { x: 'right', y: 'bottom' },
@@ -114,8 +136,9 @@ export const FX_watermarkPlacement = defineImageEffectorFx({
gl.uniform2fv(u.resolution_watermark, [textures.watermark.width, textures.watermark.height]);
gl.uniform1f(u.scale, params.scale);
+
gl.uniform1f(u.opacity, params.opacity);
- gl.uniform1f(u.angle, 0.0);
+ gl.uniform1f(u.angle, params.angle);
gl.uniform1i(u.repeat, params.repeat ? 1 : 0);
gl.uniform1i(u.alignX, params.align.x === 'left' ? 0 : params.align.x === 'right' ? 2 : 1);
gl.uniform1i(u.alignY, params.align.y === 'top' ? 0 : params.align.y === 'bottom' ? 2 : 1);
diff --git a/packages/frontend/src/utility/watermark.ts b/packages/frontend/src/utility/watermark.ts
index b91508381c..accb967f89 100644
--- a/packages/frontend/src/utility/watermark.ts
+++ b/packages/frontend/src/utility/watermark.ts
@@ -17,6 +17,7 @@ export type WatermarkPreset = {
text: string;
repeat: boolean;
scale: number;
+ angle: number;
align: { x: 'left' | 'center' | 'right'; y: 'top' | 'center' | 'bottom' };
opacity: number;
} | {
@@ -27,6 +28,7 @@ export type WatermarkPreset = {
cover: boolean;
repeat: boolean;
scale: number;
+ angle: number;
align: { x: 'left' | 'center' | 'right'; y: 'top' | 'center' | 'bottom' };
opacity: number;
} | {
@@ -69,6 +71,7 @@ export class WatermarkRenderer {
repeat: layer.repeat,
scale: layer.scale,
align: layer.align,
+ angle: layer.angle,
opacity: layer.opacity,
cover: false,
watermark: {
@@ -85,6 +88,7 @@ export class WatermarkRenderer {
repeat: layer.repeat,
scale: layer.scale,
align: layer.align,
+ angle: layer.angle,
opacity: layer.opacity,
cover: layer.cover,
watermark: {