top of page
Foto del escritorBraulio Madrid

Como batallar con WebGL en Unity


Una de las compilaciones mas agradable para el usuario es sin duda crear un juego para la web, cada vez que puedo compilar un demo de mis assets lo hago para #webGL, porque así le evito al cliente la pereza que le da de descargar un ejecutable ademas de la desconfianza que provoca, pero compilar para webGL no es nada fácil.


Para los que no sepan que es webGL, es la manera como google, mozilla, opera y otros mas que se me pasan por alto en este momento, luego este grupo pasó a llamarse Khronos.


Su intensión era poder ejecutar gráficos 3D a través de la web que fuera #Opensource, para eso crearon una API en un lenguaje de ensamblador web #Webassembly que pudiera controlar la gráfica usando la API #openGL, que pudiera ser utilizada en #Javascript.


De hecho la API #OpenGL que usa es una versión un tanto especial, se llama #OpenGLES 3.0, para hacerse a una idea, estamos en la versión 4.5 de OpenGL, una versión y media por detrás, esto se debe a que esta API esta pensada para gráficas muy antiguas que seria la media de las PCs de ofimática, que soportan menos efectos, no están pensadas para ser PCs gamer.


¿Cuales son los retos?


De entrada un reto enorme es la limitación que tenemos en cuanto a efectos que podemos aplicar en un shader, podría decirse que es necesario conocer un poco el perfil de este estándar, saber cuantas texturas máximas, cuantos registros máximos, cuantos pases máximo y que características soporta OpenGL ES 3.0, aquí dejo un link a un poco de literatura respecto a los gráficos.


Lo siguiente a tener en cuenta es que javascript no es un lenguaje multi-hilo sino mono-hilo, por lo que no puedes hacer cálculos en paralelo, o simulaciones de físicas en otro hilo, todo lo tienes que hacer en el mismo hilo, aquí hay que hacer uso de #corrutinas para calcular cosas en paralelo. Ojo si escribes algún bucle mal, porque detienes toda la aplicación, por lo mismo de solo haber un solo hilo.


Otra gran limitación es la memoria y el uso que se le da a esta, apenas cuentas con 512 mb de ram, prácticamente no hay mucho que puedas hacer en cuanto a generación procedimental, pues eleva el consumo de ram al instante, aquí es mejor hacer uso de datos ya cargados en lugar de ecuaciones, hacer uso intensivo de pool de objetos en lugar de la creación y destrucción de objetos sin control.


WebGL es difícil de diagnosticar, ya que las construcciones de desarrollo si desborda la memoria de 512 mb, ya no carga y esto es muy fácil que pase, así que a veces toca directamente compilar como si fuera el producto final para que al menos cargue, a veces compila pero no carga, a veces no compila, si carga no hay manera de hacerle un debug, porque nunca se conecta con el perfilador o el debugger de unity.


¿Como solucionar estos problemas?


Gráficamente respecto a como se ven los shaders. Afortunadamente Unity nos ayuda muchísimo a traducir instrucciones y ver si la emulación corre bien, sin embargo unity no se las sabe todas y pronto notaras que al compilar algunos de tus shaders se rompen sin explicación alguna, el método que aplico es comparar las diferencias entre los shaders que me funcionan y los que no.


Respecto al tema de que javascript es mono-hilo, te dejo algunas reflexiones acerca de las #Corrutinas, que podrás ver y espero en un futuro próximo hablar mas del tema, porque creo que me quedé corto.


Respecto al uso de la #Memoria ram, prácticamente he escrito mucho sobre ese tema aquí en mi blog, tienes en esta web tienes mucha literatura respecto al tema.


Ahora viene el tema álgido del blog y es como diagnosticar una compilación webGL.


Lo que mas o menos se le puede parecer en cuanto a características es la compilación para android, generalmente también usa OpenGL ES 2.0 o 3.0, gráficamente se le parece y las limitaciones técnicas igualmente, la ventaja que puede ofrecer compilar para android es que las compilaciones de desarrollo si conectan con el perfilador y puede ver mas fácilmente donde están los puntos calientes a tratar.


Debuggear errores de código es difícil en ambas plataformas sea android o sea WebGL, sin embargo hay una opción que facilita un poco las cosas.


Debug simbols; permite que desde el navegador aparezcan los mensajes que hemos puesto a través de Debug.Log, a parte aparece otros mensajes que no hemos puesto nosotros, pero que unity ha puesto ahí para que nosotros entendamos que ocurre tras bastidores.


Siempre es mejor compilar como si fuese la versión final, en lugar de versión de construcción, así es mas probable que cargue en el navegador sin desbordar la memoria.


Cuando compila pero no carga, hay varias posibles causas, la primera es que la memoria se ha desbordado, a veces no te das cuenta porque el navegador no arroja ningún mensaje, pero para saber si es esto, la clave es esperar y que la pagina se cuelgue sola, tarde o temprano saldrá un mensaje de si desea cerrar o esperar a que siga cargando la pagina.


Para solucionar esto debe analizar con cuidado los objetos cargados en escena o si algún script está calculando algo innecesario.


La segunda causa puede ser la plantilla web que se está usando.


Unity trae por defecto la plantilla Minimal y Default y es recomendable usar la Default, mas que cualquier otra, pero a veces usamos plantillas de otros creadores, según la plataforma web a la que vamos a publicar nuestra demo.


Lo que ocurre es que la plantilla no carga el archivo javascript que carga el juego, aquí nos damos cuenta es mirando directamente la consola del navegador y viendo que referencias está usando la plantilla y corregirla.


Otro error por el que una compilación completa no carga es porque la plantilla no está corriendo en un servidor, normalmente cuando en unity le damos Built and Run, unity crea un servidor para ejecutar la plantilla. La solución crear un servidor con node.js o cualquier otro, pero para evitarse ese problema, mejor visita este vinculo y descarga el tester.


Que hay de los errores que no permiten compilar; que yo haya detectado hay 2 posibles causas, la primera es un bug que unity ha reconocido tener y es que al compilado le asigna una cantidad enorme de memoria y finalmente explota, para esto hay que modificar el archivo "emscripten.config" en la ruta:

X:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\emscripten.config


NODE_JS=[os.getenv('NODE'),'--stack_size=8192','--max-old-space-size=4096']

Cambiarlo por 1024

NODE_JS=[os.getenv('NODE'),'--stack_size=1024','--max-old-space-size=4096']

La otra causa que no permite compilar no importa que plataforma es; tener algo guardado en el proyecto, dentro de las carpetas Plugins y Editor da problemas, así que es mejor evitar ser tentado a usar herramientas que entren en cualquiera de estos, o usar archivos .dll para extender la funcionalidad. La solución a esto es usar tanto como sea posible las herramientas que nos ofrece el motor, si usamos herramientas de terceros hay que probarlos en proyectos nuevos para detectar a tiempo que no presente errores al compilar.


 

Estas han sido las causas que he encontrado, si conoces otros métodos para diagnosticar las compilaciones para WebGL y para android me gustaría conocerlos.


Como pequeña nota quiero decirles que la actualización de la demo de Darkcom Benchmark ya esta disponible para itch.io https://darkcomdev.itch.io/darkcoms-benchmark, echale un vistazo.


No siendo mas esto sería todo por hoy, nos vemos en el próximo Blog.

249 visualizaciones0 comentarios

Comentarios


bottom of page