This content is not available in your language... So if you don't understand the language... well, at least you can appreciate the pictures of the post, right?
This content is not available in your language... So if you don't understand the language... well, at least you can appreciate the pictures of the post, right?
Em 07/06/2021 eu decidi que eu iria fazer um banner para usar no Discord, graças a datamining do cliente e como algumas pessoas da equipe do Discord já estavam usando a funcionalidade, eu já conseguia ver a resolução e como os banners ficariam nos perfis da pessoa, então ideias já começaram a serem boladas na minha cabeça para fazer um banner incrível!
Para criar a animação, em vez de eu usar After Effects ou até mesmo o Photoshop, eu decidi programar a animação em Kotlin, ou seja, cada frame é gerada usando a API de gráficos do Java! Enquanto eu nunca usei o After Effects, eu já tinha tentado usar o MAGIX Vegas para fazer o banner do SparklyPower antes, e os motivos para eu ter decidido fazer usando programação foram porque...
Então eu decidi fazer programaticamente mesmo, pelo ou menos se eu falar que um pixel deve ser de tal jeito, ele REALMENTE vai ser de tal jeito!
E se você quiser ver as mudanças que eu fiz no codificador como também a classe que cria as frames intermediárias, aqui estão elas!
Uma coisa que eu gosto de fazer é ver cada frame manualmente, para poder apreciar todos os detalhes que o banner tem! Aqui tem todas as frames que eu acho interessantes e legais para serem observadas. :lori_flushed:
Quando comecei a fazer o banner, eu estava usando o ezgif para a criação e a otimização da GIF, exportando as frames em formato PNG para uma pasta e enviando todas elas para o website.
Eu queria fazer um banner igual a página inicial do meu website: Um fundo azul com o meu banner balançando lentamente no fundo, algo simples, mas legal de ficar observando.
Fail. Não se assuste com esse círculo preto no banner! Ele existe pois ter partes estáticas economizam espaço na GIF, só que eu ainda não sabia o motivo disso economizar espaço.
Após ter terminado isso, eu pensei em colocar a Loritta correndo e depois pare, olhando para a câmera, até que uma transição de "swoop" empurrasse ela e fizesse ela cair, assim recomeçando o banner. Assim o banner ficaria bem mais interessante do que apenas "um logo girando"
E logo depois de ter feito isso eu resolvi mudar a ideia para que depois da transição mudasse para uma nova cena completamente diferente, assim dando um efeito mais de "uau!" ao ver o banner! E a nova cena seria a batalha contra o Asriel Dreemurr, um dos meus personagens favoritos.
Qual é o limite de um banner? Quantas coisas será que eu posso colocar até chegar em 10MBs? Eu não queria me contentar a um fade out após a batalha e voltar para o começo da GIF, então eu comecei a mudar a minha ideia para tentar inserir o máximo de referências e coisas que eu gosto no banner, assim mudando o meu objetivo de um banner simples para o meu perfil para fazer uma GIF que tivesse 60 segundos de duração, rodando a 30 frames por segundo e que fosse menor que 10MBs (que é o limite de tamanho para um banner no Discord)... não deve ser tão difícil, né?
...GIFs nunca foram feitas para você reproduzir vídeos, mesmo que hoje em dia várias pessoas usam GIFs para isso. Originalmente GIFs foram feitas para webcomics, já que as alternativas na época, como bmp (que não tem compressão) e jpg (é um formato para fotos, e ele perde a qualidade pois é lossy) eram inviáveis para isso, e eu sabia disso! Afinal, não era a primeira vez que eu mexia com GIFs.
Mas mesmo assim queria encarar esse desafio, eu gosto de tentar empurrar as coisas que eu faço ao limite, para impressionar os espectadores e mostrar o que é possível e atingir limites que você jamais esperava que era possível! Algo parecido com o que as pessoas que participam de demoscenes fazem, tanto que o Overdrive e o Overdrive 2 foram inspirações para o meu banner, mesmo que não tenha nenhuma similaridade entre o meu banner e a apresentação incrível do Overdrive.
Enquanto o banner ainda estava bem barebones, eu já estava bolando algumas ideias sobre o que poderia ter no banner.
Na seção da Loritta, a mensagem do chat poderia aparecer "te amo Lori" ou algo do gênero
No SparklyPower, pode ter o IP do servidor na parte de baixo igual como é na tela do Minecraft
E aí a Lori pula para lá, sai correndo para a direita, vai para palmtree panic e acaba pulando em uma mola para cima
E aí vai para aquela cena do vegeta e como não tem um jeito bom de "sair" dessa cena, poderia ficar em uma tela estática e depois uma seção de "interrompemos seu programa para mostrar fan arts da Lori"
Talvez após sair dessa seção, iria para uma seção na Lori no The Sims, e aí ela ligaria a TV (que substituiria a cabeça dela por um desenho dela mesmo) e na TV poderia ter uma seção com vídeos de YouTubers (?), até que ela decida dormir no sofá e vá para a seção do Asriel
Talvez até uma seção com o 2gh?
E no final depois daquela seção do Asriel, o chat de expandiria para mostrar um terminal, aonde no canto teria a cara da Lori fingindo que está "hackeado" o sistema, que na verdade só faz ela reiniciar a animação usando "java -jar anim.jar"
Lori correndo até o final da tela, para onde será que a Loritta está correndo?
Para fazer esse percurso da Loritta pulando, eu tive que implementar um sistema de física bem básico, bem similar a jogos de plataforma 2D, tanto que durante o "game loop" é aplicado uma força X na Loritta, para fazer ela andar para fora da tela, a animação dela é interpolada entre a posição antiga X posição nova, assim permitido que possa alterar o frame rate do gerador sem que quebre toda a animação! Sistema bem similar ao Fix Your Timestep!.
Na parte onde mostra Palmtree Panic, a ideia original seria que a Loritta pisasse em uma mola que jogaria ela para cima, que aí teria a transição para a parte aonde o Vegeta aparece, já que no vídeo original a câmera está sendo movida para cima, então combinaria perfeitamente! Só que no final eu decidi fazer que a Loritta entre em um anel gigante, que, no Sonic 1/Sonic CD, te leva a um Special Stage.
Também no "game loop" foi programado que em um "game tick" específico a Loritta tenha uma força Y aplicada para que ela pule! O game tick acontece a cada X segundos percorridos na frame.
A GIF anterior é bem maior que a segunda, mesmo que a segunda tenha mais coisas, como isso acontece? Isso é usando uma mágica chamada compressão lossy, algo que o ezgif permite fazer usando o Gifsicle.
Na época eu não entendia o motivo de deixar a GIF parecendo que está "suja" diminuiria o espaço dela, pensando apenas que era alguma magia dos deuses que diminuia a GIF, mas em próximos "episódios" do banner acabei descobrindo o motivo...
Adicionado um fundo na seção do SparklyPower, simulando uma casa de madeira que depois tem uma transição para Palmtree Panic.
Agora com uma transição da seção do Vegeta para uma nova! Com uma referência a tela de vitória de um special stage do Sonic 3!
Dá para perceber que algo está errado na Loritta quando ela é empurrada para fora da tela no começo, já que ela fica aumentando e diminuindo de tamanho! O motivo para isso ter acontecido é que quando a imagem dela era rotacionada, o tamanho do canvas dela aumentava, já que não não para você girar uma imagem quadrada em 45° sem que corte parte dela, só que o código que redimensionava a imagem dela não levava isso em consideração, fazendo ela ficar com esse efeito estranho de aumentar e diminuir de tamanho.
Nessa fase, eu queria fazer uma transição do "Loritta got a Chaos Pudding" para outra cena aonde a Loritta estaria dentro do The Sims 1, liga a televisão e depois vai jogar no computador, assim continuando para a próxima cena.
O problema é que a GIF tem tantas frames, que o ezgif não aceitava tantas frames para fazer uma GIF... E é essa uma das maiores desvantagens de ferramentas 100% online e algo que sinceramente eu fiquei sem ideias de como resolver o problema, talvez era a hora de jogar a toalha e decidir que eu estava sendo ambicioso demais...
Mas se o ezgif conseguia fazer e otimizar a minha GIF, então deve ter algum jeito de fazer alguma coisa localmente, né? Eu resolvi usar o gifsicle, uma das ferramentas que o próprio ezgif indica que usam no website para fazer as GIFs, mas o resultado ficou tão grande, que era inviável utilizar o banner!
Mas não é possível, como o ezgif conseguia otimizar tanto a GIF? Qual mágica secreta eles usam na hora de otimizar a GIF? Eu utilizava o "Optimize Transparency" que tem no ezgif, mas o que isso realmente faz? Então eu comecei a ler sobre como GIFs são feitas, ainda bem que o Wikipedia possui uma documentação extensa sobre o formato de GIFs!
Uma das primeiras coisas que chamaram a minha atenção era que GIFs permitem você escrever uma frame por cima da anterior, assim em vez de você escrever o conteúdo inteiro da frame a cada frame, você pode apenas escrever as mudanças entre cada frame, deixando o resto da frame com cor transparente, parecido com o que codecs de vídeos fazem para reduzir o tamanho de vídeos. Isso é conhecido como "disposal" e, fazendo isso, você consegue escrever apenas as mudanças entre cada frame, diminuindo bastante o espaço utilizado entre as GIFs!
Eu estava usando o GifSequenceWriter para isso, mas o problema é que ele não permite você ir bem "low level" para conseguir fazer uma otimização desse tipo, eu também tentei usar outros GIF encoders que encontrei pela internet, mas nenhum deles suportava transparência e as outras coisas que eu precisava... Até eu encontrar o AnimatedGifEncoder.
Não fique assustado com o ano de 2003 do arquivo, ele funciona e como ele escreve tudo manualmente, ele é perfeito como base para eu modificar a classe para suportar tudo que eu preciso. E a primeira coisa que eu editei foi para que suportasse o sistema de disposal que eu precisava... e foi um sucesso!
Ah, e percebeu que mudou o círculo preto? É que o Discord acabou alterando para que os banners aparecessem no perfil grande dos usuários, mas eles deixaram uma posição diferente para cada lugar! Eu peguei todos os lugares aonde aparecem o avatar e deixei em preto a união entre todos eles, e aproveitei e deixei um pequeno easter egg.
Outra otimização que eu fiz é que GIFs permitem você ter uma frame em qualquer lugar da "tela da GIF", ou seja, você tem uma GIF 500x500 e você quer fazer um quadrado 100x100 em (25, 70), você não precisa escrever a frame 500x500 inteira, você pode apenas escrever a frame 100x100 e indicar que ela deve ser escrita em (25, 70)!
E mais outra otimização boba que eu fiz é remover frames duplicadas. GIFs permitem você configurar quanto é o "delay" entre cada frame, assim diminuindo frames desnecessárias.
Eu acabei não dependendo apenas das minhas próprias otimizações, eu também estava usando as opções do Gifsicle de lossy compression, nível O3 e careful (já que sem o careful a GIF fica com problemas no Discord), mas mesmo assim as minhas próprias otimizações começaram a ajudar bastante!
Ah, e não estranhe que quando eu falo que "eu otimizei a GIF" mas o tamanho dela continua quase a mesma coisa, é que quando eu otimizo algo, eu diminuo o nível de compressão lossy do Gifsicle, para diminuir ass "sujeiras" da GIF.
Eu acabei descobrindo que se você estiver usando o OBS para gravar a sua tela, você precisa configurar ele para fazer uma gravação que evite artefatos e retenha a qualidade do vídeo, por padrão a qualidade do OBS é bem ruim e você terá vários artefatos na sua tela, tanto que a gravação do The Sims 1 era cheia disso e piorava bastante a otimização do The Sims 1. Claro, isso é totalmente desnecessário se você está fazendo livestreams ou gravando vídeos para o YouTube, mas como o meu objetivo é fazer um banner, toda a qualidade é bem-vinda, e logo você irá descobrir porque isso é importante.
Versão sem a parte do The Sims 1, usada para verificar o custo de quanto aquela cena consome.
Versão da GIF com otimização lossy do Gifsicle no máximo, para verificar o máximo de redução possível.
Agora com a cabeça da Loritta no lugar da cabeça original do Sim, já que eu achava ela muito feia.
Para combater o problema de artefatos que eu comentei, eu fiz que se a diferença entre um pixel entre uma frame e outra for pequeno, o pixel não deverá ser mudado, funcionando igual como o sistema de Fuzzy do Optimize Transparency do ezgif funciona.
O problema que isso criou outros problemas, só ver a luva do Vegeta na hora de alterar da seção dele para a parte do Chaos Pudding, fica uma parte da luva dele na outra seção devido a similaridade!
Início do desenvolvimento da seção após a Loritta ir mexer no computador, a ideia original era que o resto da animação iria acontecer dentro da "frame" do monitor, assim economizaria espaço, já que você só precisaria alterar os pixels dentro do monitor enquanto os que estão fora seriam estáticos. Eu acabei mudando de ideia pois tentar encaixar coisas dentro do monitor estava sendo difícil demais, já que o espaço é bem pequeno.
Já que fazer as coisas dentro do monitor era inviável, eu decidi fazer que tivesse um zoom que "entraria" dentro do computador e, é claro, a Loritta estaria lá!
Essa ideia foi inspirada em vários mapas de Worms Armageddon que eu joguei que eram um desktop com ícones, eu sempre achei esses mapas legais pois é meio que misturar um jogo com o seu desktop!
Tinha cansado de ver a GIF inteira só para ver como estava ficando então eu fiz que apenas renderizasse a seção que eu queria ver.
Evoluções na seção dentro do Windows, a partir daqui o banner já começa a tomar uma forma mais parecida com o que ele é hoje!
Se você perceber, ao entrar dentro do Windows, parte do monitor ainda fica na tela. Eu pensava que isso era um problema na geração de frames, mas quando eu exportava as frames para png, esse problema não aparecia! Eu acabei descobrindo depois que isso era um bug no encoder que eu estou usando.
Agora tem uma notificação da Pantufa (amiga da Loritta) entrando no Windows Live Messenger, como também tem uma seção de uma montanha russa do RollerCoaster Tycoon 2 subindo no banner. Desta vez eu gravei corretamente pelo OBS, então foi extremamente fácil tirar o fundo e deixar apenas a montanha russa, como também eu amei como ficou no banner!
Também tem o MusicBee tocando músicas no fundo e, se você perceber, o tempo e o progresso da música (Digital Love) que aparece é o mesmo tempo da GIF em tempo real!
No "buraco" entre o Windows e o Nyan Cat eu achei que seria legal colocar alguns vídeos meus e dos meus amigos, meio que um buraco entre o mundo virtual e o mundo real.
E eu acabei descobrindo que o problema do OBS de artefatos não afeta só gravações do OBS! Vídeos do YouTube também causam o mesmo problema!
E aí eu descobri: GIF usa LZW para compressão, ou seja, se você tem uma imagem 100x100 com apenas uma cor ela vai ocupar muito menos espaço que uma imagem 25x25 com cores aleatórias!
Então é por isso que a parte "suja" de artefatos do The Sims 1 ocupam tanto espaço, como também explica porque frames com transparência ocupam menos espaço! Tudo devido a compressão!!
Então eu comecei a reduzir a paleta de algumas seções, tanto que se você perceber a qualidade da seção do Vegeta e do background do Asriel Dreemurr (ambos de vídeos do YouTube) agora possuem uma paleta reduzida, assim...
As próximas versões do banner foram feitas para conseguir diminuir a paleta de várias seções diferentes, assim economizando espaço e permitindo que possa colocar mais coisas. Algo que ajudou bastante a descobrir quais frames tem o maior custo foi escrever cada frame da GIF em uma pasta e organizando as frames de maior para menor, assim é possível ver quais causam os maiores problemas e como posso arrumar.
Também vários pequenos detalhes foram adicionados:
E sabia que a imagem do Commander Keen falando "Eu não ligo" foi uma das primeiras GIFs que eu fiz na vida?
Para reduzir o impacto dos "artefatos" na seção do The Sims 1, eu decidi aumentar a porcentagem de "fuzziness" de detectar um pixel similar, assim evitando o problema dessa seção gastar muito espaço com pixels que nem deveriam ser alterados. Eu também diminui a porcentagem de "fuzziness" em outras áreas da GIF, assim corrigindo o problema da luva do Vegeta durante a transição.
Primeira versão com créditos e a primeira versão com o bug da "parte do monitor que fica mesmo após a transição" corrigido! Eu acabei descobrindo esse problema quando eu tentava mostrar os |
durante os créditos, que magicamente não apareciam mesmo que eu estivesse escrevendo eles. O problema era que, se uma frame só tivesse uma única cor, o codificador falhava e decidia que a única cor que existe é uma cor transparente, assim escrevendo uma frame vazia.
Também foi alterado os fade in/fade outs que existem na GIF, como cada fade in/fade out altera todos os pixels da frame, toda a frame precisa ser reescrita até acabar o fade in/fade out, e isso consome espaço precioso em nossa GIF! Eu acabei reduzindo a duração dos fades para que tenha mais espaço.
E finalmente o cursor na seção do The Sims 1 se mexe, yay!
Primeira versão que tem um loop completo, com um fade in/fade out após iniciar o banner com java -jar
que faz voltar ao começo da GIF.
A mesa do computador da Loritta foi alterado para ter mais tranqueiras diversas, foram adicionados mais detalhes entre a transição da Loritta para o SparklyPower e a animação do anel gigante foi corrigida.
Essa foi a versão final do banner, finalmente não precisava mais modificá-lo! Agora bastava torcer para o Discord liberar logo a funcionalidade para todos, como também torcer para que eles não reduzissem o limite de tamanho...
Em 24/06/2021 o Discord liberou a funcionalidade de banners para todos os usuários, e finalmente poderia mostrar o meu trabalho de semanas para todos! Estava liberado do sofrimento de otimizar uma GIF e jamais queria encostar em uma GIF novamente!
Até eu começar a ver que "ah, mas eu poderia melhorar um pouco mais o banner, né"...
Para reduzir o espaço, durante um fade a paleta da imagem é reduzida, assim com uma paleta reduzida tem mais pixels similares, o que agrada o LZW e assim diminui o impacto em espaço de um fade!
As madeiras no fundo da seção do SparklyPower tiveram a sua paleta reduzida, assim com mais cores similares entre as frames, tem bem menos pixels a serem alterados quando a Loritta começa a correr (já que não precisa alterar os pixels se eles são a mesma coisa).
A seção do Windows foi aumentada, o tempo da transição de batalha do Undertale foi alterada para ficar mais parecida com o jogo e agora o Asriel fica flutuando para cima e para baixo em vez de ficar estático, igual como é na batalha contra ele.
Foi reduzido as novas coisas na nova seção do Windows pois a GIF estava tão grande e não tinha mais jeitos para tentar otimizar a nova seção.
Enquanto estava legal a nova seção do Windows, com muito espaço para colocar várias tranqueiras... ela também aumentou o tempo que passa durante a seção dos vídeos dos meus amigos, assim estava aumentando MUITO o espaço da GIF e eu sinceramente não estava com paciência para conseguir otimizar tanto, então eu decidi voltar atrás e aumentei apenas um pouquinho a seção, dando mais espaço para tranqueiras mas ao mesmo tempo não causando muitos problemas.
A transição do Windows para a seção do Undertale ainda não estava 100% pronta então a Loritta apenas sai voando e depois volta a ficar em cima do coração.
As madeiras no fundo da seção do SparklyPower tiveram a sua paleta reduzida novamente, e agora usa uma paleta de apenas duas cores!
Agora com um Tux na seção dos créditos, originalmente eu iria fazer que aparecesse o resultado de um neofetch
, que iria mostrar que a "máquina" do banner estava rodando Arch Linux.
Pixels no mar de Palmtree Panic acabaram sendo removidos para melhorar a compressão da seção.
E, é claro, a versão final do banner!