← Back to Guides & Stories
Tech & Privacy 5 min read August 28, 2026

Simulating Lens Curvature: Radial Barrel Distortion in GLSL

Simulating Lens Curvature: Radial Barrel Distortion in GLSL
Photo Study: Visual study: Simulating Lens Curvature

Physical camera lenses bend light rays through curved glass elements, naturally bowing straight lines outward near the frame boundaries while keeping the center tack-sharp. In digital pipelines, reproducing this optical barrel distortion without degrading resolution requires an inverse UV coordinate transformation in a GLSL fragment shader.

Optical Curvature Physics and Brown-Conrady Distortion

Physical lens elements bend light rays according to Snell's law of refraction, but real spherical glass surfaces deviate from ideal geometric pinhole projections. Light rays passing through the outer perimeter of a spherical lens element encounter a steeper angle of incidence than rays passing near the optical axis. Consequently, peripheral rays focus closer to the rear element than axial rays, a phenomenon known as spherical aberration. When an optical formula places the physical aperture stop in front of the lens elements, peripheral magnification decreases relative to central magnification. Straight architectural lines passing near the edge of the frame bow outward away from the center, producing classic barrel distortion. Optical engineers categorize this geometric deformation using the Brown-Conrady distortion model, expressing radial displacement as an odd-degree polynomial where radial deviation equals k1 times r cubed plus k2 times r to the fifth power. Vintage wide-angle prime lenses, such as the 28mm retrofocus lenses popular on 1970s rangefinders and SLRs or the compact meniscus lenses found in disposable point-and-shoots, typically exhibit between 1.5% and 4.0% negative barrel distortion. While modern mirrorless camera firmware silently flattens this geometry using embedded digital lens profiles, analog street and documentary photographers often prized this natural curvature. The slight peripheral bulging creates a subtle three-dimensional sense of volume, drawing the viewer's gaze inward toward the optical center while giving peripheral context an organic, tactile presence that clinical modern optics intentionally eliminate.

Inverse Coordinate Mapping in the Fragment Shader

Simulating optical curvature in a real-time graphics pipeline requires a fundamental shift in geometric thinking. In rasterization pipelines, fragment shaders cannot push input pixels to arbitrary new output coordinates; instead, each output fragment must pull its color by calculating which source texture coordinate maps to its screen position. This process demands an inverse mapping function. The GLSL fragment shader in RfCamera (located in shaders/film.frag) implements radial barrel distortion using a compact inverse quadratic formula where normalized coordinates undergo radial scaling.

The Barrel Distortion Kernel

The algorithm subtracts 0.5 from the normalized texture coordinates uv, shifting the origin to the optical center of the lens axis. The dot product dot(c, c) calculates the squared Euclidean distance r2 from that center, which is multiplied by 4.0 so that the midpoint of the frame edges corresponds to a normalized radius of 1.0. To produce outward barrel bulging on screen, the shader divides the centered coordinate c by (1.0 + k * r2). When the distortion factor k is positive, this division compresses the sampling coordinate closer to the center. Sampling source pixels from a smaller central radius pushes the displayed image outward toward the edges of the screen. At the optical center where c equals vec2(0.0), r2 equals 0.0, and the denominator simplifies exactly to 1.0. The central coordinates undergo zero displacement, preserving original sensor sharpness and focus where the subject is framed.

Lateral Chromatic Aberration and Channel Splitting

Real lenses suffer from chromatic dispersion because optical glass exhibits a wavelength-dependent refractive index, a physical property governed by Cauchy's dispersion equation. Short blue wavelengths around 450 nanometers refract more sharply than medium green wavelengths at 530 nanometers, while long red wavelengths at 650 nanometers bend least of all. In uncorrected or vintage optical designs, this dispersion manifests as lateral chromatic aberration: the three primary color planes focus at slightly different positions across the focal plane, producing red and cyan or blue and yellow fringing that expands outward toward the frame boundaries.

The shaders/film.frag shader simulates this physical lens defect by separating color channels along the radial distortion vector. After calculating the distorted coordinates duv, the shader constructs a direction vector pointing outward from the lens center. Multiplying this direction vector by the chromatic aberration uniform uChroma scales the color separation proportionally with radial distance. This mathematical formulation models optical reality: the optical center exhibits zero separation and pristine color alignment, while the extreme corners experience maximum channel splitting.

