El artículo trata principalmente sobre sombreadores GLSL y cómo los utilicé en este mini juego de demostración.
El artículo se divide en el siguiente orden:
- Enlaces y una breve descripción.
- Una descripción muy breve de la lógica del juego y las características utilizadas de Godot.
- Sobre los sombreadores usados.
- Un poco más sobre Godot y sus características.
- WebGL2 funciona
- Multijugador
1. Enlaces y descripción
Puede descargar la versión Win / Linux desde el enlace a itch.io
El código fuente de todo el juego está disponible en github o gitlab .
Jugabilidad:
Mínimo, este no es un juego completo. (sin sonido en el juego)
El objetivo del juego es mantener el número máximo de rondas. Las rondas comienzan cuando las esferas de HP son cero y no hay robots en el juego.
Al destruir figuras, aparecen bonificaciones, una vez por ronda , dan la velocidad de la animación del disparo, el daño (solo en la esfera principal) y la altura del salto, en color azul, rojo / verde, amarillo. Los bots también dan una bonificación pero al azar. El personaje del jugador restaura + 1HP cada nueva ronda.
2. La lógica del juego y los recursos utilizados.
Recursos utilizados:
Blender se usó solo para reducir la cantidad de polígonos en los modelos y para crear piezas rotas de modelos.
Se utiliza el módulo futari-addon . (Escribiré sobre eso a continuación)
En el juego, dos modelos tienen animaciones.
Movimientos del personaje del jugador que hice en Godot, el modelo original
El segundo modelo es esfera-bot que tiene animaciones de alta calidad.
Todos los modelos de objetos de terceros listos para usar se enumeran aquí .
La lógica del juego y las características de Godot:
La lógica del juego no se realiza de la mejor manera, enumeraré los puntos que se hacen normalmente.
Solo se usa una ventana gráfica para una escena 3D, y varias ventanas gráficas (baja resolución) en las que hay cámaras ortogonales para ventanas gráficas 2D (también de baja resolución) en las que se procesan sombreadores Multipass / Feedback, más sobre ellas a continuación.
Todas las texturas tienen mipmap , e incluso funcionan en el navegador. Hay configuraciones de gráficos adicionales (Esc - Configuraciones) . Por ejemplo, puede hacer cualquier resolución para el juego , hasta 32x32
píxeles, por ejemplo, configuré la resolución en 320x240
en la configuración, ejecuté el juego en un navegador y activé el MSAA anti-aliasing máximo. 
Todas las fuentes de luz funcionan en tiempo real , hay 16 en total.
El piso y la cerca son las partículas más simples que duplican el mismo modelo muchas veces, el código es trivial .
La matriz de rotación de partículas (piezas de piso) en mis sombreadores es solo una breve entrada de esta fórmula:
mat4 rotationAxisAngle( vec3 v, float angle ) { float s = sin( angle ); float c = cos( angle ); float ic = 1.0 - c; return mat4( vx*vx*ic + c, vy*vx*ic - s*vz, vz*vx*ic + s*vy, 0.0, vx*vy*ic + s*vz, vy*vy*ic + c, vz*vy*ic - s*vx, 0.0, vx*vz*ic - s*vy, vy*vz*ic + s*vx, vz*vz*ic + c, 0.0, 0.0, 0.0, 0.0, 1.0 ); }
por ejemplo, v=vec3(0.0,0.0,1.0)
es la rotación a lo largo del eje z
, y angle=PI/2.
sustitúyalos y obtenga el turno deseado.
La animación de bloques destructibles se considera un motor de física en tiempo real.
La física en Godot es bastante limitada, y comienza a reducir significativamente el FPS incluso con una docena de objetos activos, por lo que todas las colisiones entre piezas destruidas se desactivan y se establecen otras, se establecen niveles para la física, también hay un límite en la cantidad de destrucción simultánea y la cantidad máxima de bots al mismo tiempo (seis).
La física de la inercia y la interacción del personaje del jugador con objetos dinámicos. Está desactivado por defecto en Godot, escribí una interacción mínima, el código en los archivos:
bot_hit.gd _integrate_forces funciona y todo lo que se llama son movimientos adversarios-bot
player_l.gd en primer lugar, la función move_and_slide
desactiva la inercia infinita, y la función process_collision
repele los objetos.
La precarga (precarga) al comienzo del juego se usa para evitar el retraso cuando aparece el objeto por primera vez, esto ayuda, sin embargo, cuando enciende las sombras (y algunas otras opciones), los retrasos aparecerán nuevamente en la primera aparición del objeto. Además, en el navegador esto no ayuda debido a las peculiaridades de los navegadores que trabajan con sombreadores.
Varios objetos duplicados en uno, y varios GIProbe, las formas y parámetros de las fuentes de luz están destinados a evitar las limitaciones de OpenGL o las restricciones en Godot.
3. Sombreadores usados
Panorama del entorno:
Este juego utiliza un panorama estático, la imagen se obtiene de este sombreador (colores c1 c2, posición ldir)
vec3 sky(vec3 d, vec3 c1, vec3 c2) { vec3 ldir = normalize(vec3(0.,0.,-1.)); vec3 col = mix(c1*100., c2*100., min(abs(dy)*2. + .5, 1.)) / 255.*.5; col *= (1. + vec3(1., .7, .3) / sqrt(length(d - ldir))*2.); //sun return clamp(col,vec3(0.),vec3(1.)); }
para obtener un panorama, elimine el comentario de la línea 57 panorama_uv(fragCoord,ro,rd);
y poner un comentario en la línea 58
Panorámicas dinámicas para Godot en demos anteriores (YouTube y hay enlaces al código) panorama de nubes .
Y el panorama del ciclo día / noche con el movimiento de las nubes se utilizó en esta demostración:
otro panorama de día / noche, por ejemplo, en sombreado no lo usé en ningún lado
Si necesita convertir CubeMap en un panorama del entorno para Godot , hice un simple convertidor web .
Sombreadores muy simples:
Los sombreadores de partículas determinan estáticamente su posición para la animación o no. Por ejemplo spawn.shader)
Para un brillo adicional alrededor de los objetos , no solo bolas, esta es una línea de gglow.shader (los números se pueden cambiar según sea necesario)
float intensity = pow(0.122 + max(dot(NORMAL, normalize(VIEW)),0.), 010.85);

