오래된 게임에서 사라집니다. 알고리즘이 어떻게 도출되었는지 알아내는 데 도움이 필요합니다.


12

죄송합니다.이 질문은 약간 난해하지만, 제 머리에서 벗어날 수는 없습니다!

아케이드 게임 DoDonPachi (및 다른 많은 오래된 게임)에서 사용되는 페이드 알고리즘을보고 있습니다.

여기에 이미지 설명을 입력하십시오

파이썬 픽셀을 작성하여 몇 픽셀을 골라 페이드 기간 동안 추적했습니다. 다음은 대표적인 결과 샘플입니다. 각 그룹의 첫 번째 행은 시작 색상 값이고 이후의 각 행은 현재 프레임의 색상 값과 이전 프레임의 색상 값의 차이입니다.

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]

보시다시피 각 프레임의 각 색상 구성 요소에서 8 또는 9를 뺍니다. 또한 시작 색차 값이 각 색상 구성 요소마다 다르더라도 9는 항상 8 이후에 3 개의 프레임으로 나타납니다. 또한 각 색상 구성 요소는 임의의 나머지가 아닌 8 또는 9의 차이로 0 (즉, 검은 색)에 도달합니다. 이것은 8,8,8,9의 뺄셈 값 사이클이 절대로 깨지지 않음을 의미합니다! (이 알고리즘은 아마도 페이드의 마지막 프레임이 다른 프레임처럼 매끄 럽도록하기 위해 작성되었을 것입니다.)

자, 이것은 당황합니다. 내 계산에 따르면 프로세스를 반대로하면 즉 8,8,8,9주기를 취해 합산하여 29 프레임에서 가능한 모든 조합을 찾으려면 52 개의 고유 숫자 만 얻습니다. 그러나 이와 같이 각 색상 구성 요소는이 세트의 멤버입니다. 즉,이 페이드 알고리즘에 대해 색상을 구체적으로 선택했거나 (아마도) 페이드 알고리즘이 게임의 색상 팔레트를 중심으로 설계되었음을 의미합니다. 그러나 지구상에서 8,8,8,9를 취하고주기를 적절하게 이동하고 팔레트의 각 색상 구성 요소에서 숫자를 계속 빼면 모든 단일 색상에 대해 0에 도달한다는 것을 어떻게 알 수 있었습니까? ! 내가 놓친 수학적 트릭이 있어야합니다. 무엇입니까?


2
왜 알파 만 가지고 놀아 보지 않겠습니까? 이것이 페이드 인 / 아웃 애니메이션을위한 방법입니다.
DogDog

내 코드에서 알고리즘을 복제하려고 시도하지 않고 알고리즘이 파생 된 방법을 파악하려고합니다.
Archagon

나는 그것이 당신이 말한 것처럼 느낍니다. 색상은 시퀀스 8,8,8,9에 따라 선택되었습니다. 이 시퀀스를 감안하면 52 * 52 * 52 색상 중에서 선택할 수있었습니다. 흥미로운 점은 0에서 시작하여 시퀀스 8,8,8,9를 추가하면 255가됩니다. 그러면 흑백을 사용할 수 있습니다.
Luis Estrada

@Apoc : 페이드 아웃 스타일은 알파 페이드와 눈에 띄게 다릅니다. 각 색상 값이 초기 값의 백분율이 아닌 고정 숫자 (숫자 패턴)로 어떻게 내려가는 지보십시오. 이는보다 일반적인 방법보다 선호하는 환경이 있음을 의미합니다. 예를 들어 레트로 스타일.
AlbeyAmakiir

답변:


20

실제로 8-8-8-9 패턴에는 간단한 논리가 있습니다. 32 개의 강도 레벨 (구성 요소 당 5 비트) 만 사용하지만 구성 요소 당 8 비트 디스플레이에서 렌더링하려는 경우 자연스럽게 발생합니다.

5 비트 강도 레벨이 있고 8 비트로 확장하려는 경우를 고려하십시오. 가장 간단한 방법은 왼쪽으로 시프트하고 하위 3 비트를 0으로 남겨 두는 것입니다. 문제는 순수한 흰색으로 가지 않는 것입니다. 도달 할 수있는 가장 높은 강도 수준은 11111000 또는 248입니다. 따라서 8 비트 디스플레이의 전체 강도 범위를 사용하고 있지 않습니다.

실제로, 당신이하고 싶은 intensity8 = round(intensity5 * 255.0 / 31.0)것은 [0, 31] 범위를 [0, 255]로 재조정하는 것과 같은 계산 입니다. 그러나 부동 소수점 수학이나 나누기없이 이것을 달성하는 깔끔한 트릭이 있습니다. 하위 3 비트를 상위 3 비트와 동일하게 설정하십시오. 즉, 강도를 5 비트에서 8 비트로 변환하려면

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

그런 다음 11111의 강도는 11111111에 매핑되고 (31은 255에 매핑 됨) 중간 결과도 예를 들어 10000-> 10000100 (16-> 132)처럼 제정신이됩니다.

이 숫자 집합은 정확히 당신이 가진 것입니다. 첫 번째 예의 빨간색 구성 요소를 사용하면 다음이 있습니다.

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

하위 3 비트가 항상 상위 3 비트와 어떻게 동일한 지 확인하십시오. 비트 0과 비트 3이 동시에 플립 될 때 9의 차이가 발생합니다.

이 상황에서 5 비트 강도 레벨이 사용 된 이유가 확실하지 않습니다. 아마도 그것은 아케이드 머신의 하드웨어의 한계일까요? 5 비트 RGB 값은 15 비트이며 16 비트 워드에 잘 맞습니다. 어쨌든, 그것은 홀수 8-8-8-9 패턴을 설명합니다.


1
픽셀 당 16 비트를 '하이 컬러'라고합니다. (즉, 나는 그것에 대해 기억하는 모든 약의) en.wikipedia.org/wiki/High_color는
예인선

1
위키 피 디아를 통해 짧은 여행 후, 세가 새턴 ( en.wikipedia.org/wiki/Sega_Saturn#Video가 ) 15 비트 컬러 디스플레이 모드뿐만 아니라 게임 보이 어드밴스 (언급 en.wikipedia.org/wiki/Game_Boy_Advance를 )
예인선

1
훌륭합니다! 이제 모든 것이 이해됩니다. 감사합니다!
Archagon

게임의 색상은 16 비트 여야하고, 아티스트는 투명도를 희생하여 게임에서 더 많은 색상을 짜내고 RGBA 5551 색상 구성표를 만들려고했습니다.
Archagon

0

모드 13h 또는 256 색상 팔레트 페이딩을 살펴 봐야합니다. 그 당시에는 색상이 많지 않았지만 새 색상을 계산할 수 없었기 때문에 팔레트 전체가 엉망이었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.