To execute the channel separation, the fragment shader samples three separate color coordinates. The red channel samples along the positive radial offset, the green channel samples at the undistorted baseline coordinate, and the blue channel samples along the negative radial offset. The sampleClamped helper function verifies that every sampled coordinate falls strictly within the normalized unit square between zero and one. When extreme distortion pushes a sampling coordinate outside the active image bounds, the function returns a clean black border rather than repeating edge pixels, preventing unsightly color smearing across the frame margin.

GPU Shader Pipeline Performance and Mobile Thermals

Mobile graphics processing requires balancing visual authenticity against strict thermal budgets and battery consumption limits. Mobile GPUs, including Apple's custom silicon and Qualcomm Adreno architectures, employ tile-based deferred rendering (TBDR) architectures optimized for high arithmetic throughput and fast texture filtering. In shaders/film.frag, the radial distortion and chromatic aberration calculations require only two dot products, five floating-point multiplications, one division, and three texture lookups per fragment. Because mobile GPUs contain dedicated hardware texture mapping units (TMUs), bilinear interpolation of non-integer UV coordinates occurs directly on the hardware samplers in a single clock cycle without CPU intervention. By avoiding multi-pass blur kernels or iterative coordinate solvers, the shader maintains a rock-solid 60 frames per second on high-refresh mobile displays while drawing less than 200 milliwatts of GPU power.

Memory bandwidth is minimized because the shader reads from a single source texture bound to the camera preview buffer, completely avoiding temporary offscreen framebuffer allocations during the rendering loop. Standard mobile post-processing pipelines frequently stutter because texture ping-ponging saturates the shared LPDDR memory bus; by performing coordinate warping and channel splitting in a single unified fragment pass, RfCamera leaves 95 percent of memory bandwidth free for real-time sensor ingestion and auto-exposure metering. This lightweight execution profile ensures that the smartphone chassis remains cool even during continuous outdoor shooting sessions in direct sunlight, avoiding thermal throttling that would otherwise drop preview framerates or stall camera responsiveness. The table below compares the computational overhead of this single-pass analytical shader against alternative optical distortion methods.

Distortion Technique Shader Passes Texture Fetches Corner Acutance GPU Cost (1080p)
Analytical GLSL (RfCamera) 1 Pass 3 Clamped Fetches Bilinear Preserved < 0.4 ms
Mesh Grid Warping 1 Pass 1 Fetch (Vertex Bound) Tessellation Dependent ~ 0.6 ms
Iterative Brown-Conrady 1 Pass 3 Fetches + 8 Solves Sub-pixel Accurate ~ 1.2 ms
Post-Process Displacement Map 2 Passes 4 Multi-Texture Fetches Interpolation Loss ~ 1.8 ms

Deterministic Pipeline Parity: From Viewfinder to Bake Isolate

A primary architectural challenge in mobile camera design is maintaining exact visual parity between the live interactive viewfinder and the saved final photograph. In RfCamera, widgets/film_view.dart renders the camera stream using Flutter's FragmentProgram API, binding the compiled shaders/film.frag shader directly to the live preview. However, saving the captured photograph cannot rely on capturing a compressed screenshot of the screen canvas, which would permanently downsample the 12-megapixel or 48-megapixel sensor capture to phone screen resolution. Instead, core/bake.dart delegates the full-resolution processing to a dedicated background Dart isolate using compute(). Inside this worker isolate, the application executes the identical mathematical sequence over the uncompressed capture buffer: the film stock color matrix, the analytical barrel distortion formula, lateral chromatic displacement, and blend modes for real scanned grain and dust plates.

Replaying the exact math ensures that edge curvatures, chromatic fringing widths, and focal falloff align perfectly between the preview frame and the high-resolution output file. Because the isolate runs in an independent memory space without garbage collection pauses affecting the UI thread, full-resolution JPEG baking completes in under 400 milliseconds. The photographer can immediately snap subsequent frames while earlier exposures process smoothly in the background without UI stutter. Disk serialization writes directly to standard JPEG files stored within the application's private documents directory, requiring no invasive storage permissions. Furthermore, because RfCamera declares zero internet permissions and operates strictly on-device, the entire optical simulation functions without remote servers, subscription authentications, or network telemetry.

RfCamera Team

RfCamera Editorial Team

Dedicated to pure analog 35mm film craft, optics, and 100% offline software.

Experience Real 35mm Film in Your Pocket

12 classic analog cameras, live fragment shaders, and mechanical acoustics. 100% offline & free.