Sombreadores em 2S no Godot para desenvolvimento de jogos: programe uma luminária de bolhas animada | Isaac B. | Skillshare

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Sombreadores em 2S no Godot para desenvolvimento de jogos: programe uma luminária de bolhas animada

teacher avatar Isaac B., Software and Game Developer

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Código uma lâmpada de lava

      1:19

    • 2.

      Observe uma referência de lâmpada de Lava

      0:49

    • 3.

      Configure o motor

      1:43

    • 4.

      Crie um Sprite e Shader

      8:15

    • 5.

      Crie alguns bobs

      12:05

    • 6.

      Anime os bobs

      6:26

    • 7.

      Adicione cores

      9:32

    • 8.

      Adicione uma base

      8:02

    • 9.

      Os quadros de exportação para PNGs

      9:54

    • 10.

      Converter PNGs para GIF

      1:02

    • 11.

      (Bônus) adicione a lâmpada Lava à sua tela

      3:38

    • 12.

      Considerações finais

      0:23

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

373

Estudantes

15

Projetos

Sobre este curso

Neste curso, vamos aprender a fazer sombreadores no Godot Game Engine através de um projeto de lava! O Godot Game é um motor de jogos de código livre e livre de o de e a luz é o de Godot.

Este curso serve como introdução como shaders, 2D, que são usados com frequência os shaders, e de dois de dois de de jogos para obter efeitos visuais únicos para ser executado rapidamente no processamento paralela, quais significado muitos pontos são processados no código individualmente e simultaneamente. Ser capaz de escrever shaders é uma habilidade valiosa que pode adicionar muito ar brilho aos seus projetos de jogos e, depois de criar a lâmpada de lava, você terá uma boa compreensão de como eles funcionam!

Vamos escrever nosso código de lâmpada de lava na shading de Godot, que é muito semelhante à GLS, a linguagem de sombre No final do curso, vamos criar um loop GIF sem costura da sua lâmpada de lava personalizado em ação para compartilhar na galeria do projeto

Como bônus, vou mostrar como você pode executar sua lâmpada de lavaria na sua área enquanto faz outras coisas As

Embora você possa acompanhar sem experiência, e vou ter cuidado para explicar cada passo nos detalhes, uma experiência com programação ou motores de jogos será muito útil para ser for o seu compreensão. Se você se de algum problemas, me avise por meio da aba e vou ajudar você a encontrar os problemas.

Próximo curso:

Conheça seu professor

Teacher Profile Image

Isaac B.

Software and Game Developer

Professor
Level: Intermediate

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

Transcrições

