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):
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?
Respostas:
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ê fariaEm 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:
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.
fonte
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.
fonte