Cách cắt bảng sprite AI không đều

Bạn yêu cầu mô hình tạo ảnh một chu kỳ đi bộ bốn nhân bốn và nhận về một PNG lớn. Nó trông như lưới. Nhưng không phải lưới. Cắt thành mười sáu hình chữ nhật bằng nhau sẽ cắt mất đầu chỗ này, mũi kiếm chỗ kia và khiến nửa số khung lệch tâm. Đây là lý do điều đó xảy ra và cách vẫn lấy được các khung dùng được từ sheet.

Vì sao sprite sheet AI không bao giờ nằm trên lưới hoàn hảo

Bảng sprite truyền thống được dựng bằng công cụ. Họa sĩ vẽ khung ở kích thước ô cố định và công cụ xuất đóng gói ở độ lệch pixel chính xác. Mọi ô giống nhau, mỗi sprite nằm trong khung đã biết và việc cắt chỉ là tính toán.

Trình tạo ảnh không làm vậy. Mô hình khuếch tán DALL·E, Midjourney, Stable Diffusion tạo một ảnh liên tục. Khi yêu cầu “bảng sprite hiệp sĩ đi bộ, lưới 4x4”, mô hình tạo thứ trông như một sprite sheet vì nó đã thấy hàng nghìn sheet như vậy. Nó bắt chước phong cách trực quan của lưới, chứ không tính ranh giới ô. Không có gì trong quá trình tạo buộc hàng ba phải bắt đầu đúng ở vị trí 384 pixel tính từ trên xuống.

Hệ quả thực tế nhất quán:

  • Khoảng cách thay đổi. Khoảng cách sprite thay từ vài pixel tới vài chục. Lệch thường tích lũy trái sang phải và trên xuống, nên khung dưới phải sai nhiều nhất.
  • Kích thước sprite không nhất quán. Nhân vật đang bước rộng hơn nhân vật đứng yên. Mô hình vẽ mỗi tư thế ở kích thước trông hợp lý, không thu vào một khung đồng nhất.
  • Nội dung lệch tâm. Ngay khi ô gần đều, sprite bên trong hiếm khi ở giữa, nên cắt lưới đúng vẫn cho khung rung khi phát.
  • Khung thiếu hoặc gộp. Đôi khi bố cục 4x4 chỉ có 15 sprite, hoặc hai tư thế chồng thành một khối.
  • Kích thước canvas lẻ. Đầu ra 1024x1024 chia cho ba cột là 341,33 pixel. Phải có làm tròn, và sai số làm tròn tích lũy.
Bảng sprite được tạo của hiệp sĩ giáp xanh, mười sáu tư thế có kích thước và độ lệch không nhất quán, khoảng cách có độ rộng khác nhau thay vì lưới đều
Bảng được tạo điển hình. Thoạt nhìn giống bố cục 4x4, nhưng tư thế khác kích thước, khoảng cách không đều và vài sprite lệch tâm trong ô tưởng tượng. Một khung thậm chí vượt cạnh canvas.

Vì sao cắt theo lưới cố định thất bại

Cắt lưới cố định có một giả định: ảnh là lưới ô bằng nhau. Chia rộng cho cột, cao cho hàng rồi cắt. Khi đúng, hoàn hảo và nhanh. Khi sai, lỗi không phải nhiễu ngẫu nhiên bỏ qua được. Mọi đường cắt sai vị trí và lỗi hiện đúng theo cách ảnh hưởng hoạt ảnh nhất.

Khung bị cắt mất bốn pixel ở trên không chỉ là vấn đề hình thức. Trong engine trò chơi, các khung được vẽ tại cùng điểm neo, nên sprite có nội dung thấp hơn bốn pixel ở khung hai so với khung một sẽ nhảy rõ khi phát. Người chơi coi đó là lỗi dù không gọi tên được. Sửa thủ công từng khung sau đó tốn thời gian hơn cắt đúng ngay từ đầu.

So sánh cạnh nhau: trái, đường lưới đỏ đều cắt qua nhiều nhân vật; phải, hộp xanh theo đúng đường bao từng nhân vật
Cùng sheet cắt hai cách. Lưới cố định theo toán, cắt đầu và vũ khí; phát hiện nội dung tìm phạm vi thật trước rồi cắt quanh.
Nguyên tắc thực dụng: nếu sheet đến từ trình tạo ảnh, hãy coi nó không đều cho đến khi kiểm chứng ngược lại. Nếu đến từ Aseprite, TexturePacker hoặc công cụ xuất spritesheet, cắt theo lưới cố định gần như chắc chắn đúng và bạn nên dùng.

