Sombreadores 2D en Godot para el desarrollo de juegos: cómo codificar una lámpara de lava animada | Isaac B. | Skillshare

Velocidad de reproducción


1.0x


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

Sombreadores 2D en Godot para el desarrollo de juegos: cómo codificar una lámpara de lava animada

teacher avatar Isaac B., Software and Game Developer

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Código de una lámpara de lava

      1:19

    • 2.

      Observar una lámpara de lava

      0:49

    • 3.

      Configura el motor

      1:43

    • 4.

      Crea un calzado y un sombreado

      8:15

    • 5.

      Crea algunos Blobs

      12:05

    • 6.

      Animar las Blobs

      6:26

    • 7.

      Añade colores

      9:32

    • 8.

      Añade una base

      8:02

    • 9.

      Exportar cuadros a PNGs

      9:54

    • 10.

      Convierte PNGs a un GIF

      1:02

    • 11.

      (Extra) añade la lámpara de lavava a tu pantalla

      3:38

    • 12.

      Reflexiones finales

      0:23

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

373

Estudiantes

15

Proyectos

Acerca de esta clase

En esta clase, aprenderemos a hacer sombreados en el juego Godot Engine través de un proyecto de lava super El Godot Game Engine es un ingenio suave, gratuito y abierto.

Esta clase sirve como una introducción a los sombras de fragmentos 2D, que se utilizan en el desarrollo de juegos para lograr efectos visuales neos Ser capaz de escribir sombreadores es una valioso habilidad que puede añadir mucho tono a tus proyectos de juego, y después de crear la lámpara lava, tendrás una buena comprensión de cómo funcionas.

Escribiremos nuestro código de lámpara de lava en el lenguaje de sombreado de Godot, que es muy similar a la GLSL, el lenguaje shading Al final de la clase, crearemos un bucle GIF sin fisuras de tu lámpara lava personalizada, para compartirlo con la galería de proyectos

Como extra, incluso te mostraré cómo puedes hacer tu lámpara de lava en tu escritorio mientras haces otras cosas (similares a Shimeji.)

Aunque debes poder seguir sin experiencia Si tienes algún problema, déjelo saber a través de la pestaña de discusiones y aseguraré de ayudarte a resolver.

Próximo clase:

Conoce a tu profesor(a)

Teacher Profile Image

Isaac B.

Software and Game Developer

