Add radial mode, UI controls, front camera, update to API 35
- Add radial/elliptical blur mode with aspect ratio control - Add UI sliders for blur intensity, falloff, and shape - Add front camera support with flip button - Update minimum SDK to API 35 (Android 15) - Enable landscape orientation (fullSensor) - Rename app to "Naiv Tilt Shift Camera" - Set APK output name to naiv-tilt-shift - Add project specification document Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e8a5fa4811
commit
d3ca23b71c
11 changed files with 679 additions and 94 deletions
|
|
@ -1,7 +1,7 @@
|
|||
#extension GL_OES_EGL_image_external : require
|
||||
|
||||
// Fragment shader for tilt-shift effect
|
||||
// Applies gradient blur based on distance from focus line
|
||||
// Supports both linear and radial blur modes
|
||||
|
||||
precision mediump float;
|
||||
|
||||
|
|
@ -9,17 +9,20 @@ precision mediump float;
|
|||
uniform samplerExternalOES uTexture;
|
||||
|
||||
// Effect parameters
|
||||
uniform int uMode; // 0 = linear, 1 = radial
|
||||
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)
|
||||
uniform float uSize; // Size of in-focus region (0-1)
|
||||
uniform float uBlurAmount; // Maximum blur intensity (0-1)
|
||||
uniform float uFalloff; // Transition sharpness (0-1, higher = more gradual)
|
||||
uniform float uAspectRatio; // Ellipse aspect ratio for radial mode
|
||||
uniform vec2 uResolution; // Texture resolution for proper sampling
|
||||
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
// Calculate signed distance from the focus line
|
||||
float focusDistance(vec2 uv) {
|
||||
// Calculate signed distance from the focus region for LINEAR mode
|
||||
float linearFocusDistance(vec2 uv) {
|
||||
// Center point of the focus region
|
||||
vec2 center = vec2(uPositionX, uPositionY);
|
||||
vec2 offset = uv - center;
|
||||
|
|
@ -35,18 +38,45 @@ float focusDistance(vec2 uv) {
|
|||
return abs(rotatedY);
|
||||
}
|
||||
|
||||
// Calculate signed distance from the focus region for RADIAL mode
|
||||
float radialFocusDistance(vec2 uv) {
|
||||
// Center point of the focus region
|
||||
vec2 center = vec2(uPositionX, uPositionY);
|
||||
vec2 offset = uv - center;
|
||||
|
||||
// Adjust for aspect ratio to create ellipse
|
||||
// Correct for screen aspect ratio first
|
||||
float screenAspect = uResolution.x / uResolution.y;
|
||||
offset.x *= screenAspect;
|
||||
|
||||
// Apply rotation
|
||||
float adjustedAngle = uAngle - 1.5707963;
|
||||
float cosA = cos(adjustedAngle);
|
||||
float sinA = sin(adjustedAngle);
|
||||
vec2 rotated = vec2(
|
||||
offset.x * cosA - offset.y * sinA,
|
||||
offset.x * sinA + offset.y * cosA
|
||||
);
|
||||
|
||||
// Apply ellipse aspect ratio
|
||||
rotated.x /= uAspectRatio;
|
||||
|
||||
// Distance from center (elliptical)
|
||||
return length(rotated);
|
||||
}
|
||||
|
||||
// Calculate blur factor based on distance from focus
|
||||
float blurFactor(float dist) {
|
||||
// Smooth transition from in-focus to blurred
|
||||
float halfSize = uSize * 0.5;
|
||||
float transitionSize = halfSize * 0.5;
|
||||
// Falloff range scales with the falloff parameter
|
||||
float transitionSize = halfSize * uFalloff;
|
||||
|
||||
if (dist < halfSize) {
|
||||
return 0.0; // In focus region
|
||||
}
|
||||
|
||||
// Smooth falloff using smoothstep
|
||||
float normalizedDist = (dist - halfSize) / transitionSize;
|
||||
float normalizedDist = (dist - halfSize) / max(transitionSize, 0.001);
|
||||
return smoothstep(0.0, 1.0, normalizedDist) * uBlurAmount;
|
||||
}
|
||||
|
||||
|
|
@ -72,9 +102,24 @@ vec4 sampleBlurred(vec2 uv, float blur) {
|
|||
vec4 color = vec4(0.0);
|
||||
vec2 texelSize = 1.0 / uResolution;
|
||||
|
||||
// Blur direction perpendicular to focus line (adjusted for portrait texture rotation)
|
||||
float blurAngle = uAngle; // Already perpendicular after -90 adjustment in focusDistance
|
||||
vec2 blurDir = vec2(cos(blurAngle), sin(blurAngle));
|
||||
// For radial mode, blur in radial direction from center
|
||||
// For linear mode, blur perpendicular to focus line
|
||||
vec2 blurDir;
|
||||
if (uMode == 1) {
|
||||
// Radial: blur away from center
|
||||
vec2 center = vec2(uPositionX, uPositionY);
|
||||
vec2 toCenter = uv - center;
|
||||
float len = length(toCenter);
|
||||
if (len > 0.001) {
|
||||
blurDir = toCenter / len;
|
||||
} else {
|
||||
blurDir = vec2(1.0, 0.0);
|
||||
}
|
||||
} else {
|
||||
// Linear: blur perpendicular to focus line
|
||||
float blurAngle = uAngle;
|
||||
blurDir = vec2(cos(blurAngle), sin(blurAngle));
|
||||
}
|
||||
|
||||
// Scale blur radius by blur amount
|
||||
float radius = blur * 20.0;
|
||||
|
|
@ -90,7 +135,12 @@ vec4 sampleBlurred(vec2 uv, float blur) {
|
|||
}
|
||||
|
||||
void main() {
|
||||
float dist = focusDistance(vTexCoord);
|
||||
float dist;
|
||||
if (uMode == 1) {
|
||||
dist = radialFocusDistance(vTexCoord);
|
||||
} else {
|
||||
dist = linearFocusDistance(vTexCoord);
|
||||
}
|
||||
float blur = blurFactor(dist);
|
||||
|
||||
gl_FragColor = sampleBlurred(vTexCoord, blur);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue