Polls

Escribirías en el wiki de codepixel?
 

Wiki Codepixel

Visita el Wiki de programación gráfica de codepixel . Podrás incluir los enlaces que creas interesantes para desarrollar videojuegos, motores de render, demos, etc.
Inicio arrow Tutoriales arrow Lo + Nuevo arrow Diseño de un motor 3d moderno: Introducción
Diseño de un motor 3d moderno: Introducción PDF Print E-mail
Written by Javier Loureiro   
Sunday, 30 March 2008

Diseño de un motor 3d moderno

 

En esta serie de artículos os voy a hablar sobre el desarrollo de un motor de render para videojuegos. Para ello nos hemos juntado Iñigo Quilez (conocido por sus trabajos en shader avanzados como el ambient occlusion en espacio de pantalla), Jesús de Santos (estuvo en la parte de tecnología de pyros studios y ahora trabaja como independiente) y el que escribe, Javier Loureiro (actualmente desarrollando el motor de render para ilion animation studios), para que cada uno aporte la visión que consideramos importante a la hora de desarrollar un motor 3D orientado a tarjeta gráfica.

Un motor realtime 3D se encarga básicamente de varias cosas, que hay que pensar detalladamente. Lo primero es mantener una descripción de la escena, con los distintos elementos que la forman, su estado, y las relaciones entre distintas entidades. Es lo que se denomina scenegraph, y puede ser que tengamos incluso distintos scenegraphs para determinadas tareas. Al scenegraph se le piden "nodos" que podremos modificar, y después el motor se encargara de pintar correctamente.

Una primera tarea es definir correctamente la descripción de la escena, y para ello normalmente se utilizan exportadores y plugins para programas 3D comerciales, como 3dsmax, XSI, o maya. Estos programas nos van a dar una cantidad de información enorme: geometría, materiales, los huesos de la animación, todo tipo de propiedades que deseemos agregar al objeto, etc. Nosotros tenemos que decidir que vamos a implementar, como vamos a permitir editarlo en el software 3d, y tendremos que pensar la mejor forma de exportar esa información a nuestra definición de escena. Este capítulo no es en sí nada trivial. Muchos de los grandes errores de un diseño del motor vienen de no pensar adecuadamente dónde almacenar los datos. Por eso lo ideal es que al principio diseñemos una forma flexible de modificar este fichero. Una idea para conocer cual es la mejor forma de almacenar los datos es investigar varios programas de 3D (maya,XSI y 3dsmax al menos), y ver qué datos se almacenan en los objetos. Este tipo de investigaciones os van a servir de mucho posteriormente, ya que tendréis claros los requisitos posteriores del motor.


El proceso normal de un no iniciado en el desarrollo de un motor de render es comenzar poco a poco a implementar cosas que se ven en pantalla. Es una forma rápida de ver resultados, pero tiene un problema, y es que te encuentras continuamente reformando el motor para implementar esa característica que no habías pensado antes. El investigar las aplicaciones 3D nos va a reducir esta pérdida de tiempo posterior. Hay que tener especial cuidad con los datos de materiales, que es algo fundamental para la tarjeta, y nos van a condicionar bastante en el futuro. Los programas de 3D actuales son bastante complejos en ese aspecto, así que tendréis trabajo para rato.

Nuestro programa (videojuego, demo, lo que sea) se encarga de comunicarse con la escena, normalmente de forma asíncrona (esto es, en cualquier momento, el estado de un nodo puede cambiar). Por ejemplo, en un videojuego de coches, puede pasar que la carrocería se deteriore, y tengamos que cambiar el modelo, o puede que un objeto en nuestra demo necesite cambiar de posición, o simplemente, reproducir una animación. Esto ya nos abre la via de los threads y la sincronización entre ellos. Podemos tener un thread sólo para pintar, y el juego estará "pensando" en otro thread, o gestionando los eventos del usuario, el paso del tiempo, etc. Esto se puede hacer en 1 solo hilo, pero hoy en día es común dividir las tareas en múltiples threads. Por ejemplo, la física suele estar en otro thread, la carga de texturas en otro dedicado, etc.

En el momento que decidimos pintar nuestra definición de escena, pasamos a "visitarla", recorriendo la definición pero no para pintar inmediatamente, si no para generar unas listas de datos en bruto que mandaremos a la tarjeta. Visitar es simplemente ir recorriendo los nodos de nuestra definición de escena, ejecutando unas funciones. Este proceso en 2 etapas es fundamental para entender cómo se genera un motor de render óptimo y cómo funcionan las tarjetas modernas.

El proceso es el siguiente. Imaginad que sólo tenemos nodos con una geometría, y una matriz de transformación. Visitamos el nodo raíz, leemos su matriz como matriz "actual", e insertamos el nodo con esa matriz en la lista. Vamos a su primer hijo. Leemos su matriz, y la multiplicamos por la de su nodo padre. Insertamos ese nodo en la lista, con la matriz multiplicada. Vamos así recorriendo los nodos (usando una pila para cuando tengamos que subir en la jerarquía). Al final tendremos una lista lineal que el API de la tarjeta ira pintando secuencialmente, con un "loadmatrix".

