← Back to Guides & Stories
Bảo mật & Công nghệ 5 phút đọc 28 Tháng 8, 2026

Mô Phỏng Độ Méo Thấu Kính Bằng Fragment Shader GLSL 60fps

Mô Phỏng Độ Méo Thấu Kính Bằng Fragment Shader GLSL 60fps
Photo Study: Nghiên cứu thị giác: Mô Phỏng Độ Méo Thấu Kính Bằng Fragment Shader GLSL 60fps

Fragment shader chạy trên bộ xử lý đồ họa di động cho phép mô phỏng độ cong quang học dạng thùng (barrel distortion) và tán sắc viền với tốc độ sáu mươi khung hình mỗi giây. Bằng cách tính toán lại tọa độ lấy mẫu vân bề mặt theo thời gian thực, khung ngắm tái hiện cảm giác quang học của ống kính rangefinder cổ điển mà không làm chậm trễ giao diện người dùng.

Mô hình quang học Brown-Conrady và phương trình biến dạng xuyên tâm

Các ống kính góc rộng cơ học trên máy ảnh film rangefinder cổ điển, tiêu biểu như dòng thấu kính đối xứng Biogon hay các ống kính phụ trợ mắt cá, luôn tồn tại một mức độ méo hình quang học nhất định ở rìa khung hình. Trong hiện tượng méo thùng (barrel distortion), độ phóng đại góc nhìn giảm dần khi khoảng cách từ trục quang học tới điểm ảnh tăng lên, khiến các đường thẳng nằm gần mép ảnh bị uốn cong ra phía ngoài. Mô hình toán học Brown-Conrady mô tả mối quan hệ giữa tọa độ không méo và tọa độ méo thông qua chuỗi đa thức bậc chẵn của bán kính xuyên tâm r. Tuy nhiên, nếu áp dụng trực tiếp phép biến đổi xuôi trong đồ họa thời gian thực, GPU sẽ gặp hiện tượng tạo khoảng trống điểm ảnh (pixel gaps) do nhiều tọa độ nguồn ánh xạ không đều vào bộ đệm khung hình.

Để khắc phục triệt để vấn đề này, fragment shader shaders/film.frag của RfCamera sử dụng phương pháp ánh xạ nghịch đảo (inverse mapping). Shader tính toán tọa độ chuẩn hóa UV từ vị trí điểm ảnh hiện tại, dịch tâm quang học về gốc tọa độ giữa màn hình c = uv - 0.5, sau đó tính bình phương bán kính r2 = dot(c, c) * 4.0. Tọa độ lấy mẫu thực tế được chia ngược cho một hàm suy giảm có trọng số biến dạng: c / (1.0 + k * r2) + 0.5, trong đó k là tham số biến dạng uDistort. Nhờ thuật toán nghịch đảo này, mọi điểm ảnh hiển thị trên màn hình điện thoại đều được xác định chính xác từ một tọa độ mẫu hợp lệ trên vân bề mặt đầu vào, loại bỏ hoàn toàn hiện tượng răng cưa hay vỡ hình ngay cả khi áp dụng mức độ méo thấu kính cực đại.

Cơ chế phân tách bước sóng quang học và tán sắc viền đa kênh

Hiện tượng tán sắc sắc sai (chromatic aberration) bắt nguồn từ định luật khúc xạ ánh sáng Snell và phương trình tán sắc Cauchy, khi chiết suất của thủy tinh quang học biến thiên tỷ lệ nghịch với bước sóng ánh sáng. Ánh sáng xanh lam có bước sóng ngắn (khoảng 450nm) luôn bị bẻ cong mạnh hơn ánh sáng đỏ có bước sóng dài (khoảng 650nm) khi đi qua cùng một độ cong thấu kính. Đối với các hệ thấu kính analog chưa được bù trừ hoàn hảo bằng các thấu kính tiêu sắc (achromatic doublet), sự chênh lệch độ phóng đại quang học giữa các dải màu thể hiện rõ nhất ở rìa bức ảnh dưới dạng các viền đỏ và lục lam tách rời nhau.