1. Código uma lâmpada de lava: Olá, sou o Isaac e faço jogos do estalajadeiro. Nesta classe, criaremos uma lâmpada de lava completamente digital usando sombreadores e o motor de jogo Godot, que é um motor de jogo livre e de código aberto. O objetivo aqui é jogar e experimentar. Há toneladas de possibilidades para sua lâmpada de lava enquanto você está codificando e depois do fato. Você pode alterar coisas como o tamanho e a velocidade das bolhas, a cor de fundo, as cores de primeiro plano, os gradientes, o brilho de cada blob individual, bem como a própria base. Vamos escrever nosso código de lâmpada de lava usando a linguagem de sombreamento Godot, que é muito semelhante ao GLSL, a popular linguagem de sombreamento OpenGL. No final da aula, criaremos um GIF de loop contínuo do seu projeto de lâmpada de lava para compartilhar na galeria do projeto e em outros lugares. Como bônus, vou até te mostrar como você pode manter sua lâmpada de lava funcionando em seu desktop. Esta classe serve como uma introdução aos shaders de fragmento 2D, que são frequentemente utilizados no desenvolvimento de jogos para obter efeitos visuais puros que são executados rapidamente através de processamento paralelo. Ser capaz de escrever shaders é uma habilidade valiosa que pode adicionar muito talento aos seus projetos de jogo, e depois de criar sua lâmpada de lava, você terá uma boa compreensão de como eles funcionam. Terei o cuidado de explicar cada passo em detalhes, mas alguma experiência anterior com codificação ou mecanismos de jogos em geral seria muito útil para a sua compreensão. Se você tiver algum problema, por favor me avise na guia de discussões e eu vou ter certeza de ajudá-lo. Com isso, vamos começar. Certifique-se de que você está me seguindo aqui no Skillshare para mais aulas de desenvolvimento de jogos como esta. Em nossa primeira lição, observaremos uma lâmpada de lava real para descobrir como vamos imitá-la com nosso código de sombreamento. 2. Observe uma referência de lâmpada de Lava: Vamos dar uma olhada nesta lâmpada de lava para referência antes de começarmos a codificar. Primeiro, a lava separa em manchas esféricas distintas, esticando, separando e fundindo. Usaremos algo semelhante aos metaballs para alcançar este efeito. Segundo, a lava tende a fluir rapidamente, para cima ou para baixo, abrandar quando atinge um ponto final e, eventualmente, muda de direção. Vamos olhar para algumas funções matemáticas que oscilam assim ao longo do tempo. Três, a lava é realmente brilhante na parte inferior e uma cor completamente diferente no topo. Parece brilhar um pouco. Podemos tentar usar alguns gradientes aqui para imitar esse efeito. Quatro, da mesma forma, a solução de álcool é mais brilhante nas bordas da lâmpada e mais escura no meio. Novamente, podemos tentar usar gradientes aqui. Vamos manter essas ideias em mente à medida que começarmos a codificar. Na próxima lição, vamos baixar e configurar o Kidlo para que possamos começar. 3. Configure o motor: Nesta lição, vamos baixar o mecanismo e configurar um projeto básico. Se você ainda não tem o mecanismo de jogo Godot, você pode obtê-lo em Godotengine.org, clicar em Downloads e encontrar o download que corresponde ao seu sistema operacional e à sua arquitetura de sistema. Você também pode baixar o motor do Steam. Se você fizer isso, ele virá pré-carregado com um monte de demonstrações que você pode conferir para ver como os projetos básicos funcionam. Vá em frente e ligue o motor se você ainda não fez isso. Se você baixou a imagem do Godot do site, depois de extraí-la do arquivo zip e tentar executá-la pela primeira vez, você pode encontrar um aviso de segurança do seu sistema operacional. No Windows, você pode tranquilizar o Windows Defender pressionando mais informações e, em seguida, executar de qualquer maneira. Godot é um software de código aberto, então você é bem-vindo para ler o código você mesmo, se quiser. Este é o gerente de projeto do Godot. Se você baixar o mecanismo do Steam, você encontrará um monte de demos aqui. Desde que eu baixei o motor do site, eu não tenho nada aqui ainda. Vou pressionar este botão Novo Projeto à direita. Eu gostaria que este projeto estivesse na minha área de trabalho, então eu vou digitar desktop aqui. Você pode precisar pressionar este botão “Procurar” para encontrar uma pasta onde você gostaria de colocar seu projeto Godot. Godot está dizendo, “Por favor, escolha uma pasta vazia”, porque ele acha que eu quero colocar os arquivos diretamente na minha área de trabalho. Ele gostaria de colocar coisas como minhas sprites e texturas ao lado da lixeira, o que não é o que eu quero. Claramente, a área de trabalho não está vazia. Ele, pelo menos, contém o atalho da lixeira de reciclagem. Eu vou digitar Lava Lamp na seção de nome do projeto e pressionar este prático botão “Criar pasta”, e agora Godot criou uma pasta chamada Lava Lamp na minha área de trabalho para que todos os arquivos do projeto para este projeto possam viver diretamente em que pasta. Como eu não preciso que este aplicativo seja executado em um ambiente web, eu vou deixar a opção de renderização padrão. Na próxima lição, pressionarei este botão e criaremos nossa estrutura de projeto e começaremos a escrever nosso código de sombreamento. 4. Crie um Sprite e Shader: Nesta lição, vamos configurar uma estrutura de projeto e começar a escrever algum código Shader. Vou pressionar o botão “Criar e Editar”. Este é o editor Godot. No meio, você verá basicamente uma representação da cena atual que você está criando. Aqui à esquerda, temos a opção de criar o nó raiz para esta cena. Em Godot, nós representa pequenos blocos de construção de jogos. Eles são nós para criar imagens, personagens, elementos de interface do usuário, animações e muito mais. Como estamos focados em escrever um Shader para este tutorial, nós realmente não precisamos de muitos nós, mas precisamos de pelo menos um nó ao qual podemos aplicar nosso Shader. Este nó também deve desenhar nossa base de linha de nível quando chegarmos a essa etapa. Podemos escrever Shaders 2D através de materiais para qualquer nó que herde de um item Canvas. Para mostrar o que são esses nós, vou pressionar “Outro nó”. Esta é uma árvore inteira que consiste em , em última análise, todos os nós que Godot tem em oferta. Estamos procurando coisas que herdam do item Canvas. Coisas que existem abaixo deste menu suspenso chamado item Canvas. Eu vou para Node2D e todo o caminho na parte inferior Sprite, porque eu também quero renderizar a base da lâmpada de lava e, em seguida, renderizar nosso Shader em uma parte específica da base. Vou pressionar “Criar” para fazer um Sprite. Agora você pode ver que eu tenho aquele Sprite aqui à esquerda como o nó raiz da minha cena atual. Aqui à direita, temos acesso a mais propriedades para o nó que acabamos de criar. No topo aqui você pode ver estas são propriedades que são específicas para o nó Sprite, logo abaixo que temos propriedades que são específicas para todos os Node2Ds, e sendo que temos propriedades que são específicas para todos os itens do Canvas. Claro, novamente, todos os nós. Novamente, isso é porque se voltarmos e olharmos para a árvore, temos nó no topo da árvore, item Canvas abaixo disso, e Node2D abaixo disso. Estas são as propriedades para Sprites, estas são as propriedades para Node2Ds, estas são as propriedades para itens Canvas e estas são as propriedades para todos os nós. Vou pressionar “Cancelar” porque só queria mostrar a árvore. Desde que eu criei um nó 2D como o nó raiz para a cena, Godot nos trocou automaticamente para a visualização 2D. Esta caixa azul aqui representa o tamanho da tela que acontecerá quando eu pressionar “Play” para depurar o jogo. Você pode ver que eu tenho o Sprite selecionado, então esta mira aqui representa a localização atual do Sprite. Atualmente não está renderizando qualquer textura, e você pode ver que ao ver também que a textura está vazia. Vou arrastar icon.png para a propriedade Sprite, e agora você pode ver que icon.png está sendo processado como a textura deste Sprite. Nós vamos apenas usar icon.png temporariamente para ver como Sprites funcionam e também para escrever nosso primeiro código Shader apenas para sobrescrever a textura básica. Você pode ver que o nó Sprite agora se estende fora da caixa azul que criamos. Você pode ver que o Sprite agora se estende para fora da região, marcado pela caixa azul, o que significa que muito disso não será renderizado na tela. Vou executar o jogo pressionando o botão “Play”. Vai reclamar porque eu não marquei uma cena principal. Porque este é um projeto muito simples para demonstrações Shader. Para salvar o meu trabalho, vou fazer o “Control S”. Você pode fazer “Command S” se estiver em um Mac. Para salvar meu trabalho até agora, vou para Scene e pressionar “Salvar cena”. Já que não salvei esta cena antes, está a pedir-me um nome. Vou chamá-lo de lamp.scn e pressionar “Salvar”. Você também pode ver agora que lamp.scn apareceu nos arquivos do projeto. Se eu pressionasse “Play” aqui em cima, Godot me avisaria que eu nunca defini uma cena principal. Isso ocorre porque a maneira que os jogos são geralmente estruturados em Godot, esses são raiz visto que o jogo é executado como a coisa fundamental que todas as outras cenas em nós são filhos de. Ainda não definimos um desses, então precisamos selecioná-lo. Eu vou novamente escolher lamp.scn que acabamos de criar, e pressione “Abrir”. Como, por padrão, a origem de um Sprite é 00 o centro do objeto, você pode ver que o Sprite está sendo cortado em três dos quatro quadrantes. Vou fechar isso. Voltando ao nosso projeto, podemos olhar para offset e desmarcar centrado. Agora você pode ver que o Sprite se encaixa completamente dentro desta caixa azul, que representa o tamanho da tela que você receberá quando você jogar o jogo. Agora vamos começar a escrever algum código Shader. Eu disse anteriormente que podemos escrever código Shader para qualquer nó que herda de um item Canvas. Vou procurar aqui as propriedades de todos os nós que herdam do item Canvas, e abaixo do material, você pode ver que ele diz atualmente, material vazio. Vou clicar nesta seta suspensa e pressionar “NewShaderMaterial”. Você verá uma prévia do material básico que acabamos de criar aqui nesta esfera. Vou clicar nele e, em seguida, onde ele diz Shader, vou clicar na seta suspensa e definir um novo Shader. Então eu vou clicar no “Shader”, e você pode ver que ele está aberto uma pequena janela de código aqui. No momento, temos um erro. Ele diz que esperado um tipo de Shader no início do Shader, tipos válidos de nosso item Canvas, partículas e espacial. Estamos escrevendo um CanvasItemShader, então eu vou escrever Shader type: Canvas item, e um ponto-e-vírgula para indicar que eu terminei com a linha. Você pode ver que isso fez o erro desaparecer. É importante notar que o que estamos escrevendo aqui não é o script Judy, que você pode ter usado em um tutorial em vídeo anterior de mim. Mas uma linguagem criada especificamente para escrever Shaders em Godot. É semelhante ao GSL se você já usou isso. Vamos começar definindo um fragmento Shader que simplesmente define a cor em cada ponto coberto pelo Sprite como branco. Eu vou ampliar um pouco no Sprite usando a do mouse e mantenha pressionada a roda do mouse para fixar, só que eu posso ver um pouco mais claramente o que eu estou fazendo. Vamos começar escrevendo a função de fragmento. Esta função vai escrever vai ser chamado pelo motor em cada ponto individual em que o nosso Shader é executado. Primeiro escrevemos, “Void”, porque esta função não retorna nada para a função que codificou, e então vamos escrever, “Fragmento”, porque estamos implementando a função de fragmento. Você pode ver que Godot tentou preencher automaticamente para mim. A função de fragmento não usa nenhum parâmetro, então é parênteses vazias lá. Em seguida, abra o colchete, Enter. Agora este é o bloco de código que será executado sempre que o motor chamar a função de fragmento. Para definir cada fragmento individual coberto pelo Sprite como branco, escreverei cor igual a vec4, que significa vetor 4 ou uma coleção de quatro números neste caso. Então eu vou escrever, 1.0, 1.0, 1.0, 1.0. O que isso significa neste contexto, você pode ver que ele acabou de ser atualizado e agora está demonstrando completamente branco é 1.0, que significa completamente vermelho, 1.0 que significa completamente verde, 1.0 que significa completamente azul, e 1.0, o que significa completamente opaco. Este é o valor Alfa, então é RGBA. Quando dizemos que a cor é igual ao branco, o que estamos realmente dizendo é que para cada ponto em que este Shader funciona, eu quero que a cor nesse ponto específico seja branca. Há uma maneira abreviada de fazer isso, que é escrever vec4 e, em seguida, apenas um único 1.0. Vou apagar tudo isso. Você pode ver que está tudo bem. O motor está apenas preenchendo 1.0 em todas as posições vec4 automaticamente. Na próxima lição, criaremos algumas bolhas básicas em preto e branco. 5. Crie alguns bobs: Nesta lição, vamos criar algumas bolhas pretas e brancas básicas. Vamos começar definindo a cor de fundo para preto. Como o valor RGB de preto é 000, você pode pensar que definir zero aqui criaria uma saída de fundo preto. Mas, na verdade, uma vez que o valor Alpha também é definido zero quando definimos todos os quatro componentes do vetor 4 zero, obtemos um valor preto com uma saída totalmente transparente. Precisamos dizer mil, e depois 1,0 no Alpha. Agora, temos a nossa saída de fundo preto. Agora eu quero adicionar algumas bolhas brancas. Para fazer isso, preciso substituir uma cor que acabamos de definir aqui como branca nas áreas que queremos que nossas bolhas apareçam. Primeiro, vou criar uma lista que contém apenas os pontos centrais de cada uma dessas blobs, bem como a força desse blob, relativamente análogo ao tamanho do blob. Vamos começar escrevendo vec3, blob_centers, e eu quero que isso tenha atualmente dois elementos para dois blobs e, em seguida, adicione um ponto-e-vírgula para a enésima linha. Agora vou atribuir cada um desses centros de blob a um ponto e uma força. Para o 0º blob ou o primeiro blob na lista, eu vou atribuir esse igual a um vetor3, e esta é uma coordenadas relativas aqui. Se eu disser 1.0,1.0 e, em seguida, imprimir um zero, isso faz referência a 1.0 todo o caminho, 100 por cento através da textura no eixo x e 100 por cento abaixo da textura no eixo y. Eu atualmente defini a força para zero. Digamos que eu quero isso talvez por aqui para 0,6 no x e 0,6 no y, ou 60 por cento através da textura em ambas as direções. Vou ajustar a força para 0,5. Vou fazer algo parecido com o próximo centro de bolhas. Talvez eu queira que este seja um pouco mais à esquerda. Eu vou dizer 0,5, 0,55, e então eu quero que isso seja um pouco maior, digamos 0,6. Agora definimos os locais para duas blobs aqui e aqui. Lembre-se de que o sombreador de fragmento que estamos escrevendo é executado individualmente em cada ponto dessa textura. O que eu quero fazer é para este ponto atual em que estamos, ver o quanto ele é influenciado por esses centros de blobs usando a força. Se for influenciado mais do que um determinado limite, podemos definir essa cor como branca. Vamos começar medindo a influência que cada uma das bolhas tem neste ponto individual. Eu vou dizer float para valor de ponto flutuante, e eu vou digitar influência e defini-lo para 0.0 para iniciar. Em seguida, vou percorrer a lista de blobs para medir o quanto esse ponto individual é afetado por cada um deles. Eu direi para, entre parênteses abertas, int i é igual a 0, porque queremos começar a contar em zero, i menor que blob_centers.length. Queremos que eu fique menos de dois porque esta matriz só tem os índices zero e um porque tem dois elementos. Outro ponto-e-vírgula, e eu vou dizer i++, para incrementar i por um depois de cada vez que iteramos através das bolhas. Vou abrir alguns colchetes aqui, e este é o código que será executado para cada uma das blobs. Primeiro, vamos calcular a distância deste centro de blob que estamos atualmente até o ponto em que estamos trabalhando atualmente. Eu vou dizer float distance_to_blob_center, e eu vou dizer distância para a boa e velha função de distância embutida. Abra parênteses e ponto-e-vírgula. A função de distância quer duas posições para medir a distância entre. Eu vou dizer blob_centers, abrir colchetes, e então i, porque eu quero o blob em que estamos atualmente, e então eu vou dizer y.xy para construir um vetor com apenas o componente x e o componente y do vetor atual. BLOB_centers i, se estamos no 0º neste momento, será 0.6, 0.6 e será um vetor também. Então eu quero medir a distância entre o centro de blob atual e nossa posição atual, que é representada pela entrada uv. Agora, esta função de distância é bom para agora, já que atualmente temos uma textura quadrada no sprite. Mas mais tarde, vamos querer usar uma textura retangular para o sprite para que possamos adicionar nossa base de lâmpada de lava. Digamos que a textura fosse desse tamanho, por exemplo. Lembre-se que para as posições que estamos usando aqui, blob centra xy e uv, é relativo ao máximo geral x e y. isso é 1.0 no eixo x, e mesmo que agora seja um retângulo, isso é ainda 1.0 no eixo y, uma vez que é relativo ao tamanho geral. Isso significa que nossa função de distância será um pouco distorcida. Quanto mais longe chegamos de uma textura sprite quadrada perfeita. Eu vou dividir cada uma dessas posições componente-wise por tamanho de pixel de textura. Para a textura atual, estamos usando icon.png. Tamanho de pixel de textura é um vetor também que contém 1 sobre 64 e 1 sobre 64. O que isso realmente está fazendo aqui é multiplicar componente wise uma coordenada relativa, representada entre zero e 1.0, pelo número de pixels em cada direção. Está convertendo de uma coordenada relativa em uma posição absoluta na textura. Vou dimensionar um sprite de volta ao modo como ele costumava ser, passando pelo menu suspenso de transformação 2D do nó e redefinindo a escala. Agora vamos adicionar alguma influência a este ponto com base em sua distância do blob específico. Adicione uma nova linha aqui e diga influência mais é igual a dizer que eu quero adicionar e reatribuir, e então eu direi blob_centers i, novamente, para o blob atual. Eu vou dizery.z porque nós só queremos este terceiro componente, que dissemos representa a força para este blog em particular tem. Seu instinto agora pode ser multiplicar isso por distância-centro. Mas lembre-se de que isso significa que quanto mais a bolha estiver desse ponto específico, maior será esse valor e maior será a influência geral. Queremos o inverso disso. Os pontos mais próximos do blob devem ser os mais influenciados pelo blob e mais propensos a serem brancos. O que realmente queremos é 1,0 dividido por distância-centro. Vou apenas capturar isso entre parênteses, e isso nos dará a relação correta entre influência e a distância da bolha até o ponto específico. Agora, é aqui que um pouco de magia vai acontecer. Queremos dizer que se a influência estiver acima de um certo limite, queremos mudar a cor do que é atualmente, preto para branco. Eu vou correr se a influência estiver acima, digamos, 0.3, queremos definir a cor para branco. Lembrem-se, temos uma bela taquigrafia. Podemos dizer vec4 e, em seguida, preencher todos esses componentes com 1.0. Ali. Agora temos algumas pequenas bolhas que apareceram na tela. Eu vou ampliar e você pode ver como isso está funcionando um pouco mais claramente. Como esperávamos, temos uma área de branco em torno de cada uma das bolhas. É sempre uma boa ideia criar exemplos para você mesmo para testar seu código e certificar-se de que você está entendendo como tudo está funcionando. Vamos dar um exemplo de ponto entre os dois centros de blob. Se eu olhar para os pontos intermediários entre estes, isso é sobre o ponto 0.55 no eixo x, 0.575 no eixo y. Isso é em algum lugar por aqui. Vamos passar pelo nosso código usando isso como exemplo. Como esse é o ponto atual que estamos olhando, suas coordenadas estarão na entrada UV. Agora, vamos verificar o nosso código. Primeiro, a influência é definida como 0,0, então, para cada uma das bolhas, fazemos isso. Digamos que para o primeiro blob, este aqui, nós temos distância-centro é a distância entre centros de blob i, então o blob atual, novamente, este ume.xy, então nós temos apenas o 0.6 e o 0.6, dividido pelo pixel de textura tamanho. Neste caso, isto significa componente a ser dividido por 1 sobre 64 e 1 sobre 64, que é o mesmo que multiplicar ou escalar este vetor por 64. Então temos a mesma coisa, mas para UV em vez dos centros blobs xy. Assim, o UV, novamente, é atualmente 0,55 e 0,575. Se calcularmos a distância entre essas duas coisas, obtemos cerca de 3.578. Agora queremos adicionar para influenciar um valor que corresponde à força atual do blob e nossa distância do centro do blob. Substituímos o componente blob z atual, que é 0,5, multiplicamos 0,5 vezes 1,0 sobre 3,578. Se fizermos isso, teremos cerca de 0,14. Adicionamos 0,14 para influenciar e, em seguida, passar para o próximo blob. Agora estamos nesta bolha. Agora passamos pelos mesmos cálculos novamente. Calculamos a distância até o centro de blob, e como o ponto que escolhemos para ser uv está a meio caminho entre esses dois centros de blobs, sabemos que será apenas 3.578 novamente. Em seguida, adicionamos para influenciar o componente blobs z atual, que neste caso é 0.6 agora, e depois multiplicamos isso por 1.0 sobre 3.578 novamente. O que temos para a influência a acrescentar aqui é 0,17. Nós adicionamos 0,17 à influência, e agora temos 0,31 como nossa influência atual, já que 0,14 mais 0,17 é 0,31. Agora, movendo nosso código, se a influência for maior que 0,3, definimos a cor como branca. Uma vez que a influência é atualmente 0,31, ele avalia verdade que esse valor é realmente maior que 0,3, e assim definimos a cor para branco. O ponto no meio entre essas duas bolhas é de fato branco. Apenas para verificar novamente nossa matemática, nós também podemos aumentar esse valor de 0,3. Diga, eu quero que seja 0,31, e eu posso ver que o ponto entre estes não é mais branco. Isso porque 0,31 não é maior que 0,31, e também porque arredondamos algumas vezes quando estávamos falando em aumentar a influência. O valor que arredondamos para ser 0,31 não é maior que o ponto 0,31, então não definimos a cor para branco e ela permanece preta, como dissemos inicialmente. Só porque eu posso querer ajustar isso mais tarde, eu vou substituí-lo por uma nova variável que eu vou chamar limiar e criar um uniforme acima do fragmento superior. Vou declarar um novo uniforme escrevendo o limite flutuante uniforme. Eu vou dizer por padrão, vamos definir isso como 0.3, que é o valor que tínhamos antes. Mas aqui, há uma coisa nova, uma nova lista suspensa chamada Shader Param, e temos esse novo uniforme de limiar que acabamos de definir, configuração 0.3. Agora, se eu aumentar esse valor, você pode ver que, de fato, nossas atualizações de sombreamento. Você também pode clicar e manter pressionado e arrastar em qualquer direção, esquerda ou direita, com o mouse para assistir como isso se ajusta. Isso apenas torna muito fácil ajustar o limite do editor em vez de do nosso código. Clicar nesse botão de redefinição, como eu acabei de fazer, apenas o define de volta para o valor que você define igual a aqui, é como um padrão. Na próxima lição, vamos adicionar mais algumas bolhas e animá-las. 6. Anime os bobs: Nesta lição, vamos adicionar mais algumas bolhas e animá-las para começar a parecer um pouco mais como uma lâmpada de lava. Para começar, vou aumentar o número de centros de blobs que tenho. Eu vou definir isso para seis em vez de dois apenas para que agora temos seis centros de blob total. Eu só vou fazer Controle C nesta seleção para copiar e Controle V para colá-lo algumas vezes. Dependendo do seu sistema operacional, você pode precisar usar o Comando V ou/e Comando C em vez de Controle, e eu vou definir isso como 2, 3, 4, 5. Agora, de fato, temos seis centros totais de blob. Você verá que o tamanho do blob aumentou muito aqui, e isso é porque adicionamos para cada uma das blobs, algumas influenciaram o ponto atual. Mesmo para blobs que estão longe daqui, muito longe de qualquer um dos centros de blob, eles ainda recebem cada vez mais influência só porque adicionamos mais blobs. Eles são mais propensos a serem incluídos nesse intervalo do que eram antes, simplesmente porque há mais. Eu vou diminuir um pouco usando a roda do mouse apenas para que eu possa ver um pouco mais claramente o que está acontecendo, e eu vou apenas mover as coordenadas x um pouco para ter certeza que eu posso ver um pouco mais claramente onde cada uma dessas bolhas estão, porque agora muitos deles têm exatamente a mesma posição. 0,6, 0,5. Digamos que este é 0,55, este está em 0,45, este em, eu não sei, 0,62, este é em, digamos 0,7. Eles deveriam ter se espalhado um pouco, como você pode ver. Agora eu quero que o componente y de cada um desses centros de blobs dependa do tempo. Mais especificamente, eu quero uma função matemática que leva tempo como uma entrada e retorna para mim um valor entre 0.0 e 1.0 com base no tempo que eu lhe dei. Agora há algumas maneiras diferentes de fazer isso. Vamos começar por representar graficamente o seno x. Imagine que o eixo x é o tempo e o eixo y é a posição y do nosso blob. Sine x funciona muito bem para nossas necessidades, mas ele tem alguns valores negativos que ele produz que nós acabamos com algumas bolhas que vão acima da nossa textura. Para ter certeza de que nossos valores y do centro de blob permaneçam entre zero e um, queremos que o termo seno x seja positivo. Uma opção seria pegar apenas o valor absoluto do seno x, mas isso nos dá esses cantos, e se imaginarmos novamente que o eixo x é o tempo, isso significa que quando o blob atinge um desses cantos, ele imediatamente salta para trás e começa a mover-se na direção oposta y. Este movimento seria um pouco antinatural e pareceria que a bolha saltou para fora do topo da lâmpada e imediatamente começou a acelerar para baixo ou vice-versa. Novamente, há algumas maneiras diferentes de lidar com isso, mas eu prefiro usar seno quadrado x ou seno x vezes seno x. isso elimina os valores negativos, uma vez que um valor negativo vezes um valor negativo é um valor positivo, e suaviza esses cantos para torná-los um pouco mais redondos. Agora temos, digamos, por exemplo, uma bolha que começa na parte inferior, acelera rapidamente em direção ao topo, desacelera e, em seguida, pega velocidade novamente à medida que volta para o fundo da lâmpada. Este é o comportamento perfeito que procuramos. Para adicionar um pouco de variação entre blobs, eu também posso querer ser capaz de controlar o deslocamento inicial e a velocidade. Uma vez que o nosso eixo x é o tempo aqui, a maneira que eu posso acelerar as coisas um pouco, é multiplicar a entrada x por um fator de velocidade. Da mesma forma, se eu quiser deslocar o tempo um pouco, eu vou apenas adicionar um pouco para o x. Agora vamos traduzir isso em código. Vou definir uma nova função que retorna um flutuador chamado oscilate, e a função oscilar que estamos definindo levará x flutuador, velocidade flutuante e deslocamento flutuante. Adicionando minhas chaves, e este é o código aqui que será executado sempre que chamarmos a função oscilar. Desde que queremos seno quadrado x ou seno x vezes seno x, eu vou dizer, retornar como seno x vezes velocidade mais deslocamento, e então eu quero elevar essa coisa toda para a segunda potência, que é por isso que ela está contida no poder função. Vou escrever um ponto-e-vírgula para completar a minha expressão, e esses são função básica de oscilação. Agora eu quero usar essa função oscilar usando o tempo como uma entrada para cada um dos meus centros de blob y posições. Também pode ser aplicado como acontece com a entrada de tempo. Tudo que eu tenho que fazer é substituir o componente y de cada centro de blob por oscilação, tempo, e então talvez eu queira que isso seja executado em meia velocidade com um deslocamento de 0,4. Agora você pode ver que eu tenho esse blob que está animando para frente e para trás entre 0,0 no eixo y e 1,0 no eixo y usando o tempo como nossa entrada. Vou adicionar algo semelhante para o resto destes. Digamos que oscilar o tempo, eu quero que isso vá ainda mais devagar, 0.2, e então, eu não sei, 0,5 no deslocamento. Continua a fazer isto. Agora você pode ver que todas as minhas bolhas estão indo e voltando no eixo y usando nossa função oscilar. Agora é provavelmente um bom momento para ajustar todos esses valores apenas para ter certeza de que você está confortável com eles, então você pode talvez mudar os blobs no eixo x um pouco alterando seu componente x, ou deslocá-los em o eixo y um pouco mudando sua velocidade, seu deslocamento, e, em seguida, também mudar a influência aqui. Eu gosto de fazer a força de cada bolha um pouco maior se eles estão indo mais devagar. Aqueles que eu defini a velocidade para 0,1, eu vou aumentar a influência sobre a força um pouco, então eu vou dizer que isso é 0,8 e 0,8, e eu posso ver que as bolhas mais lentas movimento são um pouco maiores. Se você quiser ser capaz de ajustar esses valores realmente rapidamente, você pode definir um uniforme para cada um deles como fizemos para o limite. Eu não vou fazer isso só porque é um monte de uniformes diferentes para definir, mas essa é uma opção se você quiser que as pessoas ajustem rapidamente coisas como a velocidade, o deslocamento, ou a posição x do editor. Estou muito feliz com isso como é por enquanto, então eu vou seguir em frente e começar a adicionar um pouco de cor na próxima lição. 7. Adicione cores: Nesta lição, adicionaremos algumas cores à nossa lâmpada de lava. Vamos começar adicionando a cor de fundo que observamos anteriormente é mais brilhante nas bordas e mais escura no centro. Eu vou fazer essas cores uniformes que eu possa ajustá-los rapidamente mais tarde, se eu quiser. Eu vou escrever ve4 uniforme uma vez que novamente, representamos cores com vetor fours, e eu vou escrever background_edge e eu vou dizer dois-pontos, hint_color. Isso diz ao editor que eu quero que a borda de fundo tenha a dica de um seletor de cores. Mesmo que seja um vetor quatro, os quatro componentes são RGB e A. O editor agora coloca valores nesses quatro componentes dependendo da cor que eu escolher de um bom seletor de cores, em vez de ter que inserir números manualmente e isso é só porque escrevemos hint_color aqui para dizer ao editor que esta é uma cor. Eu quero definir a cor de fundo na borda para uma cor magenta agradável. Eu quero que isso seja todo o caminho em 255. Quero que o verde esteja no zero, e quero que o azul seja no 255. Agora eu tenho essa cor magenta que eu espero colocar nas bordas, especificamente as bordas X da lâmpada de lava. Agora, eu vou escrever novamente, uniforme vec4 background_center e novamente, esta é uma cor. Agora eu tenho outro que diz, se eu passar o mouse sobre o centro de fundo, eu vou apenas definir isso para uma cor roxa mais escura e, claro, eu posso ajustar esses valores mais tarde, esses são apenas valores que eu estou definindo para agora. Agora vou definir mais dois uniformes para o que eu quero que as cores das bolhas estejam no topo e no fundo. BLOB_top e é uma cor semelhante e agora, ele apareceu mais como uma cor no editor, eu vou definir isso para ser uma cor vermelha vibrante agradável e, em seguida, outro ve4 blob_bottom uniforme para o que eu quero que as blobs para estar a parte inferior e isso é outra dica de cor. Eu tenho mais um seletor de cores aqui em baixo e eu vou definir isso para ser um bom amarelo. Vamos começar definindo a cor do plano de fundo para uma mistura entre a borda do fundo e o centro do plano de fundo, criando um gradiente. Vou começar indo para onde eu estou definindo a cor para preto, bem aqui, e em vez de usar um vetor para esta constante, eu vou configurá-lo para uma mistura, que é uma função de interpolação linear em Kidlo. Agora eu vou escrever centro de fundo, borda de fundo porque eu quero misturar entre essas duas cores, e isso irá produzir um vetor 4 na cor como precisamos. Então, digamos que vou começar com 1.0 aqui. Você pode ver que isso definiu completamente tudo para ser 1.0. Temos a cor da borda de fundo definida em todos os lugares onde o preto costumava estar. Se eu fosse definir isso como 0.0, agora temos totalmente a cor central de fundo em vez disso. Se eu definir como 0.5, temos metade do caminho entre o centro de fundo e a borda de fundo, e assim por diante. Se eu mudar essa variável, ela muda a mistura que eu estou usando entre as duas cores e eu quero que essa mistura, a última variável de peso , seja dependente de quão perto eu estou ou quão longe eu estou do centro da lâmpada. Quanto mais longe eu estou do centro, mais eu quero confiar na borda de fundo, e quanto mais perto eu estou do centro, mais eu quero confiar no centro de fundo. Eu vou dizer que eu quero o valor absoluto de 0,5 menos a posição x atual, que novamente, eu posso obter a posição atual dizendo UV e, em seguida, .x, e então eu vou multiplicar isso por 2.0. Vamos testar isso para ver como está funcionando. Se eu estiver no centro, então minha posição X atual é 0.5. Eu vou fazer o valor absoluto de 0,5 menos 0,5, que é zero, e então multiplicar isso por 2.0, que é zero, o que significa que eu vou depender completamente da cor central de fundo. Deve ser um roxo escuro e é. Agora vamos testar em 0,0. O valor absoluto de 0,5 menos 0,0 é 0,5, vezes 2, é 1. Eu deveria ser completamente dependente da cor da borda de fundo e eu sou. Da mesma forma, se eu tentar uma posição entre 0,0 e 0,5 no x, digamos 0,25, terei o valor absoluto de 0,5 menos 0,25, que é 0,25, vezes 2, que é 0,5. Eu estou a meio caminho entre centro de fundo e borda de fundo, que você pode ver que eu sou. Eu posso alterar esses valores como eu quiser modificando agora a borda do fundo e a cor central do plano de fundo. Eu quero que a cor da borda de fundo seja um pouco mais escura, então eu vou apenas trazê-la para baixo um pouco. Lá vai você. Agora eu quero fazer a mesma coisa, mas pelas bolhas. Abaixo onde definimos a cor das blobs, se a influência for maior que o limite, é aqui que definimos a cor do blob como branco. Em vez disso, vou usar outra mistura, blob_top, blob_bottom e, em seguida, eu quero que isso seja dependente de onde estamos no eixo y. Quanto mais longe eu estou do topo, mais eu quero confiar no fundo. Eu só vou usar UV.y para que se eu estiver em 1,0, eu estarei completamente dependente da cor inferior da bolha, que você pode ver que eu sou e se o meu UV.y é zero, eu estou no topo deste brilhante, então eu deveria estar completamente dependente a cor do topo da bolha, que você pode ver quando uma bolha sobe aqui, que eu dependo disso completamente lá em cima. Isso funciona bem. Agora eu quero que as bolhas brilhem um pouco e a maneira que eu vou fazer isso é criar uma mistura entre a cor de fundo na posição atual e a cor do blob na posição atual. Para fazer isso primeiro, eu vou apenas armazenar esta mistura aqui e eu vou dizer, há um novo vec4 chamado current_blob_color e eu vou definir isso para essa mistura, colocar o ponto-e-vírgula, e então eu vou apenas substituir isso aqui por current_blog_ cor. Isso é apenas para evitar ter copiado e colado código. Agora eu vou criar um novo flutuador chamado glow_multiplier, e eu vou definir isso para o que eu defini meu limite para, vezes 10. Isso é bastante arbitrário e eu encorajo você a experimentar com esse valor para ver que tipos de resultados você pode obter. Mas eu vou usar esse glow_multiplier para criar uma mistura que eu vou atribuir à cor atual. Eu vou dizer que cor é igual a mistura entre qualquer que seja a cor atual, que é este gradiente que nós configuramos aqui, e eu quero uma mistura entre essa cor e o current_blob_color nesta posição com um fator que depende o glow_multiplier e a influência que as blobs têm sobre o ponto específico que estou vendo atualmente. Eu vou dizer pow, glow_multiplier vezes influência, que é a influência dessas blobs têm nesta posição atual, e então eu vou aumentar isso para dizer o quinto poder, então 5.0, e então eu vou adicionar um ponto-e-vírgula. Você pode ver que isso adicionou uma bela aura ao redor das bolhas. Você também pode ajustar esse valor 5.0 ao seu gosto. Mas se eu aumentar para dizer, 25, o brilho desaparecerá completamente. Enquanto que se eu reduzi-lo em um, o mesmo não é elevá-lo a qualquer tipo de poder, você pode ver que o brilho agora é enorme. A razão para isso, porque normalmente, você pensaria que elevar algo a um poder maior o tornaria maior. A razão para isso é que glow_multiplier vezes influência é muitas vezes um valor menor que um. Multiplicando um valor menor que um por outro valor menor que um, é claro, vamos reduzir o valor. Por exemplo, a menos que estejamos realmente perto do centro de uma bolha, como se estivéssemos nesta região brilhante, influência será um número muito pequeno. Mesmo multiplicando pelo limiar vezes 10, ainda é menos de um. Então, realmente, um valor que é perfeito é, eu não sei, talvez em algum lugar por volta das seis ou sete. Realmente o que eu estou tentando fazer aqui é apenas fazer algo que apenas suaviza a borda um pouco. Eu gosto de sete. Só que eu posso ajustar rapidamente isso, eu vou fazer um novo uniforme float glow_power. Vou voltar e fazer com que ele tenha um valor padrão de sete, que é o que eu não tinha atribuído lá em baixo, então agora você pode ver que ele restaurou o brilho que eu tinha e agora, eu posso apenas ajustar esse valor para que você possa ver que o menor fazer isso, quanto maior o brilho fica, e quanto maior eu faço, mais sutil o brilho se torna. Eu ainda gosto de um valor em torno de sete, apenas para suavizar essa borda um pouco e eu vou deixá-lo assim por enquanto. Mais uma vez, porém, ajustar e brincar com esses números é tudo parte do processo. Estou realmente curioso para ver o que você pode fazer mexendo com esta função um pouco. Na próxima lição, adicionaremos uma base de lâmpada de lava. 8. Adicione uma base: Nesta lição, vamos mudar para o uso de uma base de lâmpada de lava. Para começar, vou substituir este ícone dot png que estou usando atualmente com a base da lâmpada de lava que você pode encontrar na seção de recursos do projeto. Você também pode criar sua própria base de lâmpada de lava. O importante sobre esta imagem é que ela tem uma cor sólida que você deseja substituir com nosso sombreador globo de lâmpada de lava. Para adicionar sua imagem base da lâmpada de lava ao projeto Godot, você pode arrastar o arquivo para o sistema de arquivos aqui no canto inferior esquerdo, ou você pode adicionar esse arquivo à sua pasta em sua área de trabalho representando o projeto da lâmpada de lava. Eu salvei a imagem base da lâmpada de lava na minha área de trabalho, então eu vou apenas arrastá-la para o sistema de arquivos no canto inferior esquerdo. Agora você verá que ele diz, “lava lamp base dot png” diretamente na pasta res do sistema de arquivos. Vou clicar no meu nó “Sprite”, e onde diz Textura aqui, vou arrastar a base da lâmpada de lava para a Textura. A imagem base da lâmpada de lava que eu criei é muito, muito maior do que o ícone dot png. Ele tem uma tonelada a mais pixels, e se eu diminuir o zoom usando a roda do mouse, você pode ver que esta é uma lâmpada de lava bastante longa agora. Você também pode ver que os blobs são muito, muito pequenos agora, e isso é porque estamos dimensionando tudo pelo tamanho de pixel de textura, então a distância até o centro de blob é praticamente enorme onde quer que você vá. Para corrigir isso, vou criar um novo flutuador uniforme chamado força máxima e vou ajustá-lo para 16 por enquanto. Vou multiplicar a força máxima aqui em baixo. Pegue a força central da bolha para cada bolha, eu só vou multiplicá-la pela força máxima. Como todos esses valores para o componente de força não são mais do que um, essa é, de fato, a força máxima que um blob individual terá. Você pode ver que isso fez nossas bolhas de volta ao tamanho normal. Mas eu também posso entrar em meus Parâmetros de Shader e ajustar isso como eu quero, para torná-los maiores ou menores. Vou configurá-lo de volta para 16 por enquanto ou clique no botão de reset. A próxima coisa que vou fazer é reduzir o sprite para que ele se encaixe dentro desta caixa azul, que atualmente representa o tamanho da tela. Por enquanto, eu vou apenas definir isso para 0.4 e 0.4. Eu posso ver que isso ainda está um pouco fora da caixa, então eu vou digitar em 0.3 e 0.3. Agora estamos dentro dos limites azuis, e temos esta lâmpada de lava básica. Mas agora, já que estamos substituindo a cor em todos os lugares, não podemos realmente ver a base da lâmpada de lava em si. É por isso que eu disse que é importante que o globo da lâmpada seja uma cor sólida. Se eu rolar para cima e olhar para a textura, eu criei esta base de lâmpada de lava e você pode ver que a área que eu quero substituir com o meu sombreador é perfeitamente magenta. No meu fragmento sombreador, o que eu quero fazer é primeiro usar a cor da textura neste ponto atual, e então se a cor da textura neste ponto atual é perfeitamente magenta, então fazer todas essas coisas que já escrevemos. Para fazer isso, primeiro eu vou dizer, “cor é igual” e, em seguida Godot tem uma função de textura embutida para ler cores de texturas, e então eu vou dizer, “TEXTURE” todas as maiúsculas e “UV” para esta posição atual. Então, se a cor é agora igual a magenta, que é um vetor 4 com 1,0 no vermelho, 0,0 no verde, e 1,0 no azul, 1,0 no alfa, então dentro disso, eu quero fazer tudo isso. Vou fazer o Control X ou o Command X para cortar e colar isso aqui. Então eu vou apenas adicionar um recuo de guia para formatação. Você pode ver que agora temos nosso nível básico e você pode ver que o globo está apenas aparecendo nas áreas que eram magenta. Você pode ver uma borda de magenta indesejada ao redor do globo da lâmpada de lava como eu vejo atualmente. Se fizer isso, clique na guia “Importar” no canto superior esquerdo, verifique se a base da lâmpada de lava está selecionada como sendo importada e, em seguida, certifique-se de que Filtro e Mipmaps estão desativados. Desmarquei Filtro e vou pressionar “Reimportar”. Agora você pode ver que essa borda de magenta indesejada agora se foi e eu tenho um limite perfeito entre o cinza do fundo e meu globo de lâmpada de lava. A próxima coisa que eu quero consertar é que atualmente nossas bolhas podem ir até o fundo aqui, e nós não os vemos desde que eles vão para fora onde o globo deveria estar. Para consertar isso e fazer com que nossas bolhas só vão e voltem dentro do contexto deste globo aqui, precisamos fazer dois uniformes novos. Eu vou dizer “uniforme flutuante top” e eu vou atribuir isso a cerca de 0,2. Parece que talvez isso seja 20 por cento aqui, de cima para baixo, talvez isso seja 20 por cento, então eu vou dizer 0.2. Em seguida, o fundo flutuante uniforme, se isto é 0,2, talvez seja cerca de 0,5 aqui. Isto parece que talvez seja cerca de 0,6. Eu vou dizer 0,6 ou cerca de 60 por cento através de cima para baixo. Isto é o que eu vou usar atualmente para cima e para baixo, mas como eles são uniformes, novamente, para baixo em nossos Parâmetros Shader, eles são realmente fáceis de ajustar. Agora eu quero ter certeza de que nossa função oscilar retorna apenas como valores y entre o nosso topo e o nosso fundo. O que eu vou dizer é vezes fora do poder, eu vou dizer “vezes parênteses abertas, inferior menos topo”. Atualmente, essas escalas são função seno por 0,4 e então eu vou adicionar topo a ele. O que isso faz atualmente é escalar nossa função senoidal 0,4 e, em seguida, mudar a função para que seu valor mínimo de retorno seja 0,2. Você pode ver que esta nova função nos dará valores entre 0.2 e 0.6. Novamente, como estes são uniformes, posso ajustar seus valores na seção Parâmetro do Shader. Talvez o fundo esteja mais perto de, sei lá, 0,54. Então eu posso ter o fundo de 0,54 e as bolhas não vão abaixo desse nível. Eu também poderia aumentar o topo para ser talvez perto de 0,5, e então você pode ver que as bolhas não vão acima desse nível. Vou redefinir aqueles de volta para 0.2 e 0.6, mas saiba que você pode mexer com aqueles se você usar talvez uma base diferente para obter o valor que oscila perfeitamente as bolhas entre o topo e o fundo. Você também deve ter notado que nosso gradiente nos blobs ainda não leva em conta os novos top e bottom. Este valor aqui na parte inferior definitivamente não é igual à cor que definimos aqui para o nosso fundo blob. Se eu descer até onde eu estou falando sobre esse gradiente aqui, eu quero dimensionar os pesos que estamos usando para nossa função mista aqui. Em vez de depender apenas de UV dot y, que é um aqui embaixo, eu quero que um fique bem aqui, e eu quero que zero esteja aqui. O que eu preciso fazer é levar em consideração o topo e o fundo do globo. Para fazer isso, vou dizer “UV dot y menos top”. Agora eu já fiz isso para que o topo da nossa lâmpada agora é zero. Digamos que se estamos aqui e estamos em 0.2, agora estamos subtraindo o topo, que eu disse ser 0,2, então agora isso é zero. Eu quero escalar isso por baixo menos topo. Você pode ver que agora temos o gradiente correto. A razão para isso é que então eu estou no topo aqui, eu tenho 0.2, UV dot y é 0,2, 0,2 menos 0,2 é 0 então isso avalia a zero, então estamos completamente dependentes da cor superior blob. Mas se estamos no fundo, então UV é atualmente 0,6, o que é avaliado como um. Você também pode ver que se eu fosse dizer mover o fundo mais alto, Eu poderia fazer mais e mais da lâmpada amarela, ou se eu mover o topo mais baixo, Eu posso fazer mais e mais da lâmpada que cor vermelha. Na próxima lição, vamos exportar quadros de nossa lâmpada de lava para arquivo PNG. 9. Os quadros de exportação para PNGs: Nesta lição, vamos exportar quadros de nossa lâmpada de lava para PNGs. Agora certifique-se de que sua lâmpada de lava é exatamente como você quer. Então sinta-se livre para ajustar todas as cores e a parte superior e inferior e a força e todos esses tipos de coisas para ter certeza de que a lâmpada de lava é exatamente como você quer que ela seja exportada para um GIF. Eu vou diminuir a força máxima um pouco porque eu sinto que agora que eu tenho apertado tudo entre 0,2 e 0,6, há apenas um monte de cera em comparação com um monte de cores de fundo. Então eu vou diminuir a força máxima para talvez cerca de 12, talvez um pouco mais de 12. Vamos tentar, 14. Sim, esse valor parece bom para mim, então eu vou manter esse valor e seguir em frente para tentar fazer um GIF com isso. O que eu quero fazer em seguida é ajustar o tamanho da janela aqui, esta caixa azul para baixo para ser exatamente o tamanho da minha lâmpada de lava. Posso fazer isso olhando aqui para a textura. Tenho 512 por 1584, e atualmente tenho uma escala de 0,3 e 0,3. Eu vou lembrar esses números, e eu vou para o projeto no canto superior esquerdo e, em seguida, Configurações do projeto. Role para baixo até Janela, e onde ele diz largura e altura, eu quero que minha largura seja 512 vezes 0.3. Então eu quero a minha altura para ser 1584 vezes 0.3 e, em seguida, fechar. Você pode ver que minha caixa azul, se eu desmarcar essa luz, agora é a mesma que meu contorno Sprite, que é exatamente o que eu quero. Em seguida, vou passar para o canto superior esquerdo novamente e pressionar Scene para alternar para a guia cena. Clique em “My Sprite” e pressione este botão para adicionar um novo script. Vamos escrever um script que emite arquivos PNG para cada quadro que renderizamos da lâmpada de lava. Eu estou bem com Lamp.gd sendo o nome deste script então eu vou pressionar “Criar”. Então eu vou escrever uma nova função que salva quadros para PNGs. Lembre-se de que estamos trabalhando no gdscript agora, que não é a mesma linguagem em que estivemos trabalhando antes, então as coisas parecem um pouco diferentes. Vou escrever uma nova função chamada Save frame dizendo func save_frame (): enter. Agora nossos blocos de código são definidos por indentação e não por colchetes. Então, sempre que salvar quadro é chamado, eu quero capturar a textura que está sendo renderizada atualmente para a janela de exibição e salvá-la como um PNG. Primeiro, criarei uma variável para armazenar os dados da imagem. Eu vou dizer var image=. Então, para obter esta imagem, eu quero obter a textura atual do que está sendo renderizado para fora da janela. Esse é o ponto de vista superior do motor de jogo Godot. Então eu vou dizer get_tree () para obter toda a árvore de cena , .get_root () para obter o elemento mais alto ou o viewport, e então eu vou dizery.get_texture () para obter a textura desse viewport, e então.get_data (), para obter os dados da imagem atual de Essa textura. Preciso converter essa imagem em uma que preserve a transparência. Eu vou fazer uma nova linha e então eu vou dizer image.converge para alterar o formato desta imagem, imagem com um capital I dot RGBA8. Então eu quero este aqui, FORMAT_RGBA8. Este formato preservará, de facto, a transparência que desejamos. Agora eu vou salvar o PNG, então eu vou fazer image.save_png. Por enquanto vou digitar *frame.png* como uma string. Agora eu quero chamar essa função salvar frame sempre que um novo quadro tiver sido renderizado. Então, na função ready que é chamada quando o nó entra na árvore de cena pela primeira vez, então, quando o nosso jogo começa pela primeira vez, eu vou substituir pass com VisualServer.connect e eu quero este *frame_post_draw sinal* e eu quer se conectar a esse sinal para um método neste objeto, então eu vou digitar self, e eu quero nosso novo método save frame. Então vou digitar *save_frame* como uma string. Agora o que isso vai fazer é toda vez que o servidor visual nos diz que ele acabou de desenhar um quadro, ele chamará o método de quadro salvo neste objeto. Então, toda vez que um novo quadro foi desenhado, o método de quadro salvo será chamado, vamos obter a textura da viewport atual, e salvá-lo como uma imagem. Especificamente para frame.png. Vou pressionar o botão de reprodução para renderizar um novo quadro. Vou fechar a janela que apareceu. Você pode ver que agora no sistema de arquivos e no canto inferior esquerdo, há uma nova imagem chamada frame.png. Vou clicar duas vezes nele para obter uma pré-visualização. Você pode ver aqui à direita, nós temos dois problemas. Primeiro, o fundo não é transparente, é esta cor cinza aqui, e dois, foi virado de cabeça para baixo. Primeiro, vamos corrigir o problema de transparência. Vá para Projeto e, em seguida, configurações do projeto no canto esquerdo e, em seguida, sob transparência por pixel na guia Janela, verifique por transparência de pixel permitida e por transparência de pixel ativada. Em seguida, pressione “Fechar”. Então em nosso script antes de nos conectarmos ao servidor visual, precisamos obter nosso viewport novamente, que é exatamente o que fizemos aqui, get_tree () get_root (). Então vamos dizer get_tree () .get_root () e então.set_transparent_background (true) e queremos definir isso como true. Vou pressionar o botão play para renderizar outro quadro, fechar a janela que aparece, clique duas vezes em frame.png e agora você pode ver que, de fato, temos um fundo transparente agradável lá. Dependendo do seu sistema, o seu pode não estar de cabeça para baixo, mas o meu está. Então, depois de converter o PNG, mas antes de salvá-lo, eu quero digitar imagem. flip_y, e eu quero chamar o método flip_y na imagem para que ele vai virar de cabeça para baixo. Vou pressionar o botão play novamente para renderizar mais um quadro, fechar a janela que aparece e, em seguida, clique duas vezes em frame.png e agora você pode ver que eu tenho meu quadro muito agradável aqui. É perfeitamente para a direita, eu tenho um fundo que é transparente, e geralmente parece muito bom. Mas o que eu realmente quero é uma tonelada de quadros individuais para compilar em um GIF animado. Agora estamos apenas substituindo frame.png todas as vezes. Então eu vou definir uma nova variável membro acima no topo chamado var frame_count = 0 e eu vou defini-la como zero para começar. Agora, a fim de controlar o número de quadros que meu GIF de saída é, eu só vou salvar o quadro se a contagem de quadros estiver abaixo de um determinado nível. Acima da seção de variáveis de membro, eu vou definir uma nova constante que não vai mudar, e eu vou definir isso para MAX_FRAMES = 60 em todas as maiúsculas, e eu vou definir isso para 60 por enquanto. Em seguida, em nosso método save frame, eu vou digitar abaixo image var image_name, e eu vou atribuir isso a uma string vazia por enquanto. Agora, apenas para ter certeza de que nossos quadros de saída são classificados na ordem correta, eu vou escrever para i no intervalo (), e então eu vou dizer o comprimento da string de MAX_FRAMES menos o comprimento da string de nosso contagem de quadros. Para cada um deles, eu quero acrescentar um zero ao início do nome da imagem. Em seguida, fora deste for-loop, eu vou fazer image_name plus é igual à string da contagem de quadros atual e, em seguida, mais. PNG. Em seguida, em vez de salvar a imagem como frame.png, eu vou salvá-la como (image_name). Por último, adicionarei um à contagem de quadros. Mais é igual a um. Mas eu só quero salvar este PNG se nossa contagem de quadros atual for menor que MAX FRAMES. Então eu só vou fazer tudo isso se frame_count for menor que MAX_FRAMES. Então, como estamos trabalhando com recuo, vou destacar tudo isso e pressionar Tab para recuar. Estamos economizando 60 quadros da nossa lâmpada de lava. Mas se o Godot está recebendo 60 quadros por segundo, isso significa que nosso GIF tem apenas 1 segundo de duração, então eu queria reduzir os quadros alvo do Godot por segundo. Então, na função de pronto, eu vou digitar motor, definir FPS alvo, e eu vou definir isso para 15. Isso significa que Godot terá como alvo 15 quadros por segundo e se economizarmos 60 quadros, isso significa que temos cerca de quatro segundos de tempo de execução da lâmpada de lava. Na verdade, vou voltar e aumentar isso um pouco mais para fazer 120 por oito segundos de tempo de funcionamento da lâmpada de lava. Em seguida, pressione o botão play e deixe a janela que aparece funcionar durante oito segundos ou mais. Uma vez que passaram pelo menos oito segundos, feche a janela e verá que Godot está importando todos os nossos quadros. Então, se eu descer para o nosso sistema de arquivos aqui no canto inferior esquerdo, você pode ver que temos todos os 120 quadros começando em 000.png e indo todo o caminho para um 119.png. Agora queremos converter todos esses arquivos PNG em um arquivo.GIF que irá animar. 10. Converter PNGs para GIF: Nesta lição, converteremos nossos PNGs exportados em um GIF animado perfeito. Abra seu navegador e acesse um site que pode gerar GIFs animados a partir de PNGs. Eu recomendo usar ezgift.com/maker. Quando você estiver no site, pressione “Procurar” para fazer upload de suas imagens PNG. Depois de selecionar seus PNGs, pressione “Fazer upload e fazer GIF”, então você verá todos os PNGs da lâmpada de lava aqui. Se você rolar até a parte inferior, certifique-se de definir o tempo de atraso como zero e, em seguida, pressione “Criar um GIF”. Quando o GIF for carregado, pressione “Efeitos”, role para baixo e onde estiver escrito Animation Flow, marque a caixa ao lado de Executar até o fim e reverta para o início. Em seguida, pressione “Aplicar selecionado” e seu GIF de saída irá loop perfeitamente. Depois de fazer isso, pressione o botão “Salvar” e salve seu novo GIF no computador. Este é um projeto que oferece toneladas de oportunidades para experimentação. Quanto mais você mexer com ele, melhor será a compreensão de como os shaders funcionam no Godot Game Engine. Eu realmente encorajo você a fazer isso. Na próxima lição bônus, vamos rapidamente ver como deixar sua lâmpada de lava acesa no canto da tela enquanto você faz seu outro trabalho. 11. (Bônus) adicione a lâmpada Lava à sua tela: Nesta lição bônus, vamos rapidamente analisar como você pode executar a lâmpada de lava no canto da tela enquanto você faz seu outro trabalho. Vou começar comentando esta linha de conexão para torná-la de modo que não estamos mais exportando nossos quadros. Eu uso a libra ou o símbolo hashtag para comentar a linha. Então eu vou até Projeto, Configurações do Projeto. Role para baixo até Modo Esticado. Vou dizer “2d” e “Fechar”. Agora, se eu pressionar o botão “Play”, posso redimensionar minha lâmpada de lava. Eu posso arrastá-lo por aí, e posso dimensioná-lo de volta como eu quiser. Quando você redimensiona a janela, a proporção das lâmpadas de lava fica um pouco desligada. Para corrigir isso, vá para Projeto, Configurações do projeto e, em seguida, onde ele diz Aspect em Stretch, mude de “Aspect Ignore” para “Aspect Expandir”. Agora, quando você executa a lâmpada de lava, a lâmpada de lava sempre permanecerá a mesma proporção, mas ainda pode aumentar de tamanho. No entanto, se eu clicar no “Godot Game Engine”, ou em qualquer outra janela, minha lâmpada de lava vai atrás dela. O que eu vou fazer é ir para Projeto, Configurações do Projeto e, em seguida, marcar “Sempre no topo”. Se você não quiser que ele seja redimensionável, você pode desmarcar “Redimensionável”, e se você quiser que ele seja sem fronteiras, você pode marcar “Sem fronteiras”. Vou em frente e fazer isso por enquanto. Então, agora, se eu reiniciar, você pode ver a lâmpada de lava funciona no centro da minha tela e não tem nenhum dos limites de Godot nele. Vou pará-lo pressionando o sinal de stop. Em seguida, vamos para Editor no canto superior esquerdo e, em seguida, Configurações do Editor. Em Configurações do Editor, se eu rolar para baixo até Executar e depois Colocação da Janela, você pode ver que Rect está definido como Centrado, razão pela qual nossa lâmpada de lava está sendo executada no centro da tela. Eu posso definir isso para a posição personalizada e, em seguida, obter o tamanho da minha tela, que no meu caso é 1920 por 1080. Então eu posso dizer 1920 menos a coordenada X da nossa lâmpada de lava está brilhante, então menos 153. Então podemos dizer 1080 menos 475. Eu gostaria de subtrair um pouco mais desse número só para explicar esta barra na parte inferior aqui. Então vou subtrair 20 adicionais de 605. Então eu carrego “Fechar”, “Replay”. Agora você pode ver a lâmpada de lava funciona no canto da minha tela. Eu poderia até minimizar Godot e ter a lâmpada de lava rodando na minha área de trabalho ou eu poderia abrir o Firefox. A lista continua. Basicamente, a lâmpada de lava fica no canto inferior direito da minha tela. Se eu quiser fazer isso para que eu possa mover a lâmpada de lava ao redor, eu vou voltar para Projeto, Configurações do Projeto e depois desmarcar “Sem Borderless” e reiniciar. Agora, se eu quiser, posso arrastar o candeeiro de lava para colocá-lo em qualquer lugar que eu quiser. Mas ele ainda permanece no topo desde “Always On Top” é verificado para que eu ainda possa minimizar Godot e fazer outras coisas. É só que agora eu também posso arrastá-lo por aí se acontecer de ficar no caminho. Assim é como adicionar uma lâmpada de lava ao canto inferior direito da tela, uma vez que você já a criou usando o Godot Game Engine. Eu acho que é muito divertido, apenas um pouco de entretenimento passivo enquanto você está fazendo seu outro trabalho. Além disso, é um começo de conversa muito legal se acontecer de você compartilhar uma tela em uma chamada de Zoom ou algo assim. Obrigado por conferir a lição bônus. Vejo você no próximo vídeo para alguns pensamentos finais. 12. Considerações finais: Obrigado por checar a aula. Se você ainda não fez isso, certifique-se de postar seu presente de lâmpada de lava na galeria do projeto da classe. Eu realmente espero que você tenha se afastado disso com uma melhor compreensão de como os shaders de fragmento 2D funcionam. Eu realmente apreciaria qualquer feedback que você tem. Por favor, considere deixar um comentário aqui no Skillshare e siga-me se quiser mais aulas como esta. Você também pode me informar o que você gostaria de ver a seguir por meio do questionário na guia Discussões ou na página do meu Perfil. Te vejo na próxima vez.