Cách sửa: cắt theo nội dung, không theo tọa độ

Nếu lưới không cho vị trí sprite, pixel có thể. Trên nền trong suốt, mỗi pixel là sprite (alpha trên 0) hoặc nền (alpha 0). Phân biệt đó đủ tìm sprite không cần biết bố cục trước.

Cách phát hiện theo nội dung hoạt động

  1. Xác nhận nền trong suốt. Lấy mẫu pixel góc. Nếu hoàn toàn trong suốt, có thể dùng tự động phát hiện. Nếu trắng hoặc đồng màu, cần xóa nền trước.
  2. Tìm hàng và cột trống. Quét ảnh và ghi lại hàng pixel không có pixel đục nào, tương tự cho cột. Các dải trống đó là khoảng giữa sprite, bất kể vị trí.
  3. Cắt ở giữa mỗi khoảng cách. Khoảng cách là một vùng, không phải một đường. Cắt qua giữa vùng đó cho mỗi sprite bên cạnh nhiều không gian nhất và chấp nhận được một hoặc hai pixel khử răng cưa lạc ra ngoài.
  4. Cắt từng phần về hộp bao riêng. Khi đã tách riêng một mảnh, thu nó về hình chữ nhật nhỏ nhất chứa các điểm ảnh đục. Thao tác này bỏ phần đệm không đều khiến các ô trông không khớp.
  5. Kiểm tra kết quả rồi lặp lại. Lượt đầu thường để lại vấn đề: một phần vẫn chứa hai sprite vì chúng chạm nhau, hoặc một phần có nhiều khoảng trống hơn hẳn phần bên cạnh. Phân tích lại đầu ra rồi chia nhỏ hoặc cắt gọn lại sẽ phát hiện hầu hết vấn đề đó.

Đó là việc công cụ Magic Slice tab trong công cụ Cắt sprite sheet làm. Công cụ phát hiện nền trong suốt, tìm ranh giới sprite từ kênh alpha, rồi chạy tối đa ba lượt tinh chỉnh, kiểm tra từng phần cắt để tìm đệm thừa hoặc nhiều sprite và cắt lại khi cần. Độ nhạy thấp, trung bình hoặc cao kiểm soát mức độ mạnh của phát hiện ranh giới: tăng khi sprite gần chạm nhau, giảm khi một sprite có phần tách rời (khiên lơ lửng, hiệu ứng phép) bị chia ra.

Bảng sprite mười sáu nhân vật được tải trong công cụ cắt, có các đường ranh giới phát hiện vẽ đè; đường nằm trong khoảng trống trong suốt giữa nhân vật thay vì cách đều, nên các cột có chiều rộng khác nhau

Ranh giới phát hiện trên bảng

Kết quả cắt: 16 tệp sprite_1 đến sprite_16, mỗi tệp một nhân vật, kích thước như 204x257, 181x260 khác nhau

16 tệp, mỗi tệp cắt gọn

Ranh giới đi theo các dải trống giữa nhân vật thay vì lưới đều, nên các cột có kích thước khác nhau. Đọc kích thước dưới từng tệp xuất ở bên phải: chúng khác hàng chục pixel, đúng như lượt cắt sát cần tạo ra — và cũng chính là lý do bước thêm đệm sau đó quan trọng.

Nếu bảng có nền đặc

Phát hiện nội dung cần độ trong suốt. Nếu bảng có nền trắng, đen hoặc magenta phẳng, chạy qua xóa nền trước; công cụ của chúng tôi ở /remove-bg và hoạt động bằng cách lấy mẫu pixel góc rồi xóa mọi pixel đủ gần màu đó, sau đó xuất PNG trong suốt. Hãy làm việc này trước cắt, không phải sau: xóa nền một lần trên một sheet là một thao tác, còn làm trên mười sáu khung riêng là mười sáu cơ hội cho kết quả không nhất quán.

Chú ý những phần nền xuất hiện trong sprite. Nếu nhân vật áo trắng trên nền trắng, xóa theo góc sẽ tạo lỗ áo. Hãy yêu cầu màu nền không xuất hiện trên chủ thể: magenta sáng, xanh neon là lựa chọn cổ điển vì thế.

Đường lưới thủ công: dự phòng luôn hoạt động

