Fix front camera rotation mirroring in shader

Add uIsFrontCamera uniform to shader and adjust coordinate
transformations for front camera's mirrored texture coordinates:
- Position transform: (1-posY, 1-posX) instead of (posY, 1-posX)
- Angle transform: -angle - 90° instead of +angle + 90°

Applied to linearFocusDistance, radialFocusDistance, and blur
direction calculations in sampleBlurred.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2026-01-29 17:07:44 +01:00
commit 0cd41e9814
3 changed files with 51 additions and 17 deletions

View file

@ -10,6 +10,7 @@ uniform samplerExternalOES uTexture;
// Effect parameters
uniform int uMode; // 0 = linear, 1 = radial
uniform int uIsFrontCamera; // 0 = back camera, 1 = front camera
uniform float uAngle; // Rotation angle in radians
uniform float uPositionX; // Horizontal center of focus (0-1)
uniform float uPositionY; // Vertical center of focus (0-1)
@ -24,9 +25,15 @@ varying vec2 vTexCoord;
// Calculate signed distance from the focus region for LINEAR mode
float linearFocusDistance(vec2 uv) {
// Center point of the focus region
// Transform from screen coordinates to texture coordinates (90° rotation)
// Screen (x,y) -> Texture (y, 1-x)
vec2 center = vec2(uPositionY, 1.0 - uPositionX);
// Transform from screen coordinates to texture coordinates
// Back camera: Screen (x,y) -> Texture (y, 1-x)
// Front camera: Screen (x,y) -> Texture (1-y, 1-x) (additional X flip for mirror)
vec2 center;
if (uIsFrontCamera == 1) {
center = vec2(1.0 - uPositionY, 1.0 - uPositionX);
} else {
center = vec2(uPositionY, 1.0 - uPositionX);
}
vec2 offset = uv - center;
// Correct for screen aspect ratio to make coordinate space square
@ -35,9 +42,15 @@ float linearFocusDistance(vec2 uv) {
float screenAspect = uResolution.x / uResolution.y;
offset.y *= screenAspect;
// Adjust angle by +90 degrees to compensate for the coordinate transformation
// The position transform is a 90° CW rotation, so angles transform as θ + 90°
float adjustedAngle = uAngle + 1.5707963;
// Adjust angle to compensate for the coordinate transformation
// Back camera: +90° for the 90° CW rotation
// Front camera: -90° (negated due to X flip mirror effect)
float adjustedAngle;
if (uIsFrontCamera == 1) {
adjustedAngle = -uAngle - 1.5707963;
} else {
adjustedAngle = uAngle + 1.5707963;
}
float cosA = cos(adjustedAngle);
float sinA = sin(adjustedAngle);
@ -50,9 +63,13 @@ float linearFocusDistance(vec2 uv) {
// Calculate signed distance from the focus region for RADIAL mode
float radialFocusDistance(vec2 uv) {
// Center point of the focus region
// Transform from screen coordinates to texture coordinates (90° rotation)
// Screen (x,y) -> Texture (y, 1-x)
vec2 center = vec2(uPositionY, 1.0 - uPositionX);
// Transform from screen coordinates to texture coordinates
vec2 center;
if (uIsFrontCamera == 1) {
center = vec2(1.0 - uPositionY, 1.0 - uPositionX);
} else {
center = vec2(uPositionY, 1.0 - uPositionX);
}
vec2 offset = uv - center;
// Correct for screen aspect ratio to make coordinate space square
@ -61,9 +78,13 @@ float radialFocusDistance(vec2 uv) {
float screenAspect = uResolution.x / uResolution.y;
offset.y *= screenAspect;
// Apply rotation
// Adjust angle by +90 degrees to compensate for the coordinate transformation
float adjustedAngle = uAngle + 1.5707963;
// Apply rotation with angle adjustment for coordinate transformation
float adjustedAngle;
if (uIsFrontCamera == 1) {
adjustedAngle = -uAngle - 1.5707963;
} else {
adjustedAngle = uAngle + 1.5707963;
}
float cosA = cos(adjustedAngle);
float sinA = sin(adjustedAngle);
vec2 rotated = vec2(
@ -120,8 +141,13 @@ vec4 sampleBlurred(vec2 uv, float blur) {
vec2 blurDir;
if (uMode == 1) {
// Radial: blur away from center
// Transform from screen coordinates to texture coordinates (90° rotation)
vec2 center = vec2(uPositionY, 1.0 - uPositionX);
// Transform from screen coordinates to texture coordinates
vec2 center;
if (uIsFrontCamera == 1) {
center = vec2(1.0 - uPositionY, 1.0 - uPositionX);
} else {
center = vec2(uPositionY, 1.0 - uPositionX);
}
vec2 toCenter = uv - center;
float len = length(toCenter);
if (len > 0.001) {
@ -132,7 +158,12 @@ vec4 sampleBlurred(vec2 uv, float blur) {
} else {
// Linear: blur perpendicular to focus line
// Adjust angle for coordinate transformation
float blurAngle = uAngle + 1.5707963;
float blurAngle;
if (uIsFrontCamera == 1) {
blurAngle = -uAngle - 1.5707963;
} else {
blurAngle = uAngle + 1.5707963;
}
blurDir = vec2(cos(blurAngle), sin(blurAngle));
}