Esto tiene muchísimas ventajas. Una es separar la lógica de los gráficos. La definición de escena puede tener nodos del tipo "coche", "árbol", etc, pero al visitarlos, y crear la lista de objetos "renderizables", todos son mallas de vértices y caras. Al visitarlos, podemos descartar los objetos que no se van a ver, etc. Es importante el concepto moderno de objeto renderizable. Es importante que cada objeto en la lista tenga todas las propiedades necesarias para ser pintado, ya que es mucho mas optimo pintar los objetos agrupados por esas propiedades.

Una vez que tenemos las listas, le mandamos al driver gráfico la lista secuencial. El termino no deberíamos de confundirlo con el driver de la tarjeta. Nuestro propio driver es el que sabe como pintar, y se encargara de cosas como compilar el shader, enviar las texturas, cambiar los estados de render, leer las preferencias del usuario para pintar, etc. Aquí podemos generalizar la función "drawmesh" para que se encargue de seleccionar entre opengl/directx, etc. La idea es que el visitor tenga todo machacado, y que el driver simplemente pinte a lo tonto, sin preguntarse si debe o no hacerlo. De esta forma, todo va a ir mas rápido y sera fácil meter cambios en el motor (y poder reaprovecharlo en el futuro).

Por lo que al pensar en hacer un motor gráfico, debéis de repartir esas 4 tareas: exportado, scenegraph, visitor, driver gráfico. Cada tarea es en si bastante independiente (dentro de lo que cabe, claro), y mantener estas partes bien diferenciadas nos permitirá tener un motor mucho más flexible y fácil de mantener.

Una guía de desarrollo sería la siguiente:

a) Investigación.

Primero trabajar con varios programas 3D, y escribir algún tipo de exportador python para ellos (maya/xsi/luxology modo lo soportan, 3dsmax tiene su propio maxscript). Hacer un volcado de la escena a un fichero de texto es un muy buen ejercicio para tener claro las especificaciones del motor. Tarde o temprano tendréis que acceder a una aplicación 3D, y el leer sobre los datos que exporta el programa os dará una idea para acotar las posibilidades reales del motor (que la ignorancia suele definir en "infinitas")

Otro tema importante es mirar y conocer cómo trabajan otros motores de render. Ogre3D y el Irrlich son buenos candidatos para estudiar. yo comenzaría a mirar el irrlich, y después el ogre. Hacerse los tutoriales e implementar algún efecto nos ayudará a entender las problemáticas que tendremos que afrontar y ver cómo funcionan otras APIs. Cuanto más motores podáis analizar antes de comenzar programar el vuestro, mucho mejor, porque veréis las enormes diferencias entre ellos, y donde se va la carga de desarrollo. Es interesante que comentéis de estas investigaciones con otra gente para que os de ideas, y puntos de vista que no habíais pensado antes. Conocer un motor a fondo requiere tiempo.

b) Desarrollar vuestro propio driver gráfico. De eso hablaremos profundamente en el siguiente articulo. La idea es tener una librería de bajo nivel que vaya pintando listas de objetos previamente definidos. Podremos generar las listas de forma artesanal, o de forma precalculada. Por ejemplo, podremos comenzar a desarrollar una demo puramente gráfica, sin ningún tipo de iteractividad, pero muy eficiente pintado polígonos. Lo ideal es reducir el numero de características que vamos a pintar al principio, pero las pocas que tenga, que realmente funcionen muy bien y que este bien probada. No borres la demo porque te servirá para testear futuros desarrollos, independientemente del juego o aplicación que vayas a utilizar.

c) Desarrollar el vistante de scenegraph. Para esto dedicaremos el ultimo capitulo. Tenemos que ir leyendo algún parámetro adicional que cambie el estado del motor (posición del jugador, iteracion, físicas, etc) y nuestro programa generara la información necesaria para el driver grafico. En esta etapa, debemos de elegir bien que ira al driver y que podremos precalcular en el scenegraph.

d) Comenzaremos a implementar nuestra aplicación, que puede ser un juego, una demo interactiva o lo que sea. El proceso debería de ser iterativo. Ir probando las partes mas sencillas del motor con el artista, corregir los fallos que aparecen, y meter un nivel mas de complejidad. Por ejemplo, podemos comenzar con solo 1 shader y sin luces, e ir ampliando la lista de caracteristicas poco a poco. Primero metemos código de iluminación en el driver gráfico, metiendo directamente la info requerida por nosotros mismo, para después definirla desde el scenegraph, y posteriormente, a petición de la aplicación.

Espero que el articulo os haya entretenido, y os vengan las ganas de probar y comenzar un sencillo motor.

 

This e-mail address is being protected from spam bots, you need JavaScript enabled to view it  

 

blog  Jesús de Santos

 

blog de Iñigo Quilez

Comentarios
AgregarnuevoBuscar
- Rubén Penalva - Enhorabuena     | 195.219.143.xxx | 2008-03-31 13:30:14
Me lo he leido por encima y pinta muy bien. Tengo algunas ideas que comentaros, esta noche me lo leere con mas detenimiento y pondre por aqui los comentarios.

