Saudações leitor! A primeira parte do artigo sobre o desenvolvimento de The Light Remake delineou o processo de portar o jogo para a nova versão do Unity. Falei um pouco sobre os shaders e efeitos usados, quais soluções foram implementadas no trabalho com luz, qual conteúdo adicional foi criado, qual conteúdo da versão anterior foi retrabalhado, etc. Na segunda parte falaremos sobre outros aspectos do desenvolvimento, sobre pós-efeitos, estrutura do projeto, trabalho com som, otimização e outras nuances.
Parte 2
Efeitos de postagem
Ao transferir o projeto para um novo motor, decidiu-se deixar os métodos antigos de implementação de pós-efeitos que eram usados nas versões anteriores do Unity. Trabalhar com eles foi mais compreensível para mim e pude fazer as alterações necessárias no próprio processo de processamento de imagens.
Gama
Não havia muitos pós-efeitos no jogo original, mas um dos mais proeminentes foi a correção de cor e brilho. Então eu consegui aleatoriamente obter um brilho esbranquiçado agradável e um esquema de cores um tanto frio. A imagem era contrastante e enfatizava a atmosfera fantástica do local. O estilo visual lembrava um pouco a paleta de cores do Battlefield 3 naquela época, o que me pareceu uma coincidência muito feliz.
Uma nuance interessante é que mais tarde, após o jogo original, não consegui repetir totalmente este efeito, sempre houve algumas subtilezas que fizeram com que a imagem não se parecesse com a original. Nesse sentido, decidi mudar o esquema de cores do remake para um mais quente e positivo. O verde ficou mais claro e expressivo, e a atmosfera ficou mais associada a um dia abafado de verão. Como bônus, após completar o jogo, adicionei a capacidade de ativar a correção de cores, semelhante ao original.
Luz volumétrica
Um elemento muito importante neste remake são os pós-efeitos associados à luz. Versões mais antigas do Unity tinham um efeito de explosão solar muito bonito. No entanto, sua funcionalidade era limitada, porque ele poderia ser vinculado a apenas uma fonte de luz na cena.
Em algum momento, um efeito de iluminação volumétrica muito divertido de luzes volumétricas chamou minha atençãoEle permite que você crie um brilho denso e muito bom e raios que podem vir de diferentes fontes. A atmosfera da cena torna-se mais volumosa, os objetos começam a afundar em uma leve névoa de ar, o que me impressiona muito. A única desvantagem era a alta intensidade de recursos do efeito. No entanto, decidi usá-lo e graças à luz volumétrica, consegui criar uma agradável luz do sol em toda a cena, bem como feixes de luz direcionais místicos em alguns lugares: no corredor no início do jogo, em uma sala com um pardal. O efeito também serviu para enfatizar os acentos nos postes de luz brilhando à noite, no episódio com o projetor, na sala da caldeira para amplificar a luz das janelas, na cena final da ascensão do personagem à luz.
SSAO e SSR
Os outros efeitos mais pesados são SSAO (Ambient Occlusion), que cria sombreamento suave nos cantos e sob as superfícies, em nenhum lugar sem ele. SSR (Screen Space Reflections) também foi adicionado, com o qual realmente havia muitos problemas mesmo na fase de desenvolvimento. SSR simula reflexos em superfícies brilhantes, resultando em bons reflexos em ladrilhos, metal, etc. O problema é que o efeito foi muito forte e quase cortou o FPS no meu hardware. Por meio de algumas manipulações no código de pós-efeito, consegui reduzir um pouco a qualidade do cálculo e melhorar um pouco o desempenho. Em geral, a taxa de quadros tornou-se aceitável, mas em algumas condições (por exemplo, com o Vsync habilitado) SSR causava travamentos e solavancos periódicos quando o personagem se movia.
Outras
Além dos efeitos listados, o projeto também usa Vignette, aberração cromática, mapeamento de tons, antialiasing, névoa global e bloom. Para otimização, vinheta, aberração e mapeamento de tons foram combinados em um único processo.
A propósito, agora, ao trabalhar com gráficos, sempre lembro minha experiência pessoal de estudar em uma escola de arte, onde fomos ensinados a enfatizar sombras contrastantes sob os objetos, exibir reflexos na superfície dos objetos e aplicar névoa no horizonte ao trabalhar com paisagens para enfatizar uma perspectiva aérea. Agora eu sei que era tudo SSAO, SSR e Global Fog!
Como funciona?
O projeto original foi montado literalmente no joelho. Naquela época, eu não tinha nenhum conhecimento de programação e todas as funcionalidades do jogo eram baseadas em alguns scripts simples. O principal era o script de gatilho Activate que encontrei nos ativos padrão do Unity. Todas as funções se baseavam no fato de que o personagem entra no gatilho, liga ou desliga determinados objetos e provoca as ações necessárias. Não havia dúvida de salvar ou configurações do jogo.
Sistema
Claro, para implementar o remake, foi necessário escrever todo o sistema de jogo do zero: o sistema de controle, salva, configurações e mecânica do jogo. Em geral, a construção competente do sistema de projetos ainda é uma tarefa difícil para mim. Normalmente, eu crio um objeto do sistema base com vários objetos filho. Cada um deles desempenha seu próprio grupo de funções e estão todos interligados.
Como o jogo consiste basicamente em um local, decidi não me preocupar em carregar cenas, pré-fabricados e componentes, coloquei tudo o que precisava em uma cena principal. Foram criados controladores que gerenciam tudo que você precisa, alternar configurações, salvar o jogo e ler os dados salvos, ler os textos para legendas e notas de um arquivo especial na raiz do jogo, etc. Para facilitar a implementação, como nos jogos anteriores, optou-se por utilizar o sistema de save nos checkpoints. O local contém várias dezenas de objetos interativos, como portas, itens de jogo, lâmpadas de querosene, etc. Para cada salvamento, é necessário registrar os identificadores de estado do objeto, que geralmente são uma variável Int. Por exemplo, a porta é fechada e trancada com uma chave: DoorOpen - o, DoorLocked - 1.Não entrarei em detalhes a respeito do tópico de programação, já que minhas habilidades nesta área são um tanto específicas e superficiais, porém, são suficientes para a execução de meus próprios projetos.
Duas finais
Uma tarefa interessante para mim foi a implementação da pontuação virtual para conseguir uma das opções de finalização. Eu queria introduzir algum elemento do desafio na jogabilidade do remake e surgiu a ideia de conectar essa ideia com o símbolo principal do jogo - com a luz. Decidiu-se criar um contador que analise o nível de luz ambiente por vários parâmetros. O final do jogo vai depender de quanto tempo o jogador fica em um local iluminado ou ao sol. O primeiro estágio é a coleta de informações das sondas de luz colocadas na cena e seu nível de luminosidade. Este parâmetro é traduzido em uma média e escrito em uma variável float.
Além disso, o script leva em consideração a presença de fontes de luz adicionais nas proximidades, por exemplo, lâmpadas, luz de janelas, uma lanterna acesa ou um isqueiro na mão. A presença de uma das condições adiciona certos valores aos indicadores de luz já calculados. E, finalmente, a luz direta do sol tem o efeito mais poderoso sobre o personagem. De uma fonte de luz solar, um raio é disparado no personagem, que diz ao sistema se o jogador está ao sol.
Todos esses valores são somados e contados por um contador, que ao final do jogo determina como será a final. Se o jogador raramente visitou o céu aberto, sob raios diretos, raramente usou uma lanterna e um isqueiro, então o parâmetro final será baixo. O sistema nem sempre determina com precisão o nível de iluminação, mas em geral ele cumpre sua tarefa. Para depuração e como elemento adicional, existem manchas de tinta reflexiva no tubo de metal nas mãos do personagem, que é um indicador de iluminação.
Legendagem e localização
Para o remake, uma nova abordagem de localização e, em geral, a exibição de textos e mensagens foi elaborada. Mais precisamente, esta abordagem já foi utilizada no projeto do 7º Setor, porém, o volume de conteúdo lá era muito menor. O método de salvar dados em um documento hml é usado como base. Todas as informações de texto para localização são inicialmente armazenadas em um arquivo xml na raiz do jogo. As mensagens são divididas em grupos e individualmente marcadas, pertencem a certas categorias e certos idiomas. Para uma quebra de linha, decidi usar o caractere (*) e iniciar uma nova mensagem (#).
No momento certo (ao escolher um idioma e iniciar uma cena), o controlador lê todas as informações do texto, divide-as em linhas e grupos separados, e as grava em uma espécie de biblioteca ou dicionário. Em seguida, os scripts individuais lêem essas informações, por exemplo, ao abrir um menu ou ativar legendas na tela. O sistema me pareceu pessoalmente conveniente e, o mais importante, compreensível. Ele permite que você insira facilmente um novo idioma e faça alterações no texto existente.
Som
Alguns dos sons básicos foram transportados das fontes originais. Ambiente, canto de pássaros, som de projetor de filme, etc. decidiu-se sair para preservar o reconhecimento do projeto. No entanto, muitos novos conteúdos eram necessários. Os sons do próprio personagem, passos, objetos ativados, a respiração do herói em certos momentos, o efeito de um batimento cardíaco, etc. foram adicionados. Mais variedade foi adicionada ao conjunto de sons ambientes, o chilrear dos gafanhotos, sons aleatórios de objetos caindo e portas batendo foram adicionados. Aliás, inspirei-me nas paisagens do novo Half Life Alyx para adicionar o barulho das cigarras ou dos gafanhotos, em que o clima de um dia quente de verão é muito fresco. Eu gostei de ouvir e assistir as gravações Ambient do City17 no Youtube por um tempo.
A maioria dos sons foi emprestada de bibliotecas gratuitas. Fragmentos foram combinados entre si, efeitos foram aplicados, velocidade alterada, etc.
A criação da trilha sonora tornou-se toda uma camada de trabalho responsável e meticuloso. As composições do projeto original não foram licenciadas, tratava-se de um conjunto de faixas de Ludovico Einaudi, do compositor Thomas Newman e da OST do jogo “Afraid of monsters”. No entanto, costumamos entrar na alma do que ouvimos pela primeira vez, por exemplo, os originais das faixas muitas vezes parecem mais agradáveis do que seus remixes, pelo menos para mim. Nesse caso, ao criar novas composições, eu realmente quis preservar o estilo e a atmosfera das faixas originais. Parece-me que o compositor Dmitry Nikolaev, com quem tínhamos trabalhado anteriormente no jogo 35MM, fez um excelente trabalho nesta tarefa. Fiquei especialmente impressionado com o novo olhar sobre a composição dinâmica que soou durante a exibição do filme na sala de aula. A faixa mantém o estilo energético e ligeiramente psicodélico original,começou a soar fresco, mas reconhecível. A propósito, o próprio filme também foi fortemente revisado e incluiu muito material novo. O conteúdo do vídeo foi escolhido com mais cuidado para evitar violação de direitos autorais e alguns dos fragmentos foram criados de forma independente.
O link mostra o vídeo original usado no jogo original de 2012.
Embora não haja diálogo no jogo, havia um lugar para dublagem. A gravação foi assistida por Vsevolod Petrykin, que já havia participado do projeto 35MM e que deu sua voz ao personagem principal Petrovich. Sua fala pode ser ouvida nos alto-falantes no momento em que os aviões aparecem, no receptor de telefone no episódio do lançamento de mísseis e no rádio, no segundo andar do prédio principal.
Otimização
A otimização se tornou um dos tópicos e tarefas mais dolorosos no trabalho de remake. Acontece que quase todos os projetos que criei anteriormente na versão antiga do Unity (4.6) eram bastante simples em termos de carga no hardware. Tocar 35 MM em minha GTX 970 em alguns lugares deu 200-300 fps em cenas bastante complexas e ocupadas. O Light original, construído em uma versão ainda anterior do motor, mostrou FPS ainda mais alto. Mas ao mudar para o Unity 2017, a taxa de quadros caiu 2 a 3 vezes. É claro que a cena se tornou muito mais complexa, erros de cálculo de luz e reflexos, pós-efeitos adicionais, etc. foram adicionados. mas não esperava uma redução tão dramática no desempenho. O problema é que mesmo depois de remover quase todo o conteúdo da cena, meu FPS não passou de 200-300. Este é um palco meio vazio, Karl!Muito trabalho foi feito para simplificar alguma geometria, criar grupos Lod, configurar seleção de oclusão, etc.
Além disso, usando um script, as câmeras receberam uma distância de corte para certas camadas. Para implementação, foi utilizado um exemplo dos manuais da Unity. Objetos de tamanhos diferentes foram atribuídos a camadas separadas, que param de renderizar se a câmera estiver muito longe. Pequenos objetos como latas, lixo, entulho de madeira e livros são cortados após 20-30 metros. Maiores - após 60-80. Todas as medidas acima reduziram significativamente o número de Drawcalls. Em média, o número de chamadas de empate em uma cena varia de 800 a 2000 DC. O número de polígonos em um quadro não excede 1 milhão.
Recorte de luminária
Como parte da otimização, um script especial foi criado que, a cada 2-3 segundos, determinava a distância a pequenas fontes de luz dinâmicas, como lâmpadas de querosene. Quando a câmera foi retirada das lâmpadas, o script as desligava para não carregar o sistema com processos desnecessários. Além disso, quando o personagem desceu ao porão, a fonte de luz do sol foi desligada. Isso reduziu significativamente o número de DrawCalls.
Poucos detalhes
- Nos corredores do porão, sob os poços de esgoto de concreto com água pingando, você pode ver gotas turvas aparecendo na tela (olhos / óculos do personagem). Simplificado - desde que o herói acione o gatilho e quando a câmera for direcionada para cima, o pré-fabricado do sistema de partículas com um material Grabpass enlameado é ligado. Também neste momento, podem ser observadas gotas na superfície do cartão se o segurar nas mãos.
- . . « », . . , .
- , .
- , , .
- . “STALKER ” , . , , . , . , / .
- , — 3 . , , . . .
Como você pode ver no artigo, desenvolver seu próprio projeto é um processo muito trabalhoso. São noites sem dormir, uma busca constante por soluções, uma busca por inspiração, derrota e vitória. Mas traz grande prazer e uma sensação de auto-realização. Eu diria que isso é mais do que apenas um trabalho - é um modo de vida. Nossas mentes são incríveis e capazes de criar coisas incríveis que às vezes não podem ser comparadas com a realidade. Existe todo um universo no crânio de qualquer pessoa, e é maravilhoso, é maravilhoso que este universo possa de alguma forma ser mostrado através da sua atividade, seja um filme ou um jogo de computador. Cada trabalho é algo pessoal, criado através de um trabalho árduo e exaustivo, algo muito importante e valioso, antes de mais nada para si mesmo.
Desejo a todos boa sorte, inspiração criativa e alto FPS!