Trong tệp shader GLSL, hiệu ứng tán sắc bên (lateral chromatic aberration) được tái lập bằng cách tách rời ba kênh màu đỏ, xanh lục và xanh lam khi thực hiện lệnh lấy mẫu texture. Shader xác định hướng phân tách quang học qua vectơ xuyên tâm dir = duv - 0.5 tính từ tâm khung hình. Độ lệch không gian off được tính bằng tích của vectơ hướng với hệ số phân tách uChroma chia cho chiều rộng khung hình: off = dir * (uChroma / max(uSize.x, 1.0)) * 2.0. Kênh màu đỏ được lấy mẫu tại vị trí duv + off, kênh màu xanh lam được lấy mẫu ngược hướng tại duv - off, trong khi kênh màu xanh lục đóng vai trò gốc tọa độ chuẩn tại duv. Vì giá trị vectơ dir tại tâm quang học bằng 0, độ tán sắc ở khu vực trung tâm khung hình hoàn toàn bằng không và tăng dần tuyến tính ra bốn góc, mô phỏng chân thực bản chất vật lý của thấu kính thủy tinh thật.

Tối ưu hóa pipeline 60fps và xử lý giới hạn biên UV

Khi áp dụng phép biến dạng hình học uốn cong tọa độ UV, các điểm ảnh nằm sát mép khung hình sẽ bị kéo vào bên trong, để lại các vùng tọa độ nằm ngoài dải hợp lệ từ 0.0 đến 1.0. Nếu không xử lý cẩn thận, hành vi mặc định của bộ lấy mẫu OpenGL ES hoặc Vulkan sẽ lặp lại viền vân bề mặt (texture clamping or repeating), tạo ra các sọc màu kéo dài rất mất thẩm mỹ quanh mép màn hình. Hàm sampleClamped trong shader giải quyết dứt điểm trường hợp này bằng cách kiểm tra biên tọa độ: bất kỳ giá trị UV nào rơi ra ngoài phạm vi 0.0 đến 1.0 đều được gán ngay giá trị màu đen hoàn toàn vec4(0.0, 0.0, 0.0, 1.0), tạo ra đường viền cong cơ học sắc nét tựa như vòng đệm kim loại bên trong buồng tối máy ảnh.

Để duy trì tốc độ ổn định sáu mươi khung hình mỗi giây trên các thiết bị di động có cấu hình phổ thông, fragment shader được thiết kế để giảm thiểu tối đa băng thông bộ nhớ và số phép tính dấu phẩy động. Đoạn mã kiểm tra điều kiện nếu tham số uChroma nhỏ hơn hoặc bằng 0.001 cho phép bỏ qua hoàn toàn hai lượt lấy mẫu bổ sung khi chế độ tán sắc được tắt, giảm tải tức thì 66% số lần truy xuất bộ nhớ vân bề mặt. Vì biến uChroma là một uniform bất biến trong suốt quá trình vẽ khung hình, toàn bộ các đơn vị xử lý luồng (warp hoặc wavefront) trên vi kiến trúc GPU đều thực thi cùng một nhánh lệnh rẽ, tránh được hiện tượng phân nhánh luồng (warp divergence) làm tụt xung nhịp đồ họa. Khi chạy dưới động cơ đồ họa Impeller của Flutter, mã nguồn GLSL được biên dịch tĩnh thành mã nhị phân SPIR-V hoặc Metal Shading Language, đảm bảo thời gian dựng hình cho mỗi khung ngắm luôn dưới mốc tám mili-giây.

So sánh hiệu năng giữa tính toán GPU thời gian thực và xử lý hậu kỳ CPU