Nhận diện tự động thất bại với một số bảng, và nên biết khi nào. Sprite chồng lấn hoặc chạm nhau không thể tách bằng quét dải trống vì không có dải trống. Bảng có bóng hoặc vùng sáng trải toàn canvas không có hàng hoàn toàn trong suốt. Bảng có nhân vật gồm các phần rời sẽ bị tách quá nhiều.

Với các trường hợp đó, tự kéo đường. Phần Thủ công & Có sẵn tab bắt đầu từ lưới mẫu từ 2x2 đến 6x6 — hoặc số hàng và cột tùy chỉnh của bạn, tối đa 20x20 — rồi cho phép kéo từng đường lưới đến vị trí đúng thực tế. Quy trình là:

  1. Chọn mẫu gần bố cục mong muốn nhất, chẳng hạn 4x4 cho sheet 16 khung, dù khoảng cách thực tế lệch.
  2. Kéo mỗi đường dọc vào khoảng trống trái hoặc phải. Làm từ trái sang phải để luôn chỉnh theo đường đã sửa.
  3. Làm tương tự với đường ngang, từ trên xuống.
  4. Phóng vào khung chật nhất — thường là tư thế rộng nhất — và xác nhận không có đường nào cắt qua nó.
  5. Xuất. PNG giữ trong suốt và phù hợp sprite; có JPG, WebP nhưng JPG bỏ hoàn toàn alpha.

Chỉnh tay nghe chậm nhưng không: bảng mười sáu khung có sáu đường trong, nên sáu lần kéo không mười sáu vùng cắt. So mở editor chọn từng khung, nhanh hơn rất nhiều.

Chuẩn bị khung hình cho game engine

Khi đã có các PNG riêng, có hai cách đưa vào engine: nhập dưới dạng các khung rời, hoặc đóng gói lại thành bảng sạch và đồng đều. Cách bạn muốn dùng tùy thuộc engine và dự án.

Unity

Với khung riêng, thả PNG vào dự án và đặt Texture Type thành Sprite (2D and UI), Sprite Mode thành Single. Đặt Filter Mode thành Point (no filter) và Compression thành None cho pixel art — lọc song tuyến tính trên sprite 32x32 chính là điều làm nó nhòe bệt. Đặt Pixels Per Unit khớp lưới, rồi chọn tất cả khung và kéo lên GameObject để Unity tự tạo Animation Clip.

Với bảng đóng gói lại, dùng Sprite Mode Multiple và Sprite Editor. Grid By Cell Size chỉ hoạt động nếu sheet đóng gói lại thực sự đồng đều — đó chính là điều việc đóng gói lại tạo ra và cũng chính là điều sheet AI gốc không có.

Godot

Trong Godot 4, thêm một AnimatedSprite2D, tạo một SpriteFrames tài nguyên, và dùng Add Frames from Sprite Sheet cho sheet đồng đều hoặc Add Frames from File(s) để nạp PNG riêng trực tiếp. Khung rời là cách dễ hơn ở đây vì trình nhập sprite sheet cần ô đều. Với pixel art, đặt lọc texture Nearest — theo từng node trong CanvasItem → Texture → Filter, hoặc toàn cục qua rendering/textures/canvas_textures/default_texture_filter thiết lập dự án.

Điểm neo và căn chỉnh

Bước bỏ rồi mất cả chiều debug. Cắt mỗi khung riêng thì cỡ khác, engine đặt giữa cùng gốc. Khung hai tay giang thêm rộng dịch tâm, nhân vật như trượt sau.

Sửa bằng thêm đệm cho mọi khung về cỡ chung, nội dung nhất quán, thường giữa ngang và sát đáy dọc để chân cố định. Chọn cỡ từ khung lớn nhất, làm tròn lên số tiện, đệm phần còn lại bằng trong suốt. Cắt rồi đệm nghe vòng vèo nhưng không: cắt bỏ đệm tùy ý của bộ tạo, đệm lại phần bạn kiểm soát.

Khắc phục lỗi

Phát hiện quá nhiều phần

Độ nhạy quá cao hoặc sprite có phần rời. Giảm độ nhạy để khoảng trong suốt nhỏ bên trong không bị coi là khe giữa sprite. Nếu không giúp, dùng đường thủ công: quét alpha luôn coi nhân vật cầm vật rời là hai sprite.

Phát hiện quá ít phần

