Desvanece-se em jogos mais antigos. Precisa de ajuda para descobrir como o algoritmo foi derivado

12

Desculpe, esta pergunta é um pouco esotérica, mas não consigo tirar isso da cabeça!

Estou analisando o algoritmo fade usado no jogo de arcade DoDonPachi (assim como em muitos outros jogos antigos):

insira a descrição da imagem aqui

Eu escrevi um script python para escolher alguns pixels e rastreá-los pela duração do desbotamento. Aqui está uma amostra representativa dos resultados. A primeira linha de cada grupo é o valor da cor inicial, enquanto cada linha subseqüente é a diferença entre o valor da cor do quadro atual e o valor da cor do quadro anterior.

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]

Como você pode ver, um 8 ou um 9 é subtraído de cada componente de cor em cada quadro. Além disso, um 9 sempre aparece três quadros após um 8, mesmo que o valor subtraído inicial seja diferente para cada componente de cor. Observe também que cada componente de cor atinge 0 (ou seja, preto) com uma diferença de 8 ou 9, e não um restante arbitrário. Isso significa que o ciclo de valor subtraído de 8,8,8,9 nunca é interrompido! (Esse algoritmo foi provavelmente escrito para garantir que o último quadro do desbotamento seja tão suave quanto os outros.)

Agora, isso me intriga. De acordo com meus cálculos, se você reverter o processo - ou seja, pegar o ciclo 8,8,8,9 e resumir para encontrar todas as combinações possíveis em 29 quadros -, você obtém apenas 52 números únicos. Mas, como acontece, cada componente de cor é um membro desse conjunto! Isso significa que as cores foram escolhidas especificamente para esse algoritmo de desvanecimento (improvável) ou que o algoritmo de desvanecimento foi projetado em torno da paleta de cores do jogo. Mas como diabos alguém poderia descobrir que, se você tirar 8,8,8,9, mudar o ciclo adequadamente e continuar subtraindo os números de cada componente de cor da sua paleta, você chegará a 0 para cada cor? ! Tem que haver algum truque matemático que estou perdendo. O que é isso?

Archagon
fonte
2
Por que não apenas brincar com o alfa? É assim que eu faço para animações fade-in / out.
DogDog 21/08/12
Não estou tentando replicar o algoritmo no meu próprio código, apenas tentando descobrir como ele foi derivado.
Archagon
Eu sinto que é o que você disse, as cores foram escolhidas com base na sequência 8,8,8,9. Dada essa sequência, eles foram capazes de escolher entre 52 * 52 * 52 cores. Uma observação interessante: se você começar com 0 e adicionar a sequência 8,8,8,9, chegará a 255. O que lhes permite usar preto e branco.
Luis Estrada
@ Apoc: O estilo do fade-out é visivelmente diferente do alpha fade. Veja como cada valor de cor diminui por um número fixo (padrão numérico) em vez de uma porcentagem do valor inicial? Isso significa que há circunstâncias em que você pode preferir usá-lo em vez de métodos mais comuns. Estilo retrô, por exemplo.
precisa saber é o seguinte

Respostas:

20

Na verdade, há uma lógica simples por trás do padrão 8-8-8-9. Surge naturalmente se você usar apenas 32 níveis de intensidade (5 bits por componente), mas quiser renderizar isso em uma exibição de 8 bits por componente.

Considere se você tem um nível de intensidade de 5 bits e deseja estendê-lo para 8 bits. A coisa mais simples a fazer seria apenas virar à esquerda e deixar os três bits baixos zero. O problema é que, então, não chega ao branco puro. O nível de intensidade mais alto que você pode atingir é 11111000 ou 248. Portanto, você não está usando a faixa de intensidade total da tela de 8 bits.

Realmente, o que você gostaria de fazer é um cálculo intensity8 = round(intensity5 * 255.0 / 31.0), para redimensionar o intervalo [0, 31] para [0, 255]. No entanto, há um truque interessante para fazer isso sem nenhuma matemática de ponto flutuante ou divisão: defina os três bits baixos iguais aos três bits altos. Ou seja, para converter a intensidade de 5 bits para 8 bits, você faria

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

Em seguida, uma intensidade de 11111 será mapeada para 11111111 (31 mapas para 255), e os resultados intermediários também farão algo sensato, por exemplo, 10000 -> 10000100 (16 -> 132).

Esse conjunto de números é exatamente o que você tem. Tomando o componente vermelho do seu primeiro exemplo, você tem:

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

Observe como os três bits baixos são sempre iguais aos três bits superiores. A diferença de 9 ocorre quando os bits 0 e 3 são invertidos ao mesmo tempo.

Não sei por que os níveis de intensidade de 5 bits teriam sido usados ​​nessa situação; talvez esse fosse o limite do hardware da máquina de arcade? É notável que um valor RGB de 5 bits seja 15 bits, o que se encaixa perfeitamente em uma palavra de 16 bits. De qualquer forma, isso explica o padrão 8-8-8-9 ímpar.

Nathan Reed
fonte
1
16 bits por pixel foi chamado de 'High Color'. (Isso é tudo o que me lembro) pt.wikipedia.org/wiki/High_color
rebocadores
1
Após uma rápida viagem pela wikipedia, a Sega Saturn ( pt.wikipedia.org/wiki/Sega_Saturn#Video ) menciona o modo de exibição em cores de 15 bits, bem como o GameBoy Advance ( pt.wikipedia.org/wiki/Game_Boy_Advance )
rebocadores
1
Isso é brilhante! Tudo faz sentido agora. Obrigado!
Archagon
O jogo deve ter cores de 16 bits, e os artistas provavelmente queriam extrair mais cores do jogo à custa da transparência, fornecendo um esquema de cores RGBA 5551.
Archagon
0

Você deve procurar o modo 13h ou 256 desbotamento da paleta de cores. Naquela época, você tinha tantas cores e o que fazia estava mexendo com toda a paleta, pois não era possível calcular novas cores que não estavam nela.

Deleteman
fonte