Làm mờ dần trong các trò chơi cũ. Cần một số trợ giúp để tìm ra cách thuật toán được bắt nguồn


12

Xin lỗi, câu hỏi này hơi bí truyền, nhưng tôi không thể lấy nó ra khỏi đầu!

Tôi đang xem thuật toán fade được sử dụng trong trò chơi arcade DoDonPachi (cũng như nhiều game cũ khác):

nhập mô tả hình ảnh ở đây

Tôi đã viết một kịch bản python để chọn ra một vài pixel và theo dõi chúng trong suốt thời gian mờ dần. Đây là một mẫu đại diện của kết quả. Hàng đầu tiên của mỗi nhóm là giá trị màu bắt đầu, trong khi mỗi hàng tiếp theo là sự khác biệt giữa giá trị màu của khung hiện tại và giá trị màu của khung trước đó.

Starting Value: (132, 66, 189)
Frame 1:    [9, 9, 8]
Frame 2:    [8, 8, 8]
Frame 3:    [8, 8, 8]
Frame 4:    [8, 8, 9]
Frame 5:    [9, 9, 8]
Frame 6:    [8, 8, 8]
Frame 7:    [8, 8, 8]
Frame 8:    [8, 8, 9]
Frame 9:    [9, 0, 8]
Frame 10:   [8, 0, 8]
Frame 11:   [8, 0, 8]
Frame 12:   [8, 0, 9]
Frame 13:   [9, 0, 8]
Frame 14:   [8, 0, 8]
Frame 15:   [8, 0, 8]
Frame 16:   [8, 0, 9]
Frame 17:   [0, 0, 8]
Frame 18:   [0, 0, 8]
Frame 19:   [0, 0, 8]
Frame 20:   [0, 0, 9]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 8]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 0]
Frame 25:   [0, 0, 0]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (132, 0, 0)
Frame 1:    [9, 0, 0]
Frame 2:    [8, 0, 0]
Frame 3:    [8, 0, 0]
Frame 4:    [8, 0, 0]
Frame 5:    [9, 0, 0]
Frame 6:    [8, 0, 0]
Frame 7:    [8, 0, 0]
Frame 8:    [8, 0, 0]
Frame 9:    [9, 0, 0]
Frame 10:   [8, 0, 0]
Frame 11:   [8, 0, 0]
Frame 12:   [8, 0, 0]
Frame 13:   [9, 0, 0]
Frame 14:   [8, 0, 0]
Frame 15:   [8, 0, 0]
Frame 16:   [8, 0, 0]
Frame 17:   [0, 0, 0]
Frame 18:   [0, 0, 0]
Frame 19:   [0, 0, 0]
Frame 20:   [0, 0, 0]
Frame 21:   [0, 0, 0]
Frame 22:   [0, 0, 0]
Frame 23:   [0, 0, 0]
Frame 24:   [0, 0, 0]
Frame 25:   [0, 0, 0]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (165, 156, 222)
Frame 1:    [9, 8, 8]
Frame 2:    [8, 8, 8]
Frame 3:    [8, 8, 8]
Frame 4:    [8, 9, 9]
Frame 5:    [9, 8, 8]
Frame 6:    [8, 8, 8]
Frame 7:    [8, 8, 8]
Frame 8:    [8, 9, 9]
Frame 9:    [9, 8, 8]
Frame 10:   [8, 8, 8]
Frame 11:   [8, 8, 8]
Frame 12:   [8, 9, 9]
Frame 13:   [9, 8, 8]
Frame 14:   [8, 8, 8]
Frame 15:   [8, 8, 8]
Frame 16:   [8, 9, 9]
Frame 17:   [9, 8, 8]
Frame 18:   [8, 8, 8]
Frame 19:   [8, 8, 8]
Frame 20:   [8, 0, 9]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 8]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 9]
Frame 25:   [0, 0, 8]
Frame 26:   [0, 0, 8]
Frame 27:   [0, 0, 8]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (156, 90, 206)
Frame 1:    [8, 8, 8]
Frame 2:    [8, 8, 9]
Frame 3:    [8, 8, 8]
Frame 4:    [9, 9, 8]
Frame 5:    [8, 8, 8]
Frame 6:    [8, 8, 9]
Frame 7:    [8, 8, 8]
Frame 8:    [9, 9, 8]
Frame 9:    [8, 8, 8]
Frame 10:   [8, 8, 9]
Frame 11:   [8, 8, 8]
Frame 12:   [9, 0, 8]
Frame 13:   [8, 0, 8]
Frame 14:   [8, 0, 9]
Frame 15:   [8, 0, 8]
Frame 16:   [9, 0, 8]
Frame 17:   [8, 0, 8]
Frame 18:   [8, 0, 9]
Frame 19:   [8, 0, 8]
Frame 20:   [0, 0, 8]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 9]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 8]
Frame 25:   [0, 0, 8]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Như bạn có thể thấy, 8 hoặc 9 bị trừ khỏi từng thành phần màu trong mỗi khung. Hơn nữa, 9 luôn xuất hiện ba khung hình sau 8, mặc dù giá trị trừ bắt đầu là khác nhau đối với mỗi thành phần màu. Cũng lưu ý rằng mỗi thành phần màu đạt 0 (nghĩa là màu đen) với chênh lệch 8 hoặc 9, không phải là phần còn lại tùy ý. Điều này có nghĩa là chu kỳ giá trị bị trừ là 8,8,8,9 không bao giờ bị phá vỡ! (Thuật toán này có thể được viết để đảm bảo rằng khung hình mờ cuối cùng trơn tru như các thuật toán khác.)