Sprite chạm nhau hoặc ánh sáng nhạt nối khe. Tăng độ nhạy trước. Nếu thật sự chồng nhau, không phương pháp tự động nào tách được; tạo lại và yêu cầu rõ khoảng trống giữa khung, hoặc cắt thủ công.

Bảng sprite dày đặc gồm hai mươi nhân vật có các đường ranh giới được phát hiện vẽ đè lên; nhân vật sát nhau và chỉ tìm thấy vài đường ngang, nên nhiều hàng được coi là một dải

1. Độ nhạy quá thấp — tìm thấy ít ranh giới

Phát hiện thiếu: tám thay vì 20 tệp, một số dải rộng 1557 pixel chứa bốn nhân vật dính thay vì một

2. Có tám tệp thay vì hai mươi như dự kiến

Cận cảnh một dải đã xuất, cho thấy bốn nhân vật dính thành một tệp, không có cột hoàn toàn trong suốt ngăn chúng

3. Vì sao: không có cột trống rõ ràng giữa chúng

Cùng dải cắt lại độ nhạy cao, tách bốn tệp nhân vật với bốn chiều rộng khác

4. Tăng độ nhạy — bốn tệp

Dấu hiệu phát hiện thiếu và cách khắc phục. Số tệp ít hơn số khung trong sheet là dấu hiệu đặc trưng: quá trình quét không tìm được cột hoàn toàn trong suốt giữa các nhân vật liền kề nên coi chúng là một sprite. Tăng độ nhạy khiến công cụ cắt ở các khoảng trống hẹp hơn.

Khung có viền mờ nền cũ

Xóa nền để lại pixel cạnh bán trong suốt mang màu nền cũ. Xem hướng dẫn về PNG trong suốt và viền trắng để xem các cách sửa.

Hoạt ảnh giật trong engine

Gần như luôn là vấn đề điểm neo thay vì cắt. Xác nhận mỗi khung cùng kích thước và quy ước căn chỉnh, rồi kiểm tra điểm xoay sprite trong engine.

Không cách nào hiệu quả, bảng ảnh quá lộn xộn

Tạo lại ít tốn kém. Câu lệnh cải thiện ổn định: yêu cầu nền trong suốt rõ ràng, khoảng cách đều và kích thước nhân vật nhất quán, ít khung mỗi sheet hơn (3x3 dễ dùng hơn 6x6 nhiều), tạo từng tư thế riêng nếu hoạt ảnh quan trọng hơn sự tiện lợi.

Câu hỏi thường gặp

Tôi có thể tự động cắt bảng sprite nền trắng không?

Không trực tiếp bằng cách phát hiện dựa trên alpha, vì không có kênh alpha để đọc. Hãy xóa nền trước để tạo PNG trong suốt, rồi cắt. Có những kỹ thuật dựa trên màu phẳng thay vì alpha, nhưng chúng dễ sai hơn nhiều khi chủ thể có màu trùng với nền.

Cắt trong trình duyệt có mất chất lượng không?

Không, nếu bạn xuất PNG hoặc WebP. Cả hai đều không mất dữ liệu cho mục đích này và giữ nguyên kênh alpha. JPG mất dữ liệu và hoàn toàn không có alpha, nên xuất JPG vừa nén lại điểm ảnh vừa thay độ trong suốt bằng màu đặc. Với sprite, luôn xuất PNG.

Ảnh của tôi có được tải lên đâu khi dùng công cụ cắt không?

Không. Mọi xử lý trong trình duyệt qua Canvas API. Ảnh đọc thiết bị vào canvas, cắt, ghi thành tải xuống. Không gửi máy chủ, nên công cụ offline sau tải trang.

Nên yêu cầu trình tạo bao nhiêu khung?

Ít hơn bạn nghĩ. Chất lượng giảm nhanh khi số ô tăng vì mỗi sprite nhận ít chú ý và diện tích pixel. Bảng 3x3 hoặc 4x4 ở 1024x1024 cho khoảng 256 đến 340 pixel mỗi khung, đủ dùng. 6x6 cùng độ phân giải cho khoảng 170 và tư thế dễ nhòe vào nhau.

Thử sheet của bạn

Mở Cắt bảng sprite, thả bảng sprite vào và bắt đầu với thẻ Magic Slice. Nếu phát hiện tự động không đúng, chuyển sang Thủ công & Có sẵn rồi kéo các đường. Mọi thứ chạy cục bộ trong trình duyệt của bạn.

Mở Cắt bảng sprite