Một phương pháp tốt để tô màu họa tiết dựa trên bảng màu trong XNA là gì?


8

Tôi đã cố gắng làm việc trên một trò chơi với giao diện của trò chơi 8 bit bằng XNA, đặc biệt là sử dụng NES làm hướng dẫn.

NES có một bảng màu rất cụ thể và mỗi sprite có thể sử dụng tối đa 4 màu từ bảng màu đó. Làm thế nào tôi có thể mô phỏng điều này? Cách hiện tại tôi thực hiện điều này là tôi có một kết cấu với các giá trị được xác định đóng vai trò là chỉ mục cho một mảng màu tôi chuyển cho GPU. Tôi tưởng tượng phải có một cách tốt hơn thế này, nhưng có lẽ đây là cách tốt nhất?

Tôi không muốn đơn giản là đảm bảo rằng tôi vẽ mọi sprite với màu sắc phù hợp bởi vì tôi muốn có thể tự động thay đổi bảng màu. Tôi cũng không muốn thay đổi kết cấu trực tiếp bằng CPU.

Câu trả lời:


7

Tôi nghĩ những gì bạn đang làm là tốt.

Nếu bạn có nhiều hơn bốn màu, tôi có thể khuyên bạn nên đọc kết cấu phụ thuộc: Thay vì sử dụng giá trị của họa tiết để tìm kiếm một mảng màu (tôi giả sử bạn đang truyền những màu này dưới dạng tham số shader), bạn có thể sử dụng nó để tra cứu một màu trong kết cấu 1D khác chứa bảng màu của bạn.

Nhưng điều này có một số ý nghĩa về hiệu suất - và tôi nghĩ rằng nó giới hạn bạn trong PS 2.0.

(Có một số tối ưu hóa lén lút khác có thể xảy ra nếu bạn phải chuyển đổi bảng màu mỗi sprite và tất cả các lô bổ sung đang giết chết hiệu suất. Nhưng tôi tưởng tượng trong một trò chơi giống như NES, đây không phải là trường hợp.)

Tôi nghĩ điều có thể hữu ích trong tình huống của bạn là sử dụng đường dẫn nội dung XNA để có phiên bản màu của sprite có thể chỉnh sửa dễ dàng, kiểm tra nó chỉ sử dụng bốn màu, chuyển đổi thành kết cấu với bốn cấp độ thang độ xám (có thể sử dụng được shader), và có lẽ cũng xuất bảng màu gốc dọc theo kết cấu.

Các mẫu Câu lạc bộ Người sáng tạo cho đường ống nội dung có thể là một nơi tốt để bắt đầu.


1
+1 Đường ống nội dung đôi khi có thể là bạn của bạn. Sử dụng nó để lợi thế của bạn.
Michael Coleman

1

Sẽ là chậm để tạo một lớp tổng hợp có thể chứa tối đa 4 đối tượng là một trong mỗi màu cho sprite và kết hợp nó vào sprite được vẽ. Vì vậy, mỗi sprite là một tổng hợp của tối đa 4 sprite kết hợp và sau đó rút ra.

Sau đó, bạn có thể thay đổi 1 màu thông qua lớp đó và toàn bộ sprite sẽ thay đổi.

(lưu ý, tôi chưa thực hiện XNA nhưng điều này có thể làm nảy sinh một số ý tưởng với bạn.)


1

Nếu bạn không quan tâm đến hiệu suất bộ nhớ, bạn có thể lưu trữ các họa tiết của mình không bị nén sao cho các pixel có màu 0 là màu đỏ thuần, 1 là màu xanh lục thuần khiết, 2 là màu xanh lam thuần khiết và 3 là màu alpha thuần khiết.

Khi sắp kết xuất một sprite, hãy đặt hằng số shader pixel ma trận gồm bốn vectơ tương ứng với các màu 0, 1, 2, 3. Trong trình đổ bóng pixel, thực thi đoạn mã sau để tô màu lại sprite texel:

float4 unpaletted = tex2D( texture, uv );
float4 paletted = mul( unpaletted, paletteMatrix );

Điều này hoạt động vì khi một pixel có màu 0, nó có màu đỏ thuần và vì vậy nó sẽ kết thúc là

1 * palette[0] + 0 * palette[1] + 0 * palette[2] + 0 * palette[3]

hoặc là

1 * palette[0]

và tương tự áp dụng cho các màu 1, 2 và 3.

Nếu bạn quan tâm đến hiệu năng bộ nhớ, thì bằng mọi cách, hãy lưu trữ bảng màu NES của bạn dưới dạng kết cấu không nén 256x1 RGB, đặt lọc kết cấu cho hàng xóm gần nhất, lưu trữ các họa tiết của bạn dưới dạng kết cấu kênh đơn 8 bit không nén và thực hiện mã shader giống như thế này :

float palette_index = tex2D( texture, uv );
float4 color = tex1D( palette, palette_index * 255 );
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.