Profesor(a)
Level: Intermediate

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Código de una lámpara de lava: Hola, soy Isaac y hago juegos de Posadero. En esta clase, crearemos una lámpara de lava completamente digital utilizando shaders y el motor de juego Godot, que es un motor de juegos gratuito y de código abierto. El objetivo aquí es el juego y la experimentación. Hay toneladas de posibilidades para tu lámpara de lava mientras la estás codificando y después del hecho. Se pueden cambiar cosas como el tamaño y la velocidad de los blobs, el color de fondo, los colores de primer plano, los gradientes, el resplandor de cada blob individual, así como la base misma. Estaremos escribiendo nuestro código de lámpara de lava usando el lenguaje de sombreado Godot, que es muy similar a GLSL, el popular OpenGL Shading Language. Al final de la clase, crearemos un GIF de looping sin fisuras de tu proyecto de lámpara de lava para compartirlo en la galería de proyectos y en otros lugares. Como bono, incluso te mostraré cómo puedes mantener tu lámpara de lava funcionando en tu escritorio. Esta clase sirve como introducción a los sombreadores de fragmentos 2D, que a menudo se utilizan en el desarrollo de juegos para lograr efectos visuales aseados que se ejecutan rápidamente a través del procesamiento paralelo. Poder escribir shaders es una habilidad valiosa que puede agregar mucho estilo a tus proyectos de juego, y después de haber creado tu lámpara de lava, tendrás una comprensión bastante buena de cómo funcionan. Tendré cuidado en explicar cada paso en detalle, pero alguna experiencia previa con motores de codificación o juegos en general sería muy útil para su comprensión. Si te encuentras con algún tema, por favor avísame en la pestaña de discusiones y me aseguraré de ayudarte. Con eso, empecemos. Asegúrate de que me estás siguiendo aquí en Skillshare para más clases de desarrollo de juegos como esta. En nuestra primera lección observaremos una verdadera lámpara de lava para averiguar cómo la vamos a emular con nuestro código shader. 2. Observar una lámpara de lava: Echemos un vistazo a esta lámpara de lava para referencia antes de empezar a codificar. Una, la lava se separa en una distintiva manchas esféricas, estirando, separando, y fusionando. Usaremos algo similar a los metaballs para lograr este efecto. Dos, la lava tiende a fluir rápidamente, arriba o abajo, ralentizar cuando llega a un punto final y eventualmente cambia de dirección. Veremos algunas funciones matemáticas que oscilan así a lo largo del tiempo. Tres, la lava es realmente brillante en la parte inferior y un color completamente diferente en la parte superior. Parece brillar un poco. Podemos tratar de usar aquí algunos gradientes para imitar ese efecto. Cuatro, de igual manera, la solución alcohólica es más brillante en los bordes de la lámpara y más oscura en el medio. De nuevo, podemos tratar de utilizar gradientes aquí. Tendremos presentes estas ideas a medida que empecemos a codificar. En la siguiente lección, descargaremos y configuraremos Kidlo para que podamos empezar. 3. Configura el motor: En esta lección, descargaremos el motor y configuraremos un proyecto básico. Si aún no tienes el motor de juegos Godot, puedes obtenerlo en Godotengine.org, haz clic en Descargas y encuentra la descarga que coincida con tu sistema operativo y la arquitectura de tu sistema. También puedes descargar el motor de Steam. Si lo haces, vendrá precargado con un montón de demos que puedes revisar para ver cómo funcionan los proyectos básicos. Adelante y corre el motor si no lo has hecho ya. Si descargó la imagen de Godot del sitio web, una vez que la haya extraído del archivo zip e intente ejecutarla por primera vez, podría encontrarse con una advertencia de seguridad de su sistema operativo. En Windows, puede tranquilizar a Windows Defender presionando más información y luego ejecutar de todos modos. Godot es software de código abierto, por lo que eres bienvenido a leer el código tú mismo si lo deseas. Este es el gerente de proyecto de Godot. Si descargas el motor de Steam, aquí encontrarás un montón de demos. Desde que descargué el motor de la página web, aún no tengo nada aquí. Voy a presionar este botón Nuevo Proyecto a la derecha. Me gustaría que este proyecto estuviera en mi escritorio así que voy a escribir escritorio aquí. Es posible que tengas que pulsar este botón “Examinar” para encontrar una carpeta en la que te gustaría poner tu proyecto Godot. Godot está diciendo: “Por favor, elige una carpeta vacía”, porque piensa que quiero poner los archivos directamente en mi escritorio. Se querría poner cosas como mis sprites y texturas justo al lado de la papelera de reciclaje, que no es lo que quiero. Claramente, el escritorio no está vacío. Se, al menos, contiene el atajo de la papelera de reciclaje. Voy a escribir Lava Lamp en la sección de nombre del proyecto y presionar este práctico botón “Crear carpeta”, y ahora Godot ha creado una carpeta llamada Lava Lamp en mi escritorio para que todos los archivos del proyecto para este proyecto puedan vivir directamente en eso carpeta. Dado que no necesito que esta aplicación se ejecute en un entorno web, voy a dejar la opción de render predeterminada. En la siguiente lección, presionaré este botón y crearemos nuestra estructura de proyecto y comenzaremos a escribir nuestro código de sombreado. 4. Crea un calzado y un sombreado: En esta lección, configuraremos una estructura de proyecto y comenzaremos a escribir algún código de Shader. Voy a presionar el botón “Crear y editar”. Este es el Editor Godot. En el medio verás básicamente una representación de la escena actual que estás creando. Por aquí a la izquierda, tenemos la opción de crear el nodo raíz para esta escena. En Godot, los nodos representan pequeños bloques de construcción de juegos. Son nodos para crear imágenes, personajes, elementos de interfaz de usuario, animaciones, y más. Ya que estamos enfocados en escribir un Shader para este tutorial, realmente no necesitamos muchos nodos, pero sí necesitamos al menos un nodo al que podamos aplicar nuestro Shader. Este nodo también debe dibujar nuestra base de línea de nivel cuando lleguemos a ese paso. Podemos escribir Shaders 2D a través de materiales para cualquier nodo que hereda de un elemento de Canvas. Para mostrarte cuáles son estos nodos, voy a presionar “Otro nodo”. Este es un árbol entero que consiste en finalmente todos los nodos que Godot tiene en oferta. Estamos buscando cosas que hereden del artículo de Canvas. Cosas que existen debajo de este menú desplegable llamado elemento de lienzo. Voy a ir por Node2D y todo el camino por la parte inferior Sprite, porque también quiero renderizar la base de la lámpara de lava y luego renderizar nuestro Shader en una parte específica de la base. Voy a presionar “Crear” para hacer un Sprite. Ahora puedes ver tengo a ese Sprite por aquí a la izquierda como el nodo raíz para mi escena actual. Por aquí a la derecha, tenemos acceso a más propiedades para el nodo que acabamos de crear. En la parte superior aquí puedes ver estas son propiedades que son específicas del nodo Sprite, justo debajo de eso tenemos propiedades que son específicas de todos los Node2Ds, y siendo que tenemos propiedades que son específicas de todos los elementos de Canvas. Por supuesto, de nuevo, todos los nodos. De nuevo, eso es porque si volvemos atrás y miramos el árbol, tenemos nodo en la parte superior del árbol, elemento de lienzo debajo de eso, y Node2D debajo de eso. Estas son las propiedades para Sprites, estas son las propiedades para Node2Ds, estas son las propiedades para los elementos de Canvas, y estas son las propiedades para todos los nodos. Voy a presionar “Cancelar” porque sólo quería mostrarte el árbol. Desde que creé un nodo 2D como el nodo raíz para la escena, Godot nos cambió automáticamente a la vista 2D. Esta caja azul aquí representa el tamaño de la pantalla que sucederá cuando presione “Play” para depurar el juego. Se puede ver que tengo seleccionado el Sprite, por lo que este crosshair aquí representa la ubicación actual del Sprite. Actualmente no está renderizando ninguna textura, y se puede ver eso al ver también que la textura está vacía. Voy a arrastrar icon.png a la propiedad Sprite, y ahora se puede ver que icon.png se está renderizando como la textura de este Sprite. Solo vamos a usar icon.png temporalmente para ver cómo funcionan los Sprites y también para escribir nuestro primer código Shader solo para sobrescribir la textura básica. Se puede ver que el nodo Sprite ahora se extiende fuera de la caja azul que creamos. Se puede ver que el Sprite ahora se extiende fuera de la región, marcado por el cuadro azul por lo que eso significa que mucho de esto en realidad no se renderizará en la pantalla. Voy a ejecutar el juego pulsando el botón “Jugar”. Se va a quejar porque no he puesto una escena principal. Porque este es un proyecto muy sencillo para las demostraciones de Shader. Para salvar mi trabajo, voy a hacer “Control S”. Podrías hacer “Command S” si estás en un Mac. Para guardar mi trabajo hasta el momento, voy a ir a Escena y presionar “Guardar escena”. Ya que no he guardado esta escena antes, me está pidiendo un nombre. Sólo voy a llamarlo lamp.scn y presionar “Guardar”. También puedes ver ahora que lamp.scn ha aparecido en los archivos del proyecto. Si yo presionara “Play” aquí arriba, Godot me advertiría que nunca he definido una escena principal. Esto se debe a que la forma en que los juegos suelen estar estructurados en Godot, esos son root visto que el juego corre como lo fundamental de lo que todas las demás escenas en nodos son hijos de. Todavía no hemos definido uno de esos, por lo que necesitamos seleccionarlo. De nuevo elegiré lamp.scn que acabamos de crear, y presionaré “Abrir”. Porque por defecto el origen de un Sprite es 00 el centro del objeto, se puede ver que el Sprite está siendo cortado en tres de los cuatro cuadrantes. Voy a cerrar eso. Volviendo a nuestro proyecto, podemos mirar el offset y desmarcar centrado. Ahora puedes ver que el Sprite encaja por completo dentro de esta caja azul, que representa el tamaño de pantalla que obtendrás cuando juegues el juego. Ahora empecemos a escribir algún código Shader. Dije antes que podemos escribir código Shader para cualquier nodo que hereda de un elemento de Canvas. Buscaré aquí las propiedades de todos los nodos que heredan del elemento Canvas, y debajo del material, se puede ver que actualmente dice, material vacío. Haré clic en esta flecha desplegable y presionaré “NewShaderMaterial”. Verás una vista previa del material básico que acabamos de crear aquí en esta esfera. Voy a dar clic en él, y luego donde dice Shader, voy a hacer clic en la flecha desplegable y definir un nuevo Shader. Entonces haré clic en el “Shader”, y se puede ver que se ha abierto una pequeña ventana de código aquí. Actualmente tenemos un error. Dice que esperaba un tipo Shader al inicio de Shader, tipos válidos de nuestro artículo Canvas, partículas y espacial. Estamos escribiendo un CanvasitemShader, así que voy a escribir Shader type: Canvas item, y un punto y coma para indicar que he terminado con la línea. Se puede ver que eso hizo desaparecer el error. Es importante tener en cuenta que lo que estamos escribiendo aquí no es el guión de Judy, que podría haber utilizado en un video tutorial de mi parte anterior. Pero un lenguaje creado específicamente para escribir Shaders en Godot. Es similar a GSL si alguna vez has usado eso. Empecemos definiendo un fragmento Shader que simplemente establece el color en cada punto cubierto por el Sprite en blanco. Voy a acercar un poco el Sprite usando la rueda del ratón y mantenga presionada la rueda del ratón para pin, solo que puedo ver un poco más claramente lo que estoy haciendo. Empecemos por escribir la función de fragmento. Esta función va a escribir va a ser llamada por el motor en cada punto individual en el que se ejecuta nuestro Shader. Primero escribimos, “Vacío”, porque esta función no devuelve nada a la función que codificó, y luego escribiremos, “Fragmento”, porque estamos implementando la función de fragmento. Se puede ver que Godot trató de auto-llenar para mí. La función de fragmento no toma ningún parámetro, por lo que hay paréntesis vacíos ahí. A continuación, abra el soporte rizado, Enter. Ahora este es el bloque de código que se ejecutará siempre el motor llame a la función de fragmento. Para establecer cada fragmento individual cubierto por el Sprite en blanco, escribiré color igual a vec4, lo que significa vector 4 o una colección de cuatro números en este caso. Entonces escribiré, 1.0, 1.0, 1.0, 1.0. Lo que esto significa en este contexto, se puede ver que acaba de actualizarse y ahora está demostrando completamente el blanco es 1.0, lo que significa completamente rojo, 1.0 lo que significa completamente verde, 1.0 lo que significa completamente azul, y 1.0 lo que significa completamente opaco. Este es el valor Alpha, por lo que es RGBA. Cuando decimos que el color es igual al blanco, lo que realmente estamos diciendo es por cada punto en el que se ejecuta este Shader, quiero que el color en ese punto específico sea blanco. Hay una forma abreviada de hacer esto que es escribir vec4 y luego solo un solo 1.0. Voy a borrar todos estos. Se puede ver que eso está bien. El motor apenas está poblando 1.0 en todas las posiciones vec4 de forma automática. En la siguiente lección, crearemos algunas manchas básicas en blanco y negro. 5. Crea algunos Blobs: En esta lección, vamos a crear algunas manchas básicas en blanco y negro. Empecemos ajustando el color de fondo a negro. Dado que el valor RGB del negro es 000, se podría pensar que establecer cero aquí crearía una salida de fondo negro. Pero de hecho, dado que el valor Alpha también se establece cero cuando establecemos los cuatro componentes del vector 4 cero, obtenemos un valor negro con una salida totalmente transparente. Sí necesitamos decir 000, y luego 1.0 en el Alfa. Ahora, tenemos nuestra salida de fondo negro. Ahora quiero agregar algunas manchas blancas. Para ello, necesito anular un color que acabamos de establecer aquí en blanco en las áreas que queremos que aparezcan nuestras manchas. En primer lugar, voy a crear una lista que sólo contenga los puntos centrales de cada uno de esos blobs, así como la fuerza de esa blob, relativamente análoga al tamaño de la blob. Empecemos escribiendo vec3, blob_centers, y quiero que esto tenga actualmente dos elementos para dos blobs, y luego agregue un punto y coma para la nésima línea. Ahora voy a asignar cada uno de estos centros de blob a un punto y una fuerza. Para la 0th blob o la primera blob de la lista, asignaré eso igual a un vector3, y esto es una coordenadas relativas aquí. Si digo 1.0,1.0, y luego imprimir un cero, esto hace referencia a 1.0 Todo el camino, 100 por ciento a través de la textura en el eje x y 100 por ciento por debajo de la textura en el eje y. Actualmente he puesto la fuerza a cero. Digamos que quiero esto tal vez por aquí para 0.6 en la x y 0.6 en la y, o 60 por ciento a través de la textura en ambas direcciones. Pondré la fuerza a 0.5. Voy a hacer algo parecido con el próximo centro de blob. A lo mejor quiero que este sea un poco más a la izquierda. Diré 0.5, 0.55, y luego quiero que esto sea un poco más grande, digamos 0.6. Ahora hemos definido las ubicaciones para dos blobs por aquí y por aquí. Recuerda que el sombreador de fragmentos que estamos escribiendo se ejecuta individualmente en cada punto de esta textura. Lo que quiero hacer es por este punto actual en el que estamos, ver cuánto está influenciado por estos centros de blobs usando la fuerza. Si está influenciado más que un cierto umbral, podemos establecer ese color en blanco. Empecemos midiendo la influencia que cada uno de los blobs tiene sobre este punto individual. Diré flotante para valor de punto flotante, y escribiré influencia y lo estableceré en 0.0 para empezar. A continuación, voy a iterar a través de la lista de blobs para medir cuánto este punto individual se ve afectado por cada uno de ellos. Diré por, paréntesis abierto, int i es igual a 0, porque queremos empezar a contar a cero, i menos que blob_centers.length. Queremos que me quede menos de dos porque esta matriz sólo tiene los índices cero y uno porque tiene dos elementos. Otro punto y coma, y diré i++, para incrementar i por uno después de cada vez que iteramos a través de las manchas. Abriré aquí algunos corchetes rizados, y este es el código que se ejecutará para cada uno de los blobs. Primero, calculemos la distancia desde este centro de blob que estamos actualmente hasta el punto en el que estamos trabajando actualmente. Diré flotante distance_to_blob_center, y diré distancia para la función incorporada buena distancia antigua. Abrir paréntesis y punto y coma. La función de distancia quiere dos posiciones para medir la distancia entre. Voy a decir blob_centers, abrir corchetes, y luego i, porque quiero el blob en el que estamos actualmente, y luego digo.xy para construir un vector con sólo el componente x y el componente y del vector actual. Blob_centers i, si estamos en el 0th en este momento, será 0.6, 0.6 y será un vector también. Entonces quiero medir la distancia entre el centro de blob actual y nuestra posición actual, que está representada por el uv de entrada. Ahora bien, esta función de distancia está bien por ahora, ya que actualmente tenemos una textura cuadrada en el sprite. Pero más adelante, vamos a querer usar una textura rectangular para el sprite para que podamos agregar nuestra base de lámpara de lava. Digamos que la textura eran en realidad de este tamaño, por ejemplo. Recuerda que para las posiciones que estamos usando aquí, blob centers xy y uv, es relativo al máximo general x e y Esto es 1.0 en el eje x, y aunque ahora es un rectángulo, esto es todavía 1.0 en el eje y, ya que es relativo al tamaño general. Esto significa que nuestra función de distancia estará un poco distorsionada. Cuanto más lejos obtenemos de una textura sprite cuadrada perfecta. Voy a dividir cada una de estas posiciones componente-sabia por tamaño de píxel de textura. Para la textura actual, estamos usando icon.png. El tamaño de píxel de textura es también un vector que contiene 1 sobre 64 y 1 sobre 64. Lo que esto realmente está haciendo aquí es multiplicar por componentes una coordenada relativa, representada entre cero y 1.0, por el número de píxeles en cada dirección. Es convertirlo de una coordenada relativa en una posición absoluta sobre la textura. Voy a escalar un sprite hacia abajo a cómo solía ser yendo por debajo del desplegable de transformación 2D nodo, y restableciendo la escala. Ahora agreguemos alguna influencia a este punto en función de su distancia del blob específico. Añada una nueva línea aquí y diga influencia más igual a decir que quiero agregar y reasignar, y luego diré blob_centers i, nuevo, para el blob actual. dirá.z porque sólo queremos este tercer componente, que dijimos representa la fuerza a que tiene este blog en particular. Tu instinto instinto podría ser ahora multiplicar esto por distancia a centro de blob-blob-centro. Pero recuerda que esto significa que cuanto más lejos esté el blob de este punto específico, más grande será este valor, y más grande será la influencia general. Queremos lo inverso de esto. Los puntos más cercanos a la blob deben ser los más influenciados por la blob y más propensos a ser blancos. Lo que realmente queremos es 1.0 dividido por distancia-centro blob-centro. Simplemente captaré eso entre paréntesis, y esto nos dará la relación correcta entre influencia y la distancia desde la blob hasta el punto específico. Ahora, aquí es donde va a pasar un poco de magia. Queremos decir si la influencia está por encima de cierto umbral, queremos cambiar el color de lo que es actualmente, negro a blanco. Voy a correr si la influencia está por encima, digamos, 0.3, queremos poner color a blanco. Recuerda, tenemos esta bonita taquigrafía. Podemos decir vec4, y luego llenar todos esos componentes con 1.0. Ahí. Ahora tenemos algunas pequeñas manchas que aparecieron en la pantalla. Voy a acercar y se puede ver cómo esto está funcionando un poco más claramente. Como esperábamos, tenemos un área de blanco alrededor de cada una de las manchas. Siempre es una buena idea hacer ejemplos para ti mismo para probar tu código y asegurarte de que estás entendiendo cómo funciona todo. Tomemos un punto de ejemplo justo entre los dos centros de blob. Si miro los puntos de mitad de camino entre estos, eso es aproximadamente el punto 0.55 en el eje x, 0.575 en el eje y. Eso es en algún lugar por aquí. Vamos a repasar nuestro código usando eso como ejemplo. Dado que ese es el punto actual que estamos viendo, sus coordenadas estarán en la entrada uv. Ahora, pasemos por nuestro código. En primer lugar, la influencia se establece en 0.0, luego para cada una de las manchas, hacemos esto. Diga para el primer blob, este de aquí, tenemos distancia-blob-centro es la distancia entre los centros blob i, por lo que el blob actual, de nuevo, este uno.xy, por lo que sólo tenemos el 0.6 y el 0.6, dividido por pixel de textura tamaño. En este caso, esto significa componente-sabiamente dividido por 1 sobre 64 y 1 sobre 64, que es lo mismo que multiplicar o escalar este vector por 64. Entonces tenemos lo mismo, pero para uv en lugar de los focos de las manchas xy. Por lo que el uv, de nuevo, actualmente es 0.55 y 0.575. Si calculamos la distancia entre esas dos cosas, obtenemos alrededor de 3.578. Ahora queremos sumar para influir en un valor que corresponda a la fuerza de blob actual y a nuestra distancia del centro de blob. Reemplazamos el componente blob z actual, que es 0.5, multiplican 0.5 veces 1.0 sobre 3.578. Si hacemos esto, obtenemos alrededor de 0.14. Agregamos 0.14 para influir y luego pasamos a la siguiente blob. Ahora estamos en este blob. Ahora volvemos a pasar por los mismos cálculos. Calculamos la distancia al centro de blob, y como el punto que elegimos para ser uv está a mitad de camino entre estos dos centros de blobs, sabemos que sólo va a ser 3.578 otra vez. Entonces agregamos para influir en el componente z blobs actual, que en este caso es 0.6 ahora, y luego multiplicamos eso por 1.0 sobre 3.578 nuevamente. Lo que obtenemos para que la influencia agregue aquí es 0.17. Agregamos 0.17 a la influencia, y ahora tenemos 0.31 como nuestra influencia actual, ya que 0.14 más 0.17 es 0.31. Ahora, moviéndose hacia abajo nuestro código, si la influencia es mayor a 0.3, establecemos el color en blanco. Dado que la influencia es actualmente de 0.31, sí evalúa cierto que ese valor es efectivamente mayor a 0.3, y así establecemos el color en blanco. El punto en el medio entre estas dos manchas es efectivamente blanco. Tan solo para volver a comprobar nuestras matemáticas, también podemos aumentar este valor de 0.3. Diga, quiero que sea 0.31, y puedo ver que el punto entre estos ya no es blanco. Eso se debe a que 0.31 no es mayor a 0.31, y también porque redondeamos un par de veces cuando estábamos hablando de agregar a la influencia. El valor que redondeamos para ser 0.31 no es mayor que el punto 0.31, por lo que no ponemos el color a blanco y sigue siendo negro, como lo dijimos inicialmente. Sólo porque quizá quiera retocar esto más adelante, lo voy a reemplazar por una nueva variable a la que voy a llamar umbral y crear un uniforme arriba en el fragmento arriba arriba arriba arriba. Voy a declarar un nuevo uniforme escribiendo umbral de flotación uniforme. Voy a decir por defecto, vamos a poner eso en 0.3, que es el valor que teníamos antes. Pero por aquí, hay una cosa nueva, un nuevo desplegable llamado Shader Param, y tenemos este nuevo uniforme de umbral que acabamos de definir, la configuración 0.3. Ahora bien, si aumento este valor, se puede ver que efectivamente nuestro shader se actualiza. También puedes hacer clic y mantener pulsado y arrastrar en cualquier dirección, izquierda o derecha, con el ratón para ver como eso se ajusta. Eso simplemente hace que sea realmente fácil ajustar el umbral desde el editor en lugar de desde nuestro código. Al hacer clic en ese botón de reinicio como acabo de hacer solo lo vuelve al valor que estableces igual aquí, es como un valor predeterminado. En la siguiente lección, añadiremos un par de manchas más y las animaremos. 6. Animar las Blobs: En esta lección, añadiremos un par más de manchas y animaremos para que empiecen a parecer un poco más como una lámpara de lava. Para empezar, aumentaré el número de centros de blobs que tengo. Pondré esto en seis en lugar de dos solo para que ahora tengamos seis centros de blob totales. Yo sólo voy a hacer Control C en esta selección para copiar y Control V para pegarlo un par de veces. Dependiendo de tu sistema operativo, es posible que necesites usar Comando V o/y Comando C en lugar de Control, y solo estableceré esto en 2, 3, 4, 5. Ahora efectivamente tenemos seis centros de blob totales. Ya verás que el tamaño de la blob aumentó mucho aquí, y eso es porque agregamos para cada una de las blobs, algunos influyeron en el punto actual. Incluso para los blobs que están lejos de aquí, realmente lejos de cualquiera de los centros de blob, siguen teniendo cada vez más influencia sólo porque hemos agregado más blobs. Es más probable que se les incluya en ese rango de lo que eran antes, simplemente porque hay más. Voy a alejarme un poco usando la rueda del ratón solo para que pueda ver un poco más claramente lo que está pasando, y solo voy a mover un poco las coordenadas x para asegurarme de que pueda ver un poco más claramente dónde están cada una de estas manchas, porque en este momento muchos de ellos tienen exactamente la misma posición. 0.6, 0.5. Digamos que esto está en 0.55, este está en 0.45, este en, no sé, 0.62, este está en, digamos 0.7. Deberían haberse extendido un poco, como se puede ver. Ahora quiero que el componente y de cada uno de estos centros de blobs dependa del tiempo. Más específicamente, quiero una función matemática que tome tiempo como entrada y me devuelva un valor entre 0.0 y 1.0 basado en el tiempo que le di. Ahora hay un par de maneras diferentes de hacer esto. Empecemos graficando seno x Imaginen que el eje x es tiempo y el eje y es la posición y de nuestro blob. Sine x funciona bastante bien para nuestras necesidades, pero sí tiene algunos valores negativos que genera por lo que terminaríamos con algunas manchas que van por encima de nuestra textura. Para asegurarnos de que nuestros valores y de centro de blob se mantengan entre cero y uno, queremos que el término sine x en positivo. Una opción sería tomar sólo el valor absoluto de sine x, pero eso nos da estas esquinas, y si de nuevo imaginamos que el eje x es tiempo, eso significa que cuando el blob golpea una de estas esquinas, inmediatamente rebota hacia atrás y comienza a moverse en la dirección y opuesta. Este movimiento sería un poco antinatural y parecería que la mancha rebotó por la parte superior de la lámpara e inmediatamente comenzó a acelerarse hacia abajo o viceversa. Nuevamente, hay algunas formas diferentes de manejar esto, pero prefiero usar el seno cuadrado x o seno x veces seno x. esto elimina los valores negativos ya que un valor negativo veces un valor negativo es un valor positivo, y suaviza estas esquinas para hacerlas un poco más redondas. Ahora tenemos, digamos por ejemplo, una mancha que comienza por la parte inferior, acelera rápidamente hacia la parte superior, se ralentiza, y luego vuelve a retomar la velocidad a medida que se remonta hacia la parte inferior de la lámpara. Este es el comportamiento perfecto que buscamos. Para agregar un poco de variación entre los blobs, quizá también quiera poder controlar el desplazamiento inicial y la velocidad. Ya que nuestro eje x es tiempo aquí, la forma en que puedo acelerar un poco las cosas, es multiplicar la entrada x por un factor de velocidad. De igual manera, si quiero compensar un poco el tiempo, sólo voy a añadir un poco a la x Ahora vamos a traducir esto en código. Definiré una nueva función que devuelve un flotador llamado oscilar, y la función oscilante que estamos definiendo tomará flotador x, velocidad de flotación, y desplazamiento de flotación. Agregando mis llaves, y este es el código aquí que se ejecutará siempre que llamemos a la función oscilante. Ya que queremos seno cuadrado x o seno x veces seno x, voy a decir, devolver cómo seno x veces velocidad más offset, y luego quiero elevar ese asunto entero a la segunda potencia, razón por la cual está contenido en el poder función. Voy a escribir un punto y coma para completar mi expresión, y esos son función oscilante básica. Ahora quiero usar esta función oscilante usando el tiempo como entrada para cada uno de mis centros de blob y posiciones. También podría aplicar como con la entrada de tiempo. Todo lo que tengo que hacer es reemplazar el componente y de cada centro de blob con oscilado, tiempo, y entonces tal vez quiero que esto funcione a media velocidad con un desplazamiento de 0.4. Ahora se puede ver que tengo este blob que está animando de ida y vuelta entre 0.0 en el eje y y 1.0 en el eje y usando el tiempo como nuestra entrada. Añadiré algo similar para el resto de estos. Digamos que oscilar el tiempo, quiero que esto vaya aún más lento, 0.2, y luego, no sé, 0.5 en el offset. Sólo sigue haciendo esto. Ahora puedes ver que todas mis manchas van de ida y vuelta en el eje y usando nuestra función oscilante. Ahora probablemente sea un buen momento para ajustar todos estos valores solo para asegurarte de que te sientes cómodo con ellos, lo que quizás podrías cambiar un poco los blobs en el eje x cambiando su componente x, o cambiarlos en el eje y un poco cambiando su velocidad, su desplazamiento, y luego también cambiar la influencia aquí. A mí me gusta hacer que la fuerza de cada blob sea un poco más grande si van más despacio. los que he ajustado velocidad a 0.1, aumentaré un poco la influencia sobre la fuerza, así que diré esto es 0.8 y 0.8, y puedo ver que las manchas en movimiento más lento son un poco más grandes. Si quieres poder ajustar estos valores realmente rápidamente, puedes definir un uniforme para cada uno de ellos como lo hicimos para el umbral. No voy a hacer eso sólo porque es un montón de uniformes diferentes a definir, pero esa es una opción si quieres que la gente ajuste rápidamente cosas como la velocidad, el desplazamiento, o la posición x desde el editor. Estoy bastante contento con esto como es por el momento, así que voy a seguir adelante y empezar a añadir un poco de color en la siguiente lección. 7. Añade colores: En esta lección, agregaremos algunos colores a nuestra lámpara de lava. Empecemos agregando el color de fondo que observamos antes es más brillante en los bordes y más oscuro en el centro. Voy a hacer estos uniformes de colores para que pueda ajustarlos rápidamente después si quiero. Escribiré uniforme vec4 ya que de nuevo, representamos colores con vector fours, y escribiré background_edge y diré colon, hint_color. Esto le dice al editor que quiero que el borde de fondo tenga el toque de un selector de color. A pesar de que es un vector cuatro, los cuatro componentes son RGB y A. El editor ahora pone valores en esos cuatro componentes dependiendo del color que escoja de un bonito recogedor de color, en lugar de tener que introducir números manualmente y eso es sólo porque escribimos hint_color aquí para decirle al editor que este es un color. Quiero establecer el color de fondo en el borde a un bonito color magenta. Yo quiero que esto sea todo el camino al 255. Yo quiero que el verde esté a cero, y quiero que el azul esté a 255. Ahora tengo este color magenta que espero poner en los bordes, específicamente los X bordes de la lámpara de lava. Ahora, voy a escribir de nuevo, uniforme vec4 background_center y de nuevo, este es un color. Ahora tengo otro que dice, si paso el cursor sobre el centro de fondo, solo voy a ponerlo a un color morado más oscuro y por supuesto puedo modificar estos valores más adelante, estos son solo valores que estoy configurando por ahora. Ahora definiré dos uniformes más para lo que quiero que estén los colores de las manchas en la parte superior y la inferior. Blob_top y es un color similar y ahora, ha aparecido más como un color en el editor, voy a establecer esto para que sea un bonito color rojo vibrante y luego, otro uniforme vec4 blob_bottom para lo que quiero que estén los blobs en el fondo y ese es otro hint_color. Tengo otro recolector de color aquí abajo y voy a poner eso para que sea un bonito amarillo. Empecemos por establecer el color de fondo en una mezcla entre el borde de fondo y el centro de fondo, creando un gradiente. Empezaré por ir a donde actualmente estoy configurando el color a negro, aquí mismo, y en lugar de usar un vector para esta constante, lo estableceré en una mezcla, que es una función de interpolación lineal en Kidlo. Ahora escribiré centro de fondo, borde de fondo porque quiero mezclar entre estos dos colores, y esto generará un vector 4 en el color según necesitemos. Entonces, digamos que empezaré con 1.0 aquí. Se puede ver que esto configuró completamente todo para ser 1.0. Tenemos el color de borde de fondo establecido en todas partes donde solía estar el negro. Si yo estableciera esto en 0.0, ahora tenemos totalmente el color central de fondo en su lugar. Si lo configuro en 0.5, tenemos a mitad de camino entre el centro de fondo y el borde de fondo, y así sucesivamente. Si cambio esta variable, cambia qué mezcla estoy usando entre los dos colores y quiero que esa mezcla, esa última variable de peso, dependa de lo cerca que estoy o lo lejos que estoy del centro de la lámpara. Cuanto más lejos estoy del centro, más quiero confiar en el filo de fondo, y cuanto más cerca estoy del centro, más quiero confiar en el centro de fondo. Diré que quiero el valor absoluto de 0.5 menos la posición x actual, que de nuevo, puedo obtener la posición actual diciendo UV y luego, .x, y luego multiplicaré esto por 2.0. Probemos esto para ver cómo funciona. Si estoy en el centro, entonces mi posición x actual es 0.5. Haré el valor absoluto de 0.5 menos 0.5, que es cero, y luego multiplicaré eso por 2.0, que es cero, lo que significa que estaré completamente dependiente del color central del fondo. Debe ser un morado oscuro y lo es. Ahora vamos a probar a 0.0. El valor absoluto de 0.5 menos 0.0 es 0.5, veces 2, es 1. Debería estar completamente dependiente del color del borde de fondo y lo soy. De igual manera, si intento una posición entre 0.0 y 0.5 en la x, digamos 0.25, tendré el valor absoluto de 0.5 menos 0.25, que es 0.25, veces 2, que es 0.5. Yo estoy a medio camino entre el centro de fondo y el borde de fondo, que se puede ver que soy. Puedo cambiar estos valores sin embargo quiero modificando ahora el borde de fondo y el color central de fondo. Quiero que el color del borde de fondo sea un poco más oscuro, así que solo lo bajaré un poco. Ahí vas. Ahora quiero hacer lo mismo, pero para los blobs. Abajo donde definimos el color de las manchas, si la influencia es mayor que el umbral, aquí es donde establecemos el color de la mancha en blanco. En cambio usaré otra mezcla, blob_top, blob_bottom y luego, quiero que eso dependa de dónde estemos en el eje y. Cuanto más lejos estoy de arriba, más quiero confiar en la parte inferior. Simplemente usaré UV.y para que si estoy en 1.0, seré completamente dependiente del color de fondo blob, que se puede ver que soy y si mi UV.Y es cero, estoy en la parte superior de esta brillante, entonces debería estar completamente dependiente de el color top blob, que se puede ver una vez que una mancha sube aquí, que dependo de eso por completo allá arriba. Esto funciona bien. Ahora quiero que las manchas brillen un poco y la forma en que voy a hacer eso es crear una mezcla entre el color de fondo en la posición actual y el color de blob en la posición actual. Para hacer eso primero, solo voy a almacenar esta mezcla aquí y voy a decir, hay un nuevo vec4 llamado current_blob_color y le pondré eso a esa mezcla, pondré el punto y coma, y luego solo reemplazaré esto aquí abajo por current_blog_ color. Eso es solo para evitar haber copiado y pegado código. Ahora voy a crear un nuevo flotador llamado glow_multiplicador, y pondré eso a lo que haya establecido mi umbral, veces 10. Esto es bastante arbitrario y te animo a experimentar con este valor para ver qué tipo de resultados puedes obtener. Pero voy a usar ese glow_multiplicador para crear una mezcla que voy a asignar al color actual. Diré que el color es igual a la mezcla entre cualquiera que sea el color actual, que es este gradiente que hemos configurado aquí, y quiero una mezcla entre ese color y el current_blob_color en esta posición con un factor que depende el glow_multiplicador y la influencia que tienen los blobs sobre el punto específico que estoy viendo actualmente. Diré pow, glow_multiplicador tiempos influyen, que es la influencia de esos blobs tienen en esta posición actual, y luego levantaré eso para decir el quinto poder, entonces 5.0, y luego le añadiré un punto y coma. Se puede ver que eso agregó un bonito aura alrededor de las manchas. También puedes ajustar este valor 5.0 a tu gusto. Pero si lo aumento a decir, 25, el resplandor desaparecerá por completo. tanto que si lo reduzca por uno, mismo no es elevarlo a ningún tipo de poder, se puede ver que el resplandor ahora es masivo. El motivo de eso, porque normalmente, pensarías que elevar algo a una potencia superior lo haría más grande. El motivo de eso es que la influencia de los tiempos de glow_multiplicador suele ser un valor menor a uno. Multiplicando un valor menor que uno por otro valor menor que uno, por supuesto, reduciremos el valor. Por ejemplo, a menos que estemos realmente cerca del centro de una mancha, como si estuviéramos fuera en esta región resplandeciente, la influencia será un número bastante pequeño. Incluso multiplicándolo por umbral por 10, sigue siendo menos de uno. Entonces, en realidad, un valor que es perfecto es, no sé, tal vez en algún lugar alrededor de las seis o siete. De verdad lo que estoy tratando de hacer aquí es simplemente hacer algo que simplemente suavice un poco el borde. A mí me gustan los siete. Sólo que pueda ajustar esto rápidamente, voy a hacer un nuevo uniforme flotador glow_power. Volveré atrás y haré que tenga un valor por defecto de siete, que es a lo que tenía sin asignar ahí abajo, así que ahora se puede ver que se restauró el resplandor que acabo de tener y ahora, solo puedo modificar este valor para que veas que cuanto más pequeño yo hazlo, cuanto más grande se pone el resplandor, y cuanto más grande lo hago, más sutil se vuelve ese resplandor. Todavía me gusta un valor alrededor de las siete, solo para suavizar un poco ese filo y lo voy a dejar así por ahora. De nuevo, sin embargo, retocar y jugar con estos números es todo parte del proceso. Tengo mucha curiosidad por ver qué puedes hacer jugando un poco con esta función. En la siguiente lección, añadiremos una base de lámpara de lava. 8. Añade una base: En esta lección, pasaremos a usar una base de lámpara de lava. Para empezar, voy a reemplazar este icono dot png que estoy usando actualmente con la base de lámpara de lava que puedes encontrar en la sección de recursos del proyecto. También puedes crear tu propia base de lámpara de lava. Lo importante de esta imagen es que tiene un color sólido que quieres reemplazar con nuestro shader de globo de lámpara de lava. Para agregar tu imagen base de lámpara de lava al proyecto Godot, puedes arrastrar el archivo al sistema de archivos aquí en la esquina inferior izquierda, o puedes agregar ese archivo a tu carpeta en tu escritorio que representa el proyecto de lámpara de lava. Guardé la imagen base de la lámpara lava en mi escritorio así que solo la voy a arrastrar al sistema de archivos en la esquina inferior izquierda. Ahora verás que dice, “lámpara lava base dot png” directamente en la carpeta res del sistema de archivos. Voy a dar clic en mi nodo “Sprite”, y donde dice Textura aquí, sólo voy a arrastrar la base de la lámpara de lava hacia la Textura. La imagen base de la lámpara de lava que creé es mucho, mucho más alta que icon dot png. Tiene una tonelada más de píxeles, y si me alejo usando la rueda del ratón, se puede ver que esta es una lámpara de lava bastante larga ahora. También puedes ver que las manchas son muy, muy diminutas ahora, y eso se debe a que estamos escalando todo por tamaño de píxel de textura, por lo que la distancia al centro de blob es más o menos enorme dondequiera que vayas. Para arreglarlo, voy a crear un nuevo flotador uniforme llamado fuerza máxima y lo pondré en 16 por ahora. Voy a multiplicar la fuerza máxima aquí abajo. Toma la fuerza del centro de la blob para cada blob, solo la voy a multiplicar por fuerza máxima. Dado que todos estos valores para el componente de fuerza no son más de uno, esta es efectivamente la fuerza máxima que tendrá un blob individual. Se puede ver que eso hizo que nuestras manchas volvieran a un tamaño normal. Pero también puedo entrar en mis Parámetros de Shader y ajustar esto como quiera, para hacerlos más grandes o más pequeños. Lo volveré a ajustar a 16 por ahora o haga clic en el botón de reinicio. Lo siguiente que voy a hacer es simplemente bajar el sprite para que quepa dentro de esta caja azul, que actualmente representa el tamaño de la pantalla. Por ahora, solo pondré eso en 0.4 y 0.4. Ya veo que eso sigue un poco fuera de la caja, así que escribiré en 0.3 y 0.3. Ahora estamos dentro de los límites azules, y tenemos esta lámpara de lava básica. Pero ahora mismo, ya que estamos sobrescribiendo el color en todas partes, en realidad no podemos ver nunca la propia base de la lámpara de lava. Por eso dije que es importante que el globo de la lámpara sea de un color sólido. Si me desplazo hacia arriba y miro la textura, he creado esta base de lámpara de lava y se puede ver que el área que quiero reemplazar con mi shader es perfectamente magenta. En mi sombreador de fragmentos, lo que quiero hacer es usar primero el color de la textura en este punto actual, y luego si el color de la textura en este punto actual es perfectamente magenta, entonces haz todas estas cosas que ya hemos escrito. Para ello, primero diré, “color igual” y luego Godot tiene una función de textura incorporada para leer colores de texturas, y luego diré, “TEXTURE” todas las tapas, y “UV” para esta posición actual. Entonces si el color ahora es igual a magenta, que es un vector 4 con 1.0 en el rojo, 0.0 en verde, y 1.0 en azul, 1.0 en alfa, entonces dentro de esto, quiero hacer todas estas cosas. Yo sólo voy a hacer Control X o Comando X para cortar y pegar eso aquí. Entonces solo voy a agregar una sangría de tabulación para formatear. Se puede ver que ahora tenemos nuestro nivel básico y se puede ver que el globo sólo aparece en las áreas que eran magenta. Podrías ver un borde magenta no deseado alrededor del globo de la lámpara de lava como lo hago actualmente. Si lo hace, haga clic en la pestaña “Importar” en la esquina superior izquierda, asegúrese de que tiene la base de lámpara de lava seleccionada actualmente como lo que está importando, y luego asegúrese de que tanto Filtro como Mipmaps están desactivados. Tengo sin marcar Filtro y voy a presionar “Reimportar”. Ahora se puede ver que ese borde magenta no deseado ya se ha ido y tengo un límite perfecto entre el gris del fondo y mi globo de lámpara de lava. Lo siguiente que quiero arreglar es que actualmente nuestras manchas pueden ir hasta el fondo aquí, y no las vemos ya que van afuera donde se supone que está el globo. Para arreglar esto y hacer que nuestras manchas solo vayan y vengan dentro del contexto de este globo aquí, necesitamos hacer dos nuevos uniformes. Diré “top flotante uniforme” y asignaré eso a cerca de 0.2. Parece que tal vez esto es 20 por ciento aquí a través de arriba a abajo, tal vez esto es 20 por ciento a través, así que diré 0.2. Entonces fondo flotante uniforme, si esto es 0.2, tal vez esto es alrededor de 0.5 aquí. Esto parece que tal vez es alrededor de 0.6. Diré 0.6 o alrededor de 60 por ciento de arriba a abajo. Esto es con lo que actualmente voy a ir para arriba e abajo, pero como son uniformes, de nuevo, abajo en nuestros Parámetros de Shader, son realmente fáciles de ajustar. Ahora quiero asegurarme de que nuestra función oscilante solo regrese como valores y entre nuestra parte superior y nuestra inferior. Lo que voy a decir es tiempos fuera del poder, voy a decir “tiempos abiertos paréntesis, abajo menos arriba”. Actualmente, estas escalas son función sinusoidal por 0.4 y luego voy a sumar top a ella. Lo que esto hace actualmente es escalar nuestra función sinusoidal 0.4 y luego cambiar la función hacia arriba para que su valor mínimo de retorno sea 0.2. Se puede ver que esta nueva función nos dará valores entre 0.2 y 0.6. Nuevamente, ya que se trata de uniformes, puedo ajustar sus valores en la sección Parámetro de Shader. A lo mejor el fondo está en realidad más cerca de, no sé, 0.54. Entonces puedo tener el fondo sea 0.54 y las manchas no vayan por debajo de ese nivel. También podría aumentar top para estar tal vez cerca de 0.5, y luego se puede ver que los blobs no van a ir por encima de ese nivel. Voy a restablecer esos de nuevo a 0.2 y 0.6, pero sólo tienes que saber que puedes meterte con esos si usas tal vez una base diferente para obtener el valor que oscila perfectamente las manchas entre la parte superior y la inferior. Podría haber notado también que nuestro gradiente en las manchas no toma en cuenta la nueva parte superior e inferior todavía. Este valor aquí en la parte inferior definitivamente no es igual al color que hemos establecido aquí para nuestro fondo blob. Si voy a bajar a donde estoy hablando de ese gradiente aquí, quiero escalar los pesos que estamos usando para nuestra función mixta aquí. En lugar de depender sólo de UV dot y, que es uno de aquí abajo, quiero que uno esté justo aquí, y quiero que cero esté justo aquí. Lo que necesito hacer es tomar en consideración la parte superior y la parte inferior del globo. Para ello, voy a decir “UV dot y menos top”. Ahora ya lo he hecho para que la parte superior de nuestra lámpara sea ahora cero. Diga si estamos aquí y estamos en 0.2, ahora estamos restando top, que he dicho que es 0.2, así que ahora esto es cero. Yo quiero escalar eso por abajo menos arriba. Se puede ver que ahora tenemos el gradiente correcto. El motivo de eso es que así estoy en la parte superior aquí, tengo 0.2, UV dot y es 0.2, 0.2 menos 0.2 es 0 así que esto evalúa a cero, lo que estamos completamente dependiendo del color top blob. Pero si estamos en la parte inferior, entonces UV es actualmente 0.6, lo que evalúa a uno. También se puede ver que si dijera mover el fondo más alto, podría hacer más y más de la lámpara amarilla, o si muevo la parte superior inferior, puedo hacer cada vez más de la lámpara ese color rojo. En la siguiente lección, exportaremos marcos de nuestra lámpara de lava a archivo PNG. 9. Exportar cuadros a PNGs: En esta lección, exportaremos marcos de nuestra lámpara de lava a PNG. Ahora asegúrate de que tu lámpara de lava sea igual que tú la quieres. Así que siéntete libre de modificar todos los colores y la parte superior y la inferior y la fuerza y todo ese tipo de cosas para asegurarte de que la lámpara de lava es exactamente como quieres que se exporte a un GIF. Voy a disminuir un poco la fuerza máxima porque siento que ahora he abarrotado todo entre 0.2 y 0.6, solo hay mucha cera en comparación con muchos de los colores de fondo. Entonces voy a disminuir la fuerza máxima a tal vez alrededor de las 12, tal vez un poco más de 12. Vamos a intentarlo, 14. Sí, ese valor me queda bastante bien, así que mantendré este valor y seguiré adelante para tratar de hacer un GIF con esto. Lo que quiero hacer a continuación es encajar el tamaño de ventana aquí, esta caja azul abajo para ser exactamente del tamaño de mi lámpara de lava. Yo puedo hacer eso mirando por aquí la textura. Tengo 512 por 1584, y actualmente tengo una escala de 0.3 y 0.3. Voy a recordar estos números, y voy a ir a proyectar en la esquina superior izquierda, y luego Ajustes del proyecto. Desplázate hacia abajo hasta Ventana, y donde dice ancho y alto, quiero que mi ancho sea 512 veces 0.3. Entonces quiero que mi estatura sea 1584 veces 0.3 y luego cerrar. Se puede ver que mi caja azul, si anulo la selección de esta brillante, ahora es igual que mi contorno Sprite, que es justo lo que quiero. A continuación, voy a volver a pasar a la esquina superior izquierda y presionar Escena para cambiar a la pestaña de escena. Haga clic en “Mi Sprite” y presione este botón para agregar un nuevo guión. Vamos a escribir un script que emita archivos PNG por cada fotograma que rendericemos de la lámpara de lava. Me parece bien que Lamp.gd sea el nombre de este guión así que presionaré “Crear”. Entonces voy a escribir una nueva función que guarde fotogramas a PNG. Recuerda que ahora estamos trabajando en gdscript, que no es el mismo idioma en el que hemos estado trabajando antes, por lo que las cosas se ven un poco diferentes. Escribiré una nueva función llamada Guardar marco diciendo func save_frame (): enter. Ahora nuestros bloques de código están definidos por sangría y no por corchetes rizados. Por lo que siempre que se llame a guardar marco, quiero capturar la textura que actualmente se está renderizando en la ventana gráfica y guardarla como PNG. En primer lugar, crearé una variable para almacenar los datos de la imagen en. Diré var image=. Entonces para obtener esta imagen, quiero sacar la textura actual de lo que sea que se esté renderizando a la ventana. Esa es la ventanilla muy alta del motor de juego Godot. Entonces diré get_tree () para obtener todo el árbol de escena , .get_root () para obtener el elemento más alto o la ventana gráfica, y luego digo.get_texture () para obtener la textura de ese viewport, y luego en.get_data (), para obtener los datos de imagen actuales de esa textura. Necesito convertir esta imagen en una que preserve la transparencia. Haré una nueva línea y luego diré image.converge para cambiar el formato de esta imagen, imagen con un mayúscula punteo RGBA8. Por lo que quiero este de aquí, FORMAT_RGBA8. Este formato preservará efectivamente la transparencia que queremos. Ahora guardaré el PNG, así que haré image.save_png. Por ahora solo escribiré *frame.png* como una cadena. Ahora quiero llamar a esta función guardar marco cada vez que se haya renderizado un nuevo fotograma. Entonces en la función lista que se llama cuando el nodo entra al árbol de escena por primera vez, así que cuando comience nuestro juego por primera vez, reemplazaré pass con VisualServer.Connect y quiero esta *frame_post_draw signal* y yo quieren conectarse a esa señal a un método en este objeto, así que escribiré yo mismo, y quiero nuestro nuevo método de guardar marco. Entonces escribiré *save_frame* como una cadena. Ahora lo que esto hará es cada vez que el servidor visual nos diga que acaba de dibujar un marco, llamará al método de fotograma guardado en este objeto. Por lo que cada vez que se haya dibujado un nuevo fotograma, se llamará al método de fotograma guardado, obtendremos la textura de la ventana gráfica actual, y la guardaremos como una imagen. Específicamente a frame.png. Presionaré el botón de reproducción para renderizar un nuevo fotograma. Cerraré la ventana que surgió. Se puede ver que ahora en el sistema de archivos y en la esquina inferior izquierda, hay una nueva imagen llamada frame.png. Voy a hacer doble clic en él para obtener una vista previa. Se puede ver aquí a la derecha, tenemos dos problemas. Una, el fondo no es transparente, es de este color gris aquí, y dos, ha sido volteado boca abajo. En primer lugar, arreglemos el tema de la transparencia. Ve a Proyecto, y luego a la configuración del proyecto en la esquina izquierda, y luego debajo de transparencia por píxel en la pestaña Ventana, comprueba la transparencia por píxel permitida y la transparencia por píxel habilitada. Después pulsa “Cerrar”. Entonces en nuestro script antes de conectarnos al servidor visual, necesitamos volver a obtener nuestra ventana gráfica, que es exactamente lo que hicimos aquí, get_tree () get_root (). Entonces diremos get_tree () .get_root () y then.set_transparent_background (true) y queremos establecer eso en true. Presionaré el botón de reproducción para renderizar otro fotograma, cerrar la Ventana que aparece, hacer doble clic en frame.png y ahora puedes ver que efectivamente tenemos un bonito fondo transparente ahí. Dependiendo de tu sistema, el tuyo podría no estar al revés, pero el mío sí. Entonces después de convertir el PNG, pero antes de guardarlo, quiero escribir imagen. flip_y, y quiero llamar al método flip_y en la imagen para que lo voltee boca abajo. Presionaré nuevamente el botón de reproducción para renderizar otro fotograma, cerraré la ventana que aparece, y luego haga doble clic en frame.png y ahora puedes ver que tengo mi muy bonito marco aquí. Está perfectamente de lado derecho, tengo un fondo que es transparente, y generalmente se ve bastante bien. Pero lo que realmente quiero es una tonelada de marcos individuales para compilar en un GIF animado. En este momento solo estamos anulando frame.png cada vez. Entonces voy a definir una nueva variable miembro arriba en la parte superior llamada var frame_count = 0 y la pondré a cero para empezar. Ahora con el fin de controlar el número de fotogramas que es mi GIF de salida, solo voy a guardar el fotograma si el recuento de fotogramas está por debajo de cierto nivel. Por encima de la sección de variables miembro, voy a definir una nueva constante que no cambiará, y pondré eso en MAX_FRAMES = 60 en todos los mayúsculas, y pondré eso en 60 por ahora. Entonces abajo en nuestro método de guardar marco, escribiré debajo de imagen var image_name, y lo asignaré a una cadena vacía por ahora. Ahora, solo para asegurarme de que nuestros marcos de salida estén ordenados en el orden correcto, escribiré para i en rango (), y luego diré la longitud de la cadena de MAX_FRAMES menos la longitud de la cadena de nuestro actual conteo de cuadros. Para cada uno de estos, quiero anexar un cero al inicio del nombre de la imagen. Entonces fuera de este for-loop, haré image_name plus es igual a la cadena del recuento de fotogramas actual, y luego plus. PNG. Entonces en lugar de guardar la imagen como frame.png, guardaré como (image_name). Por último, voy a añadir uno al recuento de cuadros. Más es igual a uno. Pero solo quiero guardar este PNG si nuestro conteo de fotogramas actual es menor que MAX FRAMES. Entonces solo haré todo esto si frame_count es menor que MAX_FRAMES. Entonces como estamos trabajando con indentaciones, resaltaré todo esto y presionaré Tab para sangrarlo en absoluto. Por lo que actualmente estamos ahorrando 60 marcos de nuestra lámpara de lava. Pero si Godot está consiguiendo 60 fotogramas por segundo, eso significa que nuestro GIF tiene solo 1 segundo de largo, así que quería reducir los fotogramas objetivo de Godot por segundo. Entonces en la función lista, escribiré motor, estableceré FPS objetivo, y pondré eso en 15. Eso significa que Godot apuntará a 15 fotogramas por segundo y si guardamos 60 fotogramas, eso significa que tenemos alrededor de cuatro segundos de tiempo de ejecución de la lámpara de lava. En realidad voy a volver atrás y aumentar eso un poco más para que sea 120 por ocho segundos de tiempo de ejecución de lámpara de lava. Después pulsa el botón de reproducción y deja que la ventana que aparece funcione durante ocho segundos o más. Una vez que hayan pasado al menos ocho segundos, cierra esa ventana y verás que Godot está importando todos nuestros marcos. Entonces si bajo a nuestro sistema de archivos aquí en la esquina inferior izquierda, se puede ver que tenemos los 120 fotogramas comenzando en 000.png y yendo todo el camino a un 119.png. Ahora queremos convertir todos estos archivos PNG en un archivo.GIF que animará. 10. Convierte PNGs a un GIF: En esta lección, convertiremos nuestros PNG exportados en un GIF animado sin fisuras. Abre tu navegador web y accede a un sitio web que pueda generar GIF animados a partir de PNG. Te recomiendo usar ezgift.com/maker. Una vez que estés en el sitio, pulsa “Browse” para subir tus imágenes PNG. Una vez que hayas seleccionado tus PNG, pulsa “Subir y hacer GIF”, luego verás aquí todos los PNG de lámpara de lava. Si se desplaza hasta la parte inferior, asegúrese de establecer el tiempo de retardo en cero y luego presione “Hacer un GIF”. Una vez que tu GIF se haya cargado, pulsa “Effects”, luego desplázate hacia abajo y donde dice Animation Flow, marca la casilla junto a Ejecutar hasta el final y vuelve atrás al inicio. A continuación, pulsa “Aplicar seleccionado” y tu GIF de salida se bucle sin problemas. Una vez que hayas hecho esto, pulsa el botón “Guardar” y guarda tu nuevo GIF en tu computadora. Este es un proyecto que ofrece toneladas de oportunidad para la experimentación. Cuanto más te metas con él, mejor comprensión tendrás de cómo funcionan los shaders en el Godot Game Engine. De verdad te animo a que hagas eso. En la siguiente lección extra, vamos rápidamente a repasar cómo dejar tu lámpara de lava ardiendo en la esquina de tu pantalla mientras haces tu otro trabajo. 11. (Extra) añade la lámpara de lavava a tu pantalla: En esta lección extra, revisaremos rápidamente cómo puedes ejecutar la lámpara de lava en la esquina de tu pantalla mientras realizas tu otro trabajo. Voy a empezar comentando esta línea de conexión para hacerla para que ya no estemos exportando nuestros cuadros. Utilizo la libra o el símbolo hashtag para comentar la línea. Entonces voy a subir a Project, Project Settings. Desplácese hacia abajo hasta el modo Stretch. Voy a decir “2d” y “Cerrar”. Ahora si presiono el botón “Play”, puedo cambiar el tamaño de mi lámpara de lava. Puedo arrastrarlo por ahí, y puedo redimensionarlo como lo quiero. Al cambiar el tamaño de la ventana, la relación de aspecto de las lámparas de lava se pone un poco apagado. Para arreglar eso ve a Proyecto, Configuración del proyecto y luego donde dice Aspecto bajo Estirar, cambia de “Aspect Ignorar” a “Aspect Expandir”. Ahora cuando se ejecuta la lámpara de lava, la lámpara de lava siempre seguirá siendo la misma relación de aspecto, pero aún puede aumentar de tamaño. No obstante, si hago clic en el “Godot Game Engine”, o en cualquier otra ventana, mi lámpara de lava va detrás de ella. Lo que voy a hacer es ir a Project, Project Settings y luego marcar “Always On Top”. Si no quieres que sea redimensionable, puedes desmarcar “Redimensionable”, y si quieres que sea sin bordes, puedes marcar “Borderless”. Voy a seguir adelante y hacer eso por ahora. Entonces ahora si reinicio, puede ver la lámpara de lava corre en el centro de mi pantalla y no tiene ninguno de los límites de Godot en ella. Voy a detenerlo presionando la señal de stop. Después vamos a Editor en la esquina superior izquierda, y luego Ajustes de Editor. En Ajustes del Editor, si me desplaza hacia abajo hasta Ejecutar y luego Colocación de ventana, actualmente se puede ver Rect está configurado en Centrado, razón por la cual nuestra lámpara de lava está funcionando en el centro de la pantalla. Puedo establecer esto en posición personalizada y luego obtener el tamaño de mi pantalla, que en mi caso es 1920 por 1080. Entonces puedo decir 1920 menos la coordenada x en nuestra lámpara de lava es brillante, así menos 153. Entonces podemos decir 1080 menos 475. Me gustaría restar un poco más de ese número sólo para dar cuenta de esta barra de abajo aquí. Por lo que restaré un 20 adicional de 605. Después presiono “Cerrar”, “Reproducir”. Ahora puedes ver la lámpara de lava corre en la esquina de mi pantalla. Podría incluso minimizar Godot y tener la lámpara de lava funcionando en mi escritorio o podría abrir Firefox. Continúa la lista. Básicamente la lámpara de lava se queda en la esquina inferior derecha de mi pantalla. Si quiero hacerlo para que pueda mover la lámpara de lava, solo volveré a Project, Project Settings y luego desmarcaré “Borderless” y reiniciaré. Ahora si quiero, puedo arrastrar la lámpara de lava para ponerla en cualquier lugar que quiera. Pero todavía se mantiene en la cima ya que “Always On Top” está revisado por lo que todavía puedo minimizar Godot y hacer otras cosas. Es que ahora también puedo arrastrarlo por ahí si sucede que se interpone en el camino. Es así como agregar una lámpara de lava a la esquina inferior derecha de tu pantalla, una vez que ya la hayas creado usando el Godot Game Engine. Creo que es muy divertido, solo un poco de entretenimiento pasivo mientras haces tu otro trabajo. Además es un iniciador de conversación bastante genial si casualidad compartas una pantalla en una llamada de Zoom o algo así. Gracias por revisar la lección de bonificación. Te veré en el siguiente video para algunos pensamientos finales. 12. Reflexiones finales: Gracias por revisar la clase. Si aún no lo has hecho, por favor asegúrate de publicar tu regalo de lámpara de lava en la galería de proyectos de clase. Realmente espero que hayas salido de esto con una mejor comprensión de cómo funcionan los shaders de fragmentos 2D. De verdad agradecería cualquier retroalimentación que tengas. Por favor considera dejar una opinión aquí en Skillshare y sígueme si quieres más clases como esta. También puedes hacerme saber qué te gustaría ver a continuación a través de la encuesta en la pestaña Discusiones o en mi página Perfil. Te veré la próxima vez.