Al mostrar dígitos de texto en 3D , tal como lo entiendo en Godot, no hay medios para esto (sin crear un FBO adicional (vista)), por lo que un simple sombreador imprime números a partir de una textura (para que sea mipmapping ), el código del sombreador
Elementos de la interfaz de usuario:
Hacer que la forma personalizada de los paneles UI sea lo más fácil para mí es en sombreadores, tal vez esto no sea correcto en absoluto . El método correcto se muestra aquí como un ejemplo (en la sección sobre IU).
En este juego, la animación más simple es el fondo del menú , y el indicador es HP . Arriba, en el enlace al video del panorama día / noche, también está hecho, hay rayas en los lados y toda la animación en el sombreador.
Acerca del módulo futari-addon:
Funciona casi igual que este sombreador para partículas 2D en video (ver 1:41).
Se construye un mapa 2D-SDF de todos los polígonos en el video una vez al comienzo y la textura resultante simplemente se envía a las partículas, las partículas mismas se construyen normales en la posición actual y cambian el movimiento.
futari-addon hace casi lo mismo, solo que en lugar de un mapa de textura 2D, se transmiten las coordenadas de las esferas y planos 3D, que se procesan de acuerdo con la condición en el sombreador de partículas, por lo que puede cambiar libremente su posición y otros parámetros.
Además, el viento (en mi ejemplo 2D, agregar viento es muy simple, como otra textura con valores + - a la velocidad, y las partículas simplemente agregan el valor de velocidad de este mapa en su posición).
El módulo futari-addon es muy bueno , lo usó en lugar de crear su propio sistema de partículas.
Efecto Escudo:
Partículas a las que se transmiten las coordenadas del impacto en la esfera y la posición del jugador, y la extinción utilizando el búfer de realimentación de transformación . Código de sombreador en el archivo en_m.shader
Bots Shield:

Shader como capa de ruido tridimensional. Shader esencialmente todo funciona gracias a la función de flow
original aquí
El fondo está determinado por gl_FrontFacing
, y está pintado más oscuro y más verde, no azul.
Respuesta a un golpe: el temporizador de evento de descarga simplemente se transmite.
Shaders que leen su último fotograma o sombreadores Feedback / Multipass:
Casi todos los efectos se realizan utilizando esta lógica.
Uno de los sombreadores del juego .
Como fuente, configuré una cámara ortogonal que dispara objetos en un determinado grupo a una corta distancia (sin procesar toda la escena)
.
Efecto del campo de hielo:
El sombreador se indica arriba, en el archivo del proyecto es ice_feedback.shader , y un sombreador de fragmentos para el plano que crea la ilusión de profundidad del piso usando un simple bucle de profundidad:
while(current_depth < depth){ ofs -= delta; depth = textureLod(texture_depth, ofs,0.0).r; current_depth += layer_depth; }
Efecto de campo de partículas:
El sombreador es el mismo , la coordenada y
(altura) de las partículas de acuerdo con el brillo del color del búfer del marco del sombreador, el color también de acuerdo con el brillo del color ( no guardé el sombreador de partículas por separado, está en el proyecto en el objeto floor/visible_/floor3/grass/grass
).
Animación de bandera dinámica:
Godot tiene SoftBody para animar la tela, pero es una CPU, así que no la he usado. Usé un enlace de código listo para el original . Esta bandera se empuja desde tres bolas en el costado y la cabeza del personaje es la cuarta bola.
La lógica del sombreador multipass , como en el ejemplo anterior, con solo tres ejes, el código multipass del shader (1) flag.shader , el shader que dibuja la bandera solo muestra la textura y cambia la geometría del plano (2) flag.shader .
Apariencia de figuras:
Las formas no tienen UV, por lo tanto, el mapeo de texturas triplanar para el mapeo de texturas y el triángulo ( vértice ), todo el código en cchess.shader
Animación de un hitbox (marco rojo) que causa daño al personaje del jugador y un rastro del marco (las partículas son obvias):
Utiliza solo el sombreador gglow.shader ya especificado.
PD: hizo la misma animación en un sombreador , enlace a sombreador
Para las partículas, solo se usan dos texturas, un círculo y un cuadrado.
4. Acerca de Godot y sus características.
Godot es muy bueno y simple (no para un principiante). Realmente me gustó Godot por sus características.
Hay muchos errores, la documentación de Godot está incompleta y a veces es engañosa debido a errores y no indica puntos críticos (no obvio para mí) para comprender qué Godot tuvo que releer todo el código fuente muchas veces (el código no es grande y está bien escrito).
Esta es solo mi impresión, puede ser erróneo, no quiero engañar a nadie.
Insisto en que incluso los errores muy críticos en Godot pueden evitarse en Godot a través de GDScript, con un mínimo esfuerzo. Lo que sin duda es una gran ventaja.
También noto que Godot no está protegido de ninguna manera contra las peculiaridades de factores externos, como WASM en los navegadores, restricciones ANGLE, fuertes limitaciones de los navegadores mismos y, por supuesto, docenas de errores en los controladores de las tarjetas de video, todo esto debe pasarse por alto manualmente.
Retrasos : hay un gran problema con la administración, es 100% del lado de Godot, no lo solucioné. (controlar cuñas durante la compilación de sombreadores y retrasos FPS (por ejemplo, en el navegador)), también otros retrasos relacionados con las características de renderizado 3D en Godot, hice un desvío de algunos de ellos, pero todavía existen / pueden ser.
5. WebGL2 funciona Solo Linux
No inicies el juego desde el enlace si tienes Windows. Enlace a la versión WebGL2 / WASM.
Actualización de información : la versión de WebGL se lanzó en Windows10 (solo en Firefox, con ANGLE apagado) en una PC súper potente (i9 / 16gb ram / 8gb video), aunque el piso ya no se procesaba (por alguna razón), y el firefox está perdiendo memoria (> 16GB ) en cinco minutos ... es mejor no correr, bajo su propio riesgo y riesgo
Solo funciona en Chrome 76+ y Firefox (Linux).
Se envió un informe de error (enlace) sobre Windows; si se trata de un error del navegador, Google reacciona después de 2 meses. Pero aparentemente esto es un error en ANGLE, y esto seguramente no se solucionará.
El informe de errores ya está cerrado y ANGLE tampoco se editará. Entonces, en Windows, el navegador no funcionará.
En el curso de este proyecto, se solucionó un error en Chrome debido a que transform-feedback y mi última demostración (video anterior con un panorama día / noche) , que no había funcionado antes, comenzó a funcionar.
6. Multijugador
Multijugador agregado, exclusivamente para propósitos de prueba (y muestra multijugador en Godot). Código fuente y versiones binarias junto a la versión principal en github y itch (enlaces al principio).
A medida que salga Godot 3.2, agregaré WebRTC para la prueba también.