Me alegra ver que gente con tanta experiencia (y sobre todo en materias poco documentadas como el diseño de un motor 3d) se involucra en enseñar su conocimiento.

Excelente iniciativa.
- xphere - muy buena idea!!     | 195.28.224.xxx | 2008-03-31 15:00:31
Genial idea!! seguid asi!
- Guti - Felicidades     | 80.37.109.xxx | 2008-03-31 15:40:08
Estoy impaciente por ver como continúan los dos artículos que faltan.
malandrin   | 82.144.14.xxx | 2008-03-31 18:22:21
Joder, muchas gracias.
mimestim   | 84.79.161.xxx | 2008-03-31 20:44:12
Muchas gracias nuevamenta, se sale esta iniciativa, de momento me lo he bajado en pdf para luego leerlo detenidamente, de paso me he metido en favoritos los 2 blogs de los coautores para tambien hecharles un ojo y tal. Saludos.
- Diego - Felicidades!     | 84.78.38.xxx | 2008-03-31 22:34:11
Mola, lenguaje claro y sencillo para explicar conceptos no tan sencillos. La verdad es que apetece a ponerse a programar uno! :))
Felicidades a los tres, esperamos ansiosos el siguiente artículo, aunque el que tengo mas ganas de leer es el del visitante :), que parece que hay chicha ahí..
Me encanta la división visitante/driver/scenegraph, no la conocía y me parece divertidísima de implementar, y muy versátil y eficiente..
derethor   | Super Administrator | 2008-04-01 00:27:35
muchas gracias a todos! llevamos un tiempo trabajando en el tema de los articulos, haciendo correcciones y completando cosas, y creemos que ha salido algo que sera de ayuda a muchos.

Desde luego, os animo a todos a comenzar y probar uno. Desde luego, por mi parte, me encantaria que codepixel ayudase en todo a cualquiera que tenga ganas de comenzar.
derethor   | Super Administrator | 2008-04-01 00:51:07
para los que se han bajado el pdf.. por favor, volved a descargarlo, que habia alguna errata un poco "hoygan"
Pablo Quesada     | 85.48.37.xxx | 2008-04-01 01:45:23
Si que dan ganas de ponerse, aunque yo todavía no he encontrado tiempo para los papers :D (ya veo que el secreto esta en los threads ;)

El conocimiento, cuando se comparte, crece. Chapó.

Keep in touch
LaNsHoR     | 193.145.230.xxx | 2008-04-01 10:24:47
Sencillamente genial. Me uno a los agradecimientos que me preceden.

Ojalá pueda conseguir algo de tiempo para empezar a hacer pinitos en el tema.
sp3ctrum   | 89.140.89.xxx | 2008-04-07 08:11:07
Enhorabuena por la iniciativa, ojala existiera una comunidad técnica y productiva a este nivel.
- paola - critica   | 190.37.30.xxx | 2008-06-03 21:04:35
aunque sea pongan una foto del motor es para hacer un trabjo maricoooooos
- paola - crititca   | 190.37.1.xxx | 2008-06-05 22:21:38
no se les olvide poner imagenes xq sin imagenes esto es una porqueria
- vicente el largo - ¿como puedo conseguir objetos?   | 85.56.138.xxx | 2008-09-04 20:45:46
¿sabe alguien como puedo conseguir algun q otro objeto para decorar un salon, sofas y todo eso , pero modernos ¿hay alguna web q no haya q pàgarlos, valen un huevo los que he visto. gracias
Trape   | 189.179.219.xxx | 2008-12-30 04:06:00
Hola que tal exelente articulo, soy estudiante del IPN y he comenzado con el desarrollo de uno de estos como proyecto universitario pero la verdad no sabia ni por donde empezar, estos articulos son de mucha ayuda para los que somos estudiantes y queremos obtener acceso a conocimientos mas aya de viejos libros, en hora buena se han volado la barda y espero que les vaya bien en sus proyectos, q bueno q pongan esta clase de conceptos a la comunidad sin fines luvrativos por que no todos tenemos pasta pero si muchas ganas. suerte, ahi si pueden me echan una mano con mi motor para mi TT en fin de tos mos ya a empeze a hacer investigacion
- xames - motor   | 62.57.174.xxx | 2009-09-25 15:54:00
queria preguntar como se puede constrir un motor elctrico que no sea caro i que después funcione
me guistaria constrir un cohe y solo me falta un motor me poldriais decir como hacer in motor de imanes o de aire comprimido

Muchas gracias intentad responderme rapido por favor

adios
Escribir comentario
Nombre:
Email:
 
Website:
Título:
Código UBB:
[b] [i] [u] [url] [quote] [code] [img] 
 
Security Image
Por favor introduce el codigo anti-spam que puedes leer en la imagen.

Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved.



menéameDigg!Del.icio.us!Google!Technorati!Yahoo!
Last Updated ( Monday, 31 March 2008 )
 
< Prev   Next >

Lista de Correo

visita la lista de correo de codepixel. Es una lista abierta, asi que podrás subscribirte y preguntar tus dudas de programación, compartir tus opiniones, aportar ideas, y formar parte de la comunidad codepixelera.