Bây giờ, điều này đánh đố tôi. Theo tính toán của tôi, nếu bạn đảo ngược quy trình - nghĩa là thực hiện chu trình 8,8,8,9 và tổng hợp lại để tìm tất cả các kết hợp có thể có trong 29 khung - bạn chỉ nhận được 52 số duy nhất. Nhưng khi nó xảy ra, mỗi thành phần màu là một thành viên của bộ này! Điều này có nghĩa là các màu được chọn riêng cho thuật toán mờ dần (không chắc) hoặc thuật toán mờ được thiết kế xung quanh bảng màu của trò chơi. Nhưng làm thế nào trên trái đất ai đó có thể nhận ra rằng nếu bạn lấy 8,8,8,9, thay đổi chu kỳ một cách thích hợp và tiếp tục trừ các số từ mỗi thành phần màu trong bảng màu của bạn, cuối cùng bạn sẽ đạt 0 cho mỗi màu? ! Có một số mẹo toán học mà tôi đang thiếu. Nó là gì?


2
Tại sao không chơi với alpha? Đó là cách tôi làm cho hình ảnh động mờ dần.
DogDog

Tôi không cố gắng sao chép thuật toán trong mã của riêng mình, chỉ cố gắng tìm hiểu làm thế nào nó được bắt nguồn.
Archagon

Tôi cảm thấy như đó là những gì bạn nói, màu sắc được chọn dựa trên chuỗi 8,8,8,9. Với trình tự đó, họ có thể chọn từ 52 * 52 * 52 màu. Một lưu ý thú vị, nếu bạn bắt đầu từ 0 và thêm chuỗi 8,8,8,9, bạn sẽ nhận được 255. Điều này cho phép họ sử dụng màu đen và trắng.
Luis Estrada

@Apoc: Phong cách fade-out khác biệt rõ rệt với alpha fade. Xem làm thế nào mỗi giá trị màu đi xuống theo một số cố định (mẫu số) thay vì tỷ lệ phần trăm của giá trị ban đầu? Điều này có nghĩa là có những trường hợp bạn có thể thích sử dụng nó hơn các phương pháp phổ biến hơn. Phong cách retro, ví dụ.
AlbeyAmakiir

Câu trả lời:


20

Trên thực tế, có một logic đơn giản đằng sau mẫu 8-8-8-9. Nó phát sinh một cách tự nhiên nếu bạn chỉ sử dụng 32 mức cường độ (5 bit cho mỗi thành phần), nhưng muốn hiển thị mức đó trên màn hình 8 bit cho mỗi thành phần.

Xem xét nếu bạn có mức cường độ 5 bit và muốn mở rộng thành 8 bit. Điều đơn giản nhất để làm là chỉ cần dịch chuyển sang trái và để ba bit thấp bằng không. Vấn đề là, sau đó nó không đi đến màu trắng tinh khiết. Mức cường độ cao nhất bạn có thể đạt tới là 11111000 hoặc 248. Vì vậy, bạn không sử dụng phạm vi cường độ đầy đủ của màn hình 8 bit.

Thực sự, những gì bạn muốn làm là một phép tính như thế intensity8 = round(intensity5 * 255.0 / 31.0), để bán lại phạm vi [0, 31] thành [0, 255]. Tuy nhiên, có một mẹo gọn gàng để thực hiện điều này mà không có bất kỳ phép toán dấu phẩy động hay phép chia nào: đặt ba bit thấp bằng ba bit cao. Nghĩa là, để chuyển đổi cường độ từ 5 bit sang 8 bit bạn sẽ làm

intensity8 = (intensity5 << 3) | (intensity5 >> 2);

Sau đó, cường độ 1111 sẽ ánh xạ tới 11111111 (31 bản đồ thành 255) và kết quả trung gian cũng sẽ làm điều gì đó lành mạnh, ví dụ 10000 -> 10000100 (16 -> 132).

Bộ số này chính xác là những gì bạn có. Lấy thành phần màu đỏ của ví dụ đầu tiên của bạn, bạn có:

132    10000100
123    01111011
115    01110011
107    01101011
 99    01100011
 90    01011010
 82    01010010
 74    01001010

Lưu ý làm thế nào ba bit thấp luôn luôn bằng ba bit trên cùng. Sự khác biệt của 9 xảy ra khi cả bit 0 và bit 3 lật cùng một lúc.

Tôi không chắc tại sao mức cường độ 5 bit sẽ được sử dụng trong tình huống này; có lẽ đó là giới hạn của phần cứng của máy arcade? Đáng chú ý là giá trị RGB 5 bit là 15 bit, rất phù hợp với từ 16 bit. Trong mọi trường hợp, điều đó giải thích mô hình 8-8-8-9 lẻ.


1
16 bit cho mỗi pixel được gọi là 'Màu cao'. (Đó là về tất cả những gì tôi nhớ về nó) vi.wikipedia.org/wiki/High_color
kéo

1
Sau chuyến đi nhanh qua wikipedia, Sega Saturn ( en.wikipedia.org/wiki/Sega_Saturn#Video ) đề cập đến chế độ hiển thị màu 15 bit, cũng như GameBoy Advance ( en.wikipedia.org/wiki/Game_Boy_Advance )
kéo dài

1
Thật tuyệt vời! Điều này thật ý nghĩa ngay lúc này. Cảm ơn bạn!
Archagon

Trò chơi phải có màu 16 bit và các nghệ sĩ có thể muốn thu được nhiều màu hơn từ trò chơi của họ với chi phí trong suốt, tạo ra một bảng màu RGBA 5551.
Archagon

0

Bạn nên nhìn vào chế độ 13h hoặc mờ dần 256 bảng màu. Trước đó, bạn có rất nhiều màu sắc và những gì bạn đã làm, đang loay hoay với toàn bộ bảng màu, vì bạn không thể tính toán các màu mới không có trong đó.

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.