Kiến trúc phần mềm của RfCamera phân tách rành mạch giữa quá trình hiển thị tương tác trên khung ngắm và quá trình xuất ảnh độ phân giải cao ra bộ nhớ thiết bị. Khung ngắm cần độ phản hồi tức thì với độ trễ dưới mười sáu mili-giây nên việc giao phó toàn bộ khâu biến dạng cho GPU thông qua fragment shader là lựa chọn tối ưu nhất. Tuy nhiên, khi người dùng nhấn nút chụp, cảm biến máy ảnh thu nhận tệp ảnh tĩnh có kích thước từ mười hai đến bốn mươi tám megapixel, vượt xa năng lực lưu giữ kết cấu một lượt của nhiều chip đồ họa tích hợp trên điện thoại giá rẻ.

Tiêu Chí Kỹ Thuật Fragment Shader (Live Viewfinder) Isolate Bake (Lưu Tệp JPEG)
Phần cứng thực thi GPU (OpenGL ES / Vulkan / Metal) CPU đa nhân (Luồng nền isolate Dart)
Tần số và độ trễ 60 khung hình/giây (dưới 16.6ms) Bất đồng bộ (300ms đến 800ms một ảnh)
Độ phân giải xử lý Khung hình hiển thị (1080p đến 1440p) Độ phân giải gốc cảm biến (12MP đến 48MP)
Tác động luồng giao diện Không ảnh hưởng (Dựng hình GPU độc lập) Hoàn toàn cách ly qua compute()

Nếu ép GPU nạp một bức ảnh bốn mươi tám megapixel vào bộ nhớ kết cấu để chạy shader, hệ điều hành rất dễ kích hoạt cơ chế dọn dẹp bộ nhớ (Out Of Memory killer) làm sập ứng dụng. Do đó, logic xử lý của ứng dụng chuyển toàn bộ công việc xuất ảnh cuối cùng sang một isolate nền của Dart thông qua hàm compute() trong tệp core/bake.dart. Isolate nền đọc mảng byte thô của tệp ảnh tĩnh, tự tính toán phép nội suy song tuyến (bilinear interpolation) cho từng điểm ảnh tương ứng với công thức biến dạng quang học, sau đó phủ các lớp hạt phim và bụi xước được lấy từ các bản quét phim analog thực tế. Quá trình này diễn ra hoàn toàn độc lập với luồng hiển thị chính (UI thread), đảm bảo khung ngắm không bao giờ bị giật hay đứng hình trong khi tấm ảnh hoàn chỉnh đang được ghi trực tiếp vào thư mục dữ liệu cục bộ của ứng dụng.

Đảm bảo tính nhất quán giữa khung ngắm trực tiếp và tệp JPEG đầu ra

Một nguyên tắc kiến trúc xuyên suốt trong RfCamera là tính nhất quán giữa những gì người dùng nhìn thấy trên màn hình và kết quả tệp JPEG thu được. Để đảm bảo điều này, lớp dữ liệu BakeRequest đóng gói chính xác các giá trị số thực từ đối tượng FilmEffect, bao gồm hệ số méo uDistort, độ tán sắc uChroma và ma trận màu sắc, rồi gửi sang isolate xử lý mà không làm sai lệch bất kỳ tham số nào. Trình tự áp dụng các lớp hiệu ứng trong mã nguồn Dart của isolate tái lập đúng thứ tự phản ứng quang học ngoài thực tế: ánh sáng đi qua thấu kính trước (chịu méo và tán sắc), sau đó rọi vào bề mặt phim (tạo hạt nhũ tương), và cuối cùng bụi bẩn bám trên mặt kính quét được phủ lên trên cùng.

Toàn bộ chu trình tính toán này vận hành ngoại tuyến và không đòi hỏi quyền truy cập mạng Internet. Ứng dụng không khai báo quyền android.permission.INTERNET trong tệp cấu hình xuất bản, không gửi bất kỳ gói tin thống kê nào về máy chủ từ xa, và lưu ảnh trực tiếp trong thư mục ứng dụng mà không cần xin quyền đọc ghi thẻ nhớ ngoài. Bằng cách loại bỏ các tác vụ mạng nền và đồng bộ đám mây, chu kỳ xử lý của vi xử lý và chip đồ họa được dành trọn vẹn cho việc nội suy điểm ảnh và tạo chất màu quang học thuần khiết.

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.