Videojuegos 3D
Videojuegos 3D
Índice
Introducción............................................................................................... 5
Objetivos....................................................................................................... 6
1. Videojuegos 3D.................................................................................... 7
1.1. Videojuegos 2D frente a 3D ........................................................ 7
1.2. Game engines................................................................................. 10
1.2.1. Definición ...................................................................... 11
1.2.2. Arquitectura ................................................................... 16
1.2.3. Construir o comprar ...................................................... 23
1.2.4. Ejemplos ......................................................................... 24
1.2.5. Engines comerciales ........................................................ 29
1.2.6. Engines no comerciales .................................................. 39
1.2.7. Unity3D ......................................................................... 55
2. Física...................................................................................................... 72
2.1. Detección de colisiones .............................................................. 72
2.1.1. Volúmenes envolventes ................................................. 72
2.1.2. Jerarquías de volúmenes envolventes ........................... 75
2.1.3. Volúmenes envolventes a distinto nivel de detalle ....... 77
2.1.4. Descomposición del espacio .......................................... 77
2.2. Motores de física ......................................................................... 81
2.2.1. Newton Game Dynamics .............................................. 81
2.2.2. Open Dynamics Engine (ODE) ...................................... 82
Bibliografía................................................................................................. 189
© FUOC • PID_00185078 5 Videojuegos 3D
Introducción
Objetivos
1. Videojuegos 3D
La idea del Tile Based Engine es codificar todo un escenario siguiendo una es- Contenido
trategia que sea sencilla (es decir, que no suponga un coste de CPU conside- complementario
rable) y eficiente (o sea, recursos físicos de memoria y espacio de disco nece- Un Tile Based Engine puede ser-
sarios mínimos). Pues bien, podemos aplicar la misma idea cuando nuestro virnos para hacer un videojue-
go 3D. Para ello, deberemos
propósito es trabajar con un mundo 3D. Para ello, será necesario realizar la tratar el concepto anterior de
identificador de tile a un mo-
correspondencia tile (2D) - cubo (3D). Con esta idea, la implementación de un delo 3D como puede ser un
cubo. Diferentes ID se correla-
Tile Based Engine vista en el módulo anterior y unas nociones de geometría y
cionarán con cubos con dife-
mapeado de texturas para conseguir un mayor realismo visual, ya estaríamos rentes texturas.
Realizado por Pere Alsina, ex alumno del curso Iniciación a los Videojuegos de la UPC.
En las siguientes imágenes, se ven estas diferencias entre dos videojuegos del
género RTS (Real Time Strategy, estrategia en tiempo real): Warcraft II y Warcraft
III de la compañía Blizzard.
© FUOC • PID_00185078 9 Videojuegos 3D
De arriba a abajo y de izquierda a derecha, FIFA 95, PES, Yahoo Billar online y Foo Billard
© FUOC • PID_00185078 10 Videojuegos 3D
Aspectos 2D 3D
Física Bound boxes, bounding circles, pixel perfect, tiles AABB, OBB, K-d trees, BSP, Octrees
Si enriquecemos este módulo con elementos como física, redes o sonido, por
ejemplo, tendremos lo que llamamos un game engine (motor de videojuego).
De hecho, estos otros modelos también pueden presentarse de forma indepen-
diente dando lugar a un Physics Engine (motor físico) u otras capas o librerías
como pueden ser una Networking Layer (capa de red) para el desarrollo de vi-
deojuegos en línea.
1.2.1. Definición
Funcionalidades
Las funcionalidades (features) que puede brindar un motor es una de las deci-
siones más importantes que habrá que tomar. Serán diferentes según el género
del videojuego y deberá decidirse hasta qué nivel serán ofrecidas. Entre ellas
cabrá especificar diferentes aspectos como, por ejemplo, los siguientes:
Como hemos dicho, un game engine puede plantearse para dar soporte a una
solución en concreto o para acaparar un dominio mayor. A continuación, mos-
traremos dos videojuegos totalmente diferentes para detallar qué funcionali-
dades debería aportar cada uno de los motores sobre los que funcionarán.
© FUOC • PID_00185078 12 Videojuegos 3D
En el caso del videojuego Ned for speed, tenemos un videojuego del género
motor y sus necesidades vienen dadas por su género. El apartado gráfico y físi-
co deberá proporcionar una rápida respuesta para conseguir una fluida visua-
lización en tiempo real. Otros aspectos, como la técnica del motion blur, ayu-
darán a tal finalidad y a ofrecer una mayor inmersión en cuanto a velocidad
se refiere en el juego.
En el caso del videojuego Devil may cry, tenemos otros aspectos principales,
como la colocación y el tratamiento de la cámara, un algoritmo más preciso
para la detección de colisiones para interiores, múltiples y variados efectos
especiales de explosiones y disparos o el tratamiento de las animaciones de los
modelos y la interacción entre ellos.
Optimizaciones
A continuación, estudiemos dos juegos bien diferentes para corroborar las op-
timizaciones de las que deberán estar provistos cada uno de ellos.
© FUOC • PID_00185078 13 Videojuegos 3D
En el caso del juego de la serie de ID Software, Doom III, el factor más relevan-
te es la inmersión que se obtiene con el realismo gráfico. Los aspectos de tex-
turizado e iluminación que lo hacen posible se ofrecen en un alto grado de
calidad, de forma transparente (juego fluido) al usuario, aunque sea necesaria
una lógica potencia hardware.
Hardware
La continua evolución del hardware es el factor más importante que nos de-
fine la vida útil de un motor de videojuego. Concretamente nos referimos a
las tarjetas gráficas, al gran progreso del rendimiento de las GPU, que se vio
iniciado por la Voodoo, la primera tarjeta gráfica aceleradora 3D desarrollada
por 3DFX, en octubre del año 1996. A esta empresa le siguieron las que unos
años más tarde se convertirían en sus más grandes competidores, NVIDIA y
ATI y que, de hecho, abarcan el mercado actual.
© FUOC • PID_00185078 14 Videojuegos 3D
En términos generales, podemos indicar que las ventajas gráficas son el ele-
mento que más evoluciona del PC, duplican su potencia cada seis meses (lo
cual supone un incremento tres veces mayor al de la CPU) y, de hecho, el papel
de la GPU, su innovación en términos históricos, es tan sólo comparable con
la llegada de la memoria caché (1980).
Software
Los paquetes o programas típicos que suelen estar ligados a un motor de video-
juego son el editor de niveles y el editor de modelos. Otros que pueden apare-
cer son: editor de sistemas de partículas, editor de shaders y editor de terrenos.
1.2.2. Arquitectura
Los cuatro módulos que se encuentran en la parte inferior tratan la dependencia con el hardware; de color más oscuro
podemos apreciar los módulos principales; y de color más claro, los secundarios.
© FUOC • PID_00185078 17 Videojuegos 3D
Graphics Engine
El algoritmo de visibilidad del Portal Culling es un punto que puede tratar un Graphics Engine para trabajar con
escenarios indoors.
© FUOC • PID_00185078 18 Videojuegos 3D
Physics Engine
En lo que respecta a reacciones por colisiones o fuerzas externas, tenemos las Ved también
leyes físicas ya expuestas simulando física newtoniana, velocidades, fricción,
Podéis consultar las leyes físi-
inercia, campos magnéticos, etc. Por otro lado, también tienen lugar aquellos cas relacionadas con reaccio-
objetos que mantienen nexos de unión con otros (joins) y que, al ser sometidos nes por colisiones o fuerzas ex-
ternas en el módulo "Videojue-
a cualquier física, responden provocando una reacción en cadena entre ellos. gos 2D".
© FUOC • PID_00185078 19 Videojuegos 3D
Sound System
Networking
Hoy por hoy, la capa de red en los videojuegos tiene una marcada presencia. La
mayoría de éstos ofrecen el servicio en línea para añadir mayor entretenimien-
to; incluso, para algunos, es un medio imprescindible. En este ámbito, según
necesidades específicas, se tratan arquitecturas cliente-servidor, P2P, granjas,
grids o híbridas.
© FUOC • PID_00185078 20 Videojuegos 3D
Estos modelos dan respuestas diferentes para cada tipo de juego en línea, según
los siguientes factores:
• Baja latencia (lag): el retardo entre jugadores, que debe ser pequeño, ayuda
a la consistencia.
• Fiabilidad: ante situaciones adversas, que el juego pueda continuar sin ma-
yores problemas.
La información que se envía puede ser vía protocolo TCP (la información in-
dispensable) o UDP (el resto de la información). Una guía general para cual-
quier tipo de juego en red debe contemplar los siguientes puntos:
• Sólo enviar lo necesario (el qué): estado del juego y cambios de estado,
movimiento y acciones de personajes, colocación de objetos, condiciones
de nivel, etc.
© FUOC • PID_00185078 21 Videojuegos 3D
• Sólo enviar donde sea necesario: cada cambio de estado no debe ser en-
viado a todos los jugadores, sino sólo a los que vayan a verse afectados.
Por ejemplo, si los jugadores no se ven entre sí, incrementa complejidad,
pero obtenemos grandes beneficios.
Script Engine
• Los scripts pueden ser cambiados de manera mucho más fácil que el código.
De hecho, gracias a todos estos factores, podemos decir que la técnica del scrip-
ting hace posible la existencia de los Mods, concepto que proviene de la pa-
labra del inglés "modifications". Los cambios y las nuevas funcionalidades se
pueden realizar mediante herramientas de edición sencillas que han tenido
una gran presencia, sobre todo en los videojuegos FPS (first person shooters) y
RTS (real-time strategy).
Inteligencia Artificial
El pathfinding en juegos RTS como Warcraft II, es imprescindible para el movimiento de tropas.
Un game engine es un producto software muy complejo. Por tanto, como estu-
dio de desarrollo, la reflexión que deberemos realizar acerca de si construir o
comprar un motor deberá efectuarse con máxima precaución y detenimiento.
• Features: qué funcionalidades y hasta qué nivel son ofrecidas, módulos que
incorpora, tipos de formatos, etc.
• Nivel de soporte: documentación de la SDK, ejemplos, servicio de ayu-
da/consultoría.
• Vida: limitaciones, ampliable, modificable.
• Precio: hace unos años eran muy caros, centenares de miles de euros pero,
hoy en día, se ha convertido en un mercado más o menos accesible como
veremos en el apartado de ejemplos.
1.2.4. Ejemplos
SCUMM son las siglas de "Script Creation Utility for Maniac Mansion". Se
trata de un motor de videojuego de aventuras gráficas, desarrollado por Aric
Wilmunder y Ron Gilbert, y que dio luz, a través del juego que se incluye en
las propias siglas, Maniac Mansion en 1988.
Versiones SCUMM
v3.5.37: Loom
De izquierda a derecha y de arriba abajo: Maniac Mansion (1988), The Secret of Monkey Island (1990), Indiana Jones and the Fate of Atlantis (1992) y Day of the Tentacle (1993)
Las siguientes dos figuras hacen referencia a la solución concreta de Umbra. Web
La imagen de la izquierda se corresponde con la visualización de un mundo
Para entender con mayor
virtual en 3D que podría ser ofrecida por un motor de juego. En la primera profundidad el concepto de
figura, en la imagen de la derecha, se puede apreciar el conjunto de datos que middleware, recomendamos
ver el vídeo, en el cual es
son mostrados desde una cámara situada a una cierta altitud. En la segunda, posible apreciar la solución
concreta de Umbra.
se ilustra el conjunto de datos con los que trabajamos al filtrar el conjunto de
información a través de este middleware.
© FUOC • PID_00185078 27 Videojuegos 3D
Sin Umbra. A la izquierda tenemos una visualización en tercera persona desde el punto de vista del jugador. A la derecha, desde
una cámara superior, podemos ver una cantidad de objetos considerables que no contribuyen a la imagen final.
Con Umbra. El software determina qué objetos son visibles y sólo se envían a procesar estos, con la consiguiente ganancia en
rendimiento.
SpeedTree es una tecnología para modelar y simular la animación de la vegetación no sólo para videojuegos sino también para
películas, como las de este fotograma perteneciente a Avatar.
Ejemplos de motores:
Cry Engine
Crytek
Es de destacar la buena impresión que ha dado la industria del videjuego cuan- Web
do Crytek ha realizado sus demos técnicas en las sucesivas ediciones pasadas
Aquí podéis ver el vídeo que
del evento GDC (Game Developers Conference). En ellas se puede apreciar como hace referencia al Game De-
el tiempo de edición y de juego se combinan perfectamente al instante. Algo velopers Conference del año
2007.
que, por otra parte, ya es posible hacer con muchos motores de hoy en día.
© FUOC • PID_00185078 30 Videojuegos 3D
En el mes de agosto del 2011 apareció la versión gratuita de este SDK para Web
su uso no comercial, dirigido, sobre todo, a un perfil académico. En sus dos
Se ha creado una página web
primeras semanas ha llegado a descargarse en más de 300.000 ocasiones. específica para este tipo de
público interesado, donde
además encontramos foros,
Unreal Engine ayudas y soporte.
Unreal Level Editor, una de las muchas herramientas de las que viene provisto el motor Unreal Engine.
Dada la importancia de este motor, veremos con mayor detalle cuál y cómo ha
sido su evolución, desde su primera versión hasta su anunciada, pero aún no
acabada, cuarta versión. De esta manera podremos apreciar el proceso evoluti-
vo de un motor de alta complejidad así como algunas de sus particularidades.
La segunda versión del Unreal Engine hace su debut con America's Army en el
2002. Esta generación pasó por una reescritura completa del código del núcleo
y del motor de renderizado, además de integrar el nuevo UnrealEd 3. También
incluyó el SDK de Karma physics. Muchos otros elementos del motor fueron
actualizados, con mejoras, agregando soporte para la PlayStation 2, GameCube
y Xbox.
Gears of War 2 desarrollado por Epic Games y distribuido por Microsoft Game Studio utiliza el motor Unreal Engine.
Otro aspecto muy importante que hace referencia a este motor y a otros tantos Web
de manera especial es el hecho de que el 5 de noviembre del 2009 Epic Games
Os invitamos a realizar una
publicara una versión gratuita del Unreal Development Kit para permitir a visita a la página de UDK y
grupos de desarrolladores amateur realizar juegos con el Unreal Engine 3. Esto ver el total de funcionalida-
des que ofrece esta licencia.
es una política que se ha propagado en otras soluciones y que ha abierto las No se trata de una licencia
gratuita sin más, existen unas
puertas al público amateur, ya sea a nivel docente o para que estudios pequeños
condiciones, tal y como se
independientes iniciaran su periplo en la industria. detallan en su página web,
pero para iniciados, puede re-
sultar una experiencia muy
enriquecedora.
Fuentes de Epic fechan la próxima versión del motor (cuarta) para ser utilizada
durante los años 2012 a 2018. De momento su tercera versión sigue mejorán-
dose y utilizándose como se ha hecho recientemente en Gears of War 3, donde
ha alcanzado su versión 3.8.
variedad de licencias muy atractivas y con una versión para juegos 2D así como
3D.
A pesar de que se han realizado bastantes juegos con este motor, no son tan
destacables como en los motores que hemos mencionado con anterioridad.
Algunos ejemplos de juegos implementados con Torque son: Blockland, Mar-
ble Blast Gold, Minions of Mirth, TubeTwist, Ultimate Duck Hunting, Wildli-
fe Tycoon: Venture Africa, ThinkTanks, The Destiny of Zorro y Penny Arcade
Adventures.
© FUOC • PID_00185078 34 Videojuegos 3D
El estudio Golgoth ha desarrollado un remake del conocido juego Toki utilizando el motor Torque.
Unity 3D
Unity es una herramienta con un motor integrado para crear juegos 3D o cual-
quier tipo de contenido interactivo, como visualizaciones arquitectónicas y
animaciones 3D en tiempo real. Es similar a otras herramientas como las que
hemos visto con anterioridad, como el Torque Game Builder o el sandbox de
Unity 3D
CryEngine, puesto que el método de desarrollo principal se desarrolla a través
de una compleja interfaz gráfica desde la cual puede realizarse todo o casi todo
el proyecto. He aquí una muestra de la herramienta en ejecución.
© FUOC • PID_00185078 35 Videojuegos 3D
El editor de Unity. Desde este es posible realizar las principales fases de desarrollo del proyecto y probarlo ejecutándolo al
instante.
Dado que la versión gratuita del motor cuenta con un número de posibilidades
muy grande, el número de plataformas que soporta está muy bien y si quisié-
ramos optar por una futura implicación profesional mayor, sus licencias son
realmente asequibles, veremos con mayor detalle este motor en el siguiente
apartado. Detallaremos sus capacidades y veremos los primeros pasos de có-
mo se desarrolla un proyecto con un motor de los llamados point and click, a
partir de una compleja interfaz gráfica que permite editar y probar el proyecto
al instante.
© FUOC • PID_00185078 36 Videojuegos 3D
Vision Engine
Se trata de una tecnología desarrollada por el estudio Trinigy desde el año 2003
y que actualmente alcanza su octava versión. Es un motor 3D multiplaforma
disponible para PC, Xbox 360, PlayStation 3 y Wii y está enfocado a la pro-
ducción tanto de videojuegos profesionales como de serious games. Se ha uti-
Trinigy
lizado en más de 150 juegos comerciales para compañías como Ubisoft, Take
Two Interactive, JoWood, FireFly Studios, Spellbound y Neowiz.
A pesar de estas cifras los juegos desarrollados no son tan conocidos como Web
cabría esperar y entre ellos destacan Arcania: A Gothic Tale, The Settlers 7:
Aquí podéis encontrar una
Paths to a Kingdom, DIZZEL, Dungeon Hero, Arena Morte, Cutthroat y el jue- lista más extensa de juegos
go desarrollado en España por Pyro Studios Planet 51. desarrollada con Vision Engi-
ne.
Planet 51: The Game, juego de la conocida película de animación del estudio español Illion Animation Studios, desarrollado en
España por Pyro Studios y distribuido por Sega, utiliza la tecnología de Trinigy Vision Engine.
Vision Engine utiliza una serie de middlewares bastante importantes y bien co-
nocidos en la industria. Éstos colaboran con el estudio en forma de partner y
son los siguientes: SpeedTree, nVidia PhysX, Autodesk Kynapse, Autodesk Hu-
manIK, Scaleform, Quazal, FMOD, ProFX 2, OpenAL, Bullet, NaturalMotion,
Morpheme, Xaitment, Pixellux Digital Molecular Matter, NetDog, Allegorith-
mic, Havok Physics.
id Tech
Wolfenstein 3D, uno de los juegos predecesores que contribuyó tecnológicamente hablando a lo que después sería el motor id
Tech.
Es importante también dar a conocer que, conforme han surgido las versiones
de este motor, las anteriores han sido publicadas con licencias GNU, con el
consiguiente aporte a la comunidad y público amateur. Actualmente, idTech
1, 2 y 3 se encuentran bajo esta licencia de software abierto. idTech 6 es un
motor de juegos basado en OpenGL que todavía se encuentra en el inicio de
su desarrollo.
© FUOC • PID_00185078 39 Videojuegos 3D
Se desconoce el precio y tipo de licencias que ha sido posible obtener con este
motor. Suponemos que ha sido necesario ponerse en contacto directamente
con la empresa. Es posible que se trate de una de las tecnologías más caras que
ha habido en el sector. La exclusividad queda aún más patente a partir de id
Tech 5, solo disponible para su estudio hermano Bethesda.
Una vez vistas unas pinceladas sobre algunos de los motores de videojuegos
comerciales, entraremos un poco más en detalle en lo que respecta a los open
source game engines. Para ello, daremos algunos datos de cada uno de los mo-
tores libres mencionados con anterioridad, describiremos alguna de sus prin-
cipales características y mostraremos algunas imágenes de lo que se ha llegado
a hacer con ellos.
Cuando queremos elegir un motor libre, existen algunos datos de cierta rele-
vancia que hemos de tener en cuenta. Una de las primeras cosas que solemos
hacer es ver los proyectos que se han desarrollado con esta tecnología. Es una
prueba unequívoca y a una primera vista nos dirá, como mínimo, que es capaz
de ofrecernos.
Por último, pero muy importante, tenemos las features, las funcionalidades
que nos brinda el motor. Para un proyecto académico es de crucial importancia
aspectos básicos como el tratamiento de la carga y animación de modelos 3D.
Todos los motores admiten este aspecto pero, sin embargo, dan respuesta a un
número de formatos reducido. Por ello dos cosas que debemos observar es el
tipo de formato y la existencia de un posible plug-in de exportación de datos.
© FUOC • PID_00185078 40 Videojuegos 3D
Para el tipo de formato de un modelo, puede sernos útil la carga de un forma- Web
to libre, estándar, o suficientemente apoyado por la industria, como podrían
Aquí podéis acceder a más in-
ser OBJ, FBX y collada. Otro tipo de formato podría ser el profesional pero formación relativa a los for-
liberado, como por ejemplo sería el formato de los modelos del juego Quake matos: FBX y collada.
Una vez presentadas algunas cuestiones que hemos de tener en cuenta, pode-
mos ver las características de los motores libres que hemos mencionado con
anterioridad. Se trata de una lista que contiene casos bien diferentes. Los hay
más o menos recientes, que no continúan desarrollándose o que, a pesar de
su tiempo de vida sigue vigente e incluso como solución que vio su origen en
el ámbito militar.
© FUOC • PID_00185078 41 Videojuegos 3D
Irrlicht
Nebula Device
Genius 2: Taskforce Biology y Sportfischen Professional dos juegos realizados con Nebula Device 2.
© FUOC • PID_00185078 44 Videojuegos 3D
Fly3D
• "Free and open source 3D game engine", • General Features: Plug-in Architecture
desde el 2000 • Built-in Editors: Shader and world builders
• Versión actual: 2.10 (Enero 2003) • Physics: Basic Physics, Collision Detection,
• Autor: Fabio Policarpo Rigid Body
• Origen didáctico: libro "3D Games: Real-Ti- • Lighting: Per-vertex, Per-pixel, Volumetric
me Rendering and Software Technology" • Shadows: Shadow Mapping
• No se continúa desarrollando • Texturing: Basic, Multi-texturing, Bump-
• Lenguaje C++ mapping
• Plataforma: Windows • Scene Management: BSP, PVS
• API gráfica: OpenGL (render) y DirectX (in- • Animation: Keyframe Animation, Skeletal
put, sound) Animation
• Web: http://fabio.policarpo.nom.br/fly3d/ • Meshes: Mesh Loading, Skinning
• Surfaces & Curves: Splines, Patches
• Special Effects: Environment Mapping, Lens
Flares, Billboarding, Particle System, Depth
of Field, Motion Blur, Sky, Water
• Terrain: Rendering, CLOD
• Networking System: Client-Server
• Sound: 2D Sound, 3D Sound
• Artificial Intelligence: Pathfinding, Scripted
© FUOC • PID_00185078 45 Videojuegos 3D
Delta3D
• "Open source gaming & simulation engine • General Features: Object-Oriented Design
backed by the U.S. Military", desde el 2004 • Scripting: Python Bindings
(v0.1) • Built-in Editors: scene editor
• Versión actual: 2.7.1 (Agosto 2011) • Physics: Collision Detection, Rigid Body
• Origen: US Navy, después fin docente • Lighting: Per-vertex, Per-pixel
• Plataforma: Windows, Linux • Texturing: Basic, Multi-texturing, Bump-
• API gráfica: OpenGL 2.0 mapping, Procedural
• Web: http://delta3d.org/ • Shaders: Vertex, Pixel
• Scene Management: General, LOD
• Animation: Skeletal Animation
• Meshes: Mesh Loading, Tessellation
• Special Effects: Billboarding, Particle Sys-
tem, Sky, Explosion, Fog, Weather
• Terrain: Rendering, CLOD
• Networking System: Master Server
• Sound & Video: 2D Sound, 3D Sound
• Rendering: Fixed-function, Stereo Rende-
ring, Render-to-Texture, Fonts, GUI
© FUOC • PID_00185078 46 Videojuegos 3D
Imágenes de los proyectos Delta3D Cave Simulation y Nemesis realizados con Delta3D.
© FUOC • PID_00185078 47 Videojuegos 3D
Crystal Space
Dareks penguins un proyecto indie y Keepsake un proyecto comercial realizados con Crystal Space.
Ogre
Imágenes del juego Torchlight desarrollado por Runic Games mediante Ogre.
© FUOC • PID_00185078 51 Videojuegos 3D
Panda 3D
• "Framework for 3D rendering and game de- • General Features: Object-Oriented Design
velopment", desde 2002 • Scripting: python
• Versión actual: 1.7 (2009) • Built-in Editors: scene editor and particle ef-
- Autor: Disney y Carnigie Mellon University fects
• Lenguaje: C++, Python • Physics: Basic Physics, Collision Detection,
• Plataforma: Linux, Mac, Windows Rigid Body, Vehicle Physics
• API gráfica: DirectX y OpenGL • Lighting: Per-vertex, Per-pixel, Volumetric
• Web: www.panda3d.org • Texturing: Basic
• Shaders: High Level
• Animation: Skeletal Animation
• Meshes: Mesh Loading, Skinning
• Special Effects: Particle System, Motion
Blur, Fog
• Terrain: Rendering
• Networking System: Client-Server
• Sound & Video: 2D Sound, 3D Sound,
Streaming Sound
• Artificial Intelligence: Finite State Machines
• Rendering: Fixed-function, Stereo Rende-
ring, GUI
El origen de este motor reside en Disney VR, rama creada por Disney para
construir atracciones en 3D para sus parques temáticos. Construyeron una
atracción llamada Aladdin's Magic Carpet, y el motor que crearon para ello es
lo que finalmente seria Panda3D. Este motor fue utilizado en la creación de
Toontown Online, un juego en línea sobre un mundo de dibujos animados y
después para la creación de un segundo MMORPG, Pirates of the Caribbean
Online.
© FUOC • PID_00185078 52 Videojuegos 3D
Imágenes del juego Pirates of the Caribbean Online de Disney desarrollado con Panda 3D.
En el 2002, el motor fue liberado como código abierto. Según los autores, de
este modo "sería más fácil trabajar con otras universidades en proyectos de in-
vestigación sobre realidad virtual". El hecho de liberar el motor permitió que el
centro tecnológico de entretenimiento de Carnigie Mellon se uniera al desa-
rrollo del motor. Mientras que ingenieros de Disney continuaron con la mayor
parte del desarrollo, el equipo de Carnegie Mellon se propuso el rol de pulir
el motor para el provecho público, escribiendo documentación y añadiendo
determinadas funcionalidades como la tecnología shader.
© FUOC • PID_00185078 53 Videojuegos 3D
• "Open source 3D modeling, rendering, ani- • General Features: Plug-in Architecture, Sa-
mation and realtime 3D game/simulation ve/Load System
development system", desde 2000. • Scripting: Python
• Versión actual: 2.59 (2011) • Built-in Editors: scene management, anima-
• Autor: Erwin Coumans y Gino van den Ber- tion curves/keys, schematic scene diagram,
gen non-linear video sequence editing, charac-
• Lenguaje: C/C++, Python ter animation action editor, non-linear ani-
• Plataforma: Linux, Mac, Windows mation mixer, image/UV editing, file/ima-
• API gráfica: OpenGL ge selection and file management, interfa-
• Web: www.blender.org ces and much more
• Physics: Basic Physics, Collision Detection,
Rigid Body, Vehicle Physics
• Lighting: Per-vertex, Per-pixel
- Shadows: Shadow Mapping
• Texturing: Basic, Multi-texturing, Bump-
mapping
• Shaders: Vertex, Pixel
• Scene Management: General
• Animation: Inverse Kinematics, Keyframe
Animation
• Meshes: Mesh Loading, Skinning
• Surfaces & Curves: Splines
• Special Effects: Environment Mapping, Par-
ticle System, Sky, Water, Fog
• Terrain: Rendering
• Networking System: Client-Server
• Sound & Video: 2D Sound, 3D Sound
• Artificial Intelligence: Scripted
• Rendering: Fixed-function, Fonts, GUI
Blender Game Engine es un caso muy diferente a los motores libres tratados
con anterioridad. Este es un motor que incluiríamos en la categoría point-and-
click, es decir, basados en una compleja y completísima interfaz gráfica, como
por ejemplo Unity o UDK. Es un motor, un módulo, integrado en la ya de por
sí sofisticada herramienta de modelado y animación 3D que es Blender.
En lo que respecta a juegos realizados con Blender los resultados aún no son
tan espectaculares. Si bien existe una cantidad considerable, la mayoría de
estos proyectos no son de muy alta calidad. Podemos destacar, por ejemplo,
los proyectos Dead Cyborg y Krum, aunque ambos se encuentran todavía en
desarrollo. He aquí dos respectivas imágenes.
Dead Cyborg y Krum dos proyectos en desarrollo realizados con Blender Game Engine.
© FUOC • PID_00185078 55 Videojuegos 3D
1.2.7. Unity3D
Unity3D es uno de los motores más recomendados con mucha diferencia da- Web
da su relación calidad, realmente asombrosa, y precio, realmente asequible.
Aquí podéis ver descrito el
Entre ellas cabe destacar sus funcionalidades de rendering, iluminación, tex- conjunto de funcionalidades
turas, física, audio, sus diversas posibilidades en cuanto a programación y re- de Unity3D.
También podéis descargar la
des. Invitamos al lector a hacer una visita al enlace proporcionado para una herramienta Unity3D.
mayor y extensa información. En este apartado nos ceñiremos a todo lo que
concierne a su uso.
Llegados a este punto, podemos tener una primera idea de lo que significa Web
Unity3D y en general un motor empaquetado como una herramienta para
Aquí podéis observar las fun-
crear videojuegos, aplicaciones interactivas o cualquier tipo de visualizaciones cionalidades y/o limitaciones
y animaciones 3D en tiempo real. Este tipo de herramientas suele ser fácil de de Unity3D.
obtener e instalar y, por lo general, siempre podemos contar con algún tipo de
licencia que nos permite trabajar con ella y ver sus principales funcionalidades.
Las licencias de pago suelen ofrecernos mejores modelos de iluminación, con
lo que se adquiere un mayor realismo visual (que no tiene por qué traducirse
a un mejor entretenimiento en el caso de los videojuegos) así como diferentes
portings a otras plataformas, como son las diferentes consolas o dispositivos
móviles. En la especificación de los detalles de cada licencia se pueden apreciar
las funcionalidades y/o limitaciones de cada una.
Una vez realizada esta pequeña práctica, pasaremos a ver cómo es posible cum-
plir con nuestro primer proyecto con Unity3D y, en realidad, cualquier tipo de
aplicación con una herramienta de este tipo. Nuestro ejercicio "hola mundo"
tratará los principales puntos que existen en una aplicación gráfica en tiempo
real. Para ello primero presentaremos los elementos principales de la interfaz
gráfica y, acto seguido, crearemos un proyecto con un escenario compuesto
por un terreno y un cielo, colocaremos luces, un controlador en primera per-
sona a partir del cual navegaremos y, por último, veremos cómo crear nuestro
ejecutable. Estos pasos se presentarán de forma que sean muy fáciles de seguir,
sin extenderse en un sinfín de posibilidades, de tal modo que con esta lectura
sea suficiente para hacer el proyecto en paralelo. Existen muchos tutoriales y
bibliografía a tal efecto disponibles en la web y, por eso, dejaremos aparte los
aspectos concretos para centrarnos en los conceptos base, que debemos buscar
y saber encontrar en un motor de estas características.
Como hemos dicho, Unity3D ofrece un completo editor visual a partir del
cual es posible realizar videojuegos y todo tipo de aplicaciones del tipo serious
games. Fruto de todo este gran abanico de funcionalidades que nos brinda,
quizás, lo más probable es que cuando hemos arrancado por primera vez el
programa nos hemos asustado un poco. Es normal, no hay que atemorizarse,
se trata de un GUI compleja que quiere ayudarnos mucho y, por tanto, nos
da mucho. Es algo que se aprende con un poco de práctica y para nada es
necesario memorizar.
• Project: es la vista del proyecto y muestra la lista de todos los assets (que
podríamos traducir como recursos) que hay disponibles para usar en nues-
tro videojuego.
• Inspector: es la vista de inspección y muestra una lista con todas las pro-
piedades del objeto del videojuego que tienes seleccionado. Si no tienes
ningún objeto seleccionado no mostrará nada.
Este tipo de estructura es algo común entre cualquier otro motor de este tipo
así como, por ejemplo, de otras herramientas como podría ser Flash de Adobe,
también utilizada para desarrollar videojuegos así como películas de anima-
ción 2D, como la conocida serie española Cálico Electrónico. Si habéis utili-
zado alguna vez esta herramienta, os daréis cuenta de que también existe una
vista de Proyecto (llamada Biblioteca), donde se ubican los elementos diseña-
dos e instanciables en nuestra película. La vista Escena contiene el editor de
la película propiamente dicho y por tanto contiene sus capas y fotogramas.
En ella se aprecian las diferentes instancias y, cuando seleccionamos alguna
de ellas, podemos modificar sus atributos mediante el panel de propiedades
(el inspector en Unity3D). No existe vista Juego pero, mediante una simple
© FUOC • PID_00185078 59 Videojuegos 3D
Empezaremos por el elemento más sencillo, el gizmo scene, que tiene el siguien-
te aspecto:
• La caja nos lleva al modo perspectiva y es el que solemos utilizar por de-
fecto.
• El cono verde (y) nos permite apreciar la escena desde una vista ortográfica
top-down, vista desde arriba.
Ahora que hemos aprendido cómo poder apreciar la escena desde las diferentes
vistas, lo siguiente que necesitaremos es navegar a través de ella. Para ello es
necesario conocer el siguiente panel de control.
Los tres botones siguientes al de la mano, que nos permite movernos por la
escena, hacen referencia a la transformación geométrica que podemos hacer
sobre un objeto en la escena: translación, rotación y escalado. Para facilitar
esta configuración, Unity nos proporciona la siguiente interfaz gráfica para
cada herramienta:
Además de estos sencillos elementos de control, nos será muy útil conocer la
siguiente barra de herramientas, que hace referencia a la configuración de la
visualización.
• Textured: muestra las superficies con sus texturas tal y como después se
verá en el juego.
Las otras dos opciones del menú desplegable render paths y lightmap resolution
de momento no es necesario conocerlas. Hacen referencia al modelo de ilu-
minación (deferred lighting, forward rendering y vertex lit) y a la técnica del light-
maping, las texturas de iluminación pre-calculadas.
Visualización de una escena con Unity en los modos textured, wireframe y tex-wire respectivamente
© FUOC • PID_00185078 62 Videojuegos 3D
Proyecto de ejemplo
2) Creación de un terreno.
Estos son los pasos que ayudarán a introducirse mediante cualquier solución
tecnológica. Una vez vistos estos puntos, recomendaríamos tratar temas como
podrían ser los siguientes: carga y animación de modelos 3D, simulación de
efectos a partir de sistemas de partículas, reproducción de sonido, interacción
física, implementación de comportamientos a partir de scripting o modelos de
iluminación con shaders.
1)�Creación�de�un�nuevo�proyecto
Crear un proyecto con Unity es tan sencillo como seleccionar a partir del me-
nú la opción File > New Project... Se nos pedirá una ruta para el proyecto y
podremos elegir entre una lista generosa de paquetes que podremos incluir.
Los nombres de estos paquetes son lo suficientemente intuitivos como para
atrevernos con la selección de alguno de ellos y poderlos utilizar más adelante.
El proyecto que vamos a iniciar no incluirá ningún paquete de momento.
peta Assets a partir de la ruta que hayamos indicado al crear el proyecto. Co-
mo se puede apreciar en la vista Escena, tenemos una escenario vacío en el
cual Unity ha añadido una cámara inicial, tal y como puede observarse tanto
en la vista Escena como en la vista Jerarquía, de nombre Main Camera. Si la
seleccionamos podremos apreciar sus propiedades en el panel de inspección.
No hace falta que modifiquemos sus valores, pero si les prestamos un poco
de atención, reconoceremos algunos conceptos teóricos del mundo de la pro-
gramación gráfica. Nos resultarán más familiares cuanto mayor sea nuestro
conocimiento.
2)�Creación�de�un�terreno
La mayoría de motores de este tipo tratan los terrenos del mismo modo. Son
posibles editarlos desde la misma aplicación esculpiéndolos o cargados a partir
de modelos basados en alturas (en inglés digital elevation models o DEM), cuyos
ficheros suelen ser de extensión raw. Esta opción es accesible a través del menú
Terrain > Import Heightmap - Raw... Para editarlos, podemos acceder a dife-
rentes herramientas a partir del panel de inspección una vez hayamos selec-
cionado el terreno. Son posibles operaciones de elevación, rebajar y suavizar
el terreno y utilizar diferentes tipos y tamaños de pinceles entre otras. He aquí
una imagen con el panel de inspección sobre el terreno y sus posibilidades.
© FUOC • PID_00185078 65 Videojuegos 3D
Las posibilidades que nos brinda son bastante intuitivas y a partir de un prueba
y error nos podemos familiarizar rápidamente con la mayoría de las opciones.
El proceso de aplicación de una textura sobre un terreno con Unity. Arriba la ventana de herramienta de textura y debajo la
ventana de selección textura y sus propiedades.
3)�Cielo,�niebla�e�iluminación
Para añadir un cielo a nuestra escena es necesario acceder a Edit > Render
Settings. La opción Skybox Material es la que nos interesa. Al igual que en el
caso de la textura del terreno, si al crear el proyecto no incluimos la opción
del paquete de skyboxes, no podremos escoger una textura de cielo preparada.
En esta ocasión vamos a solucionarlo de otra manera. Podemos incluir un
paquete a nuestro proyecto en el momento que queramos. Es suficiente con
hacer clic con el botón derecho sobre el panel de proyecto y seleccionar la
opción Import Package > Skyboxes. Ahora ya podremos escoger el que más
nos guste y probarlo en directo.
También a partir de la opción Edit > Render Settings es posible añadir niebla
a nuestra escena. Se trata de opción fog (niebla en inglés). Podemos escoger
el tipo de niebla según como desvanece (lineal, exponencial o exponencial
cuadrática) y otros atributos como el color. Todos estos parámetros son los que
precisamente se pueden configurar programando con una API gráfica como
OpenGL.
© FUOC • PID_00185078 69 Videojuegos 3D
Venta Render Settings de Unity a partir de la cual definimos la niebla, el cielo y la iluminación ambiente.
Por último, para enriquecer nuestra escena, otro sencillo paso que podemos
realizar es la inclusión de luces. Para ello debemos seleccionar, desde el menú
principal, GameObject > Create Other > Directional Light. Tan pronto como
coloquemos la luz direccional veremos su efecto. No importa donde la ubique-
mos, se aplica sobre toda la escena por igual. Lo que sí importa es su dirección.
Con la luz seleccionada y mediante la herramienta de rotación, podremos ha-
cerla rotar para que afecte a la escena como queramos.
Llegados a este punto ya podemos disponer de una escena más o menos atrac-
tiva y podemos comprobar cómo, con muy poco tiempo, es posible disponer
de un escenario 3D más o menos realista. Es hora de navegar a través de él.
4)�Navegación
Podemos hacer dos pruebas rápidas para ver cómo navegar por el escenario
que acabamos de crear: en primera persona y en tercera persona a partir de un
modelo 3D animado. Ambas opciones son accesibles de la siguiente manera.
Sobre el panel de proyecto, hacemos clic con el botón derecho y escogemos la
opción Import Package > Character Controller. Veremos que se añade la car-
peta Character Controllers y en ella existen los objetos llamados 3rd Person
Controller y First Person Controller. Escogemos uno de los dos y lo arrastramos
sobre la escena. Mediante la herramientas de transformación geométrica nos
aseguramos que el objeto se encuentra por encima del terreno y presionamos
© FUOC • PID_00185078 71 Videojuegos 3D
el botón Play. Veremos que mediante el cursor y las teclas de dirección tene-
mos implementado el controlador típico de este tipo de juegos y podremos
movernos por el mundo que acabamos de crear.
Con estos cuatros puntos dados, tan sólo nos falta un último paso para dar por
concluida nuestra primera immersión con un motor de estas características.
Nos estamos refiriendo a la generación de un proyecto ejecutable. Para ello, a
través del menú principal, accedemos a File > Build Settings..., escogemos la
plataforma destino que deseemos y presionamos el botón Build.
© FUOC • PID_00185078 72 Videojuegos 3D
2. Física
Estos dos campos unidos por un mismo problema, al que hay que responder
con la máxima brevedad posible, han hecho posible una ardua investigación
iniciada hace muchos años. Por eso, se han realizado y de hecho continúan
llevándose a cabo publicaciones al respecto y, hoy en día, las soluciones exis-
tentes son, como mínimo, notablemente satisfactorias. Incluso se ha llegado a
adaptar este problema al hardware de la tarjeta gráfica, para que sea realizado
en un coste en tiempo todavía menor.
Comprobar la colisión entre dos objetos es muy costoso, sobre todo cuando
están formados por miles de polígonos. Para minimizar este coste, previamen-
te suele comprobarse la colisión entre sus volúmenes envolventes, de manera
© FUOC • PID_00185078 73 Videojuegos 3D
que, sólo si éstos colisionan, realizamos un test de colisión refinado entre ob-
jetos o respondemos de forma satisfactoria, con el consecuente error de pre-
cisión.
Para que sea útil, un volumen envolvente ha de cumplir las siguientes propie-
dades:
• El cálculo del volumen envolvente debe ser poco costoso, sobre todo si
éste debe recalcularse con cierta regularidad.
De izquierda a derecha, esfera, caja envolvente alineada con ejes, caja envolvente orientada y k-Ddop y envolvente
convexa
Esfera envolvente
Normalmente conocida como AABB (axis aligned bounding box), es una caja
rectangular cuyas caras están orientadas de manera que sus normales son pa-
ralelas a los ejes coordenados. La ventaja de este tipo de volumen es que el
test de colisión es muy rápido, consistiendo en la comparación directa de los
valores de coordenadas.
También conocida como OBB (oriented bounding box), este tipo de volumen
envolvente es representado por una caja rectangular con una orientación ar-
bitraria, aunque suelen utilizarse determinadas direcciones prefijadas.
Al contrario que las AABB, este tipo de volumen envolvente tiene un test de
colisión bastante costoso, basado en el teorema del eje separador. Sin embargo,
su uso viene justificado por su mejor ajuste a los objetos y su rápida actualiza-
ción en las rotaciones. Además, es necesario guardar mucha más información
para representar este volumen, normalmente bajo la forma del centro de la
caja, tres longitudes y una matriz de rotación.
predefinidas y comunes para todos los k-DOP. Las componentes de los vectores
normales están restringidas al conjunto de valores {-1,0,1}, y éstos no están
normalizados.
Ejemplo de k-DOP
Los distintos slabs son ajustados para adaptarse a un objeto, con lo que cambia la forma del volumen envolvente.
Los planos que forman un slab siempre deben tener el mismo ángulo con la vertical que la configuración original.
La actualización de un k-DOP es algo más costosa que un AABB debido a su Otros tipos de volúmenes
mayor número de slabs, pero proporcional a k. El almacenamiento de un k-
Existen muchos otros tipos de
DOP depende también del número de slabs, pero es poco costoso debido, so- volúmenes envolventes que los
bre todo, a que estos slabs están restringidos a ciertas configuraciones. Este aquí expuestos, como conos,
cilindros, elipsoides, etc.
volumen tiene la ventaja adicional de que siempre se puede modificar el tipo
de ajuste a un objeto cambiando el número de slabs que se han de utilizar.
Construcción de un OBBTree
Podemos utilizar distintos volúmenes envolventes, cada uno con mayor nivel
de ajuste o de detalle que el anterior y formar una sucesión de volúmenes
envolventes. La proximidad entre objetos se obtiene de la misma forma para
todos los niveles de este conjunto. Cuando no se puede determinar de forma
exacta si dos objetos colisionan, se pasa al siguiente nivel de detalle.
Rejilla de vóxeles
• La rejilla es muy fina. Si las celdas son muy pequeñas, el número de celdas
que se han de actualizar será alto y, por tanto, costoso en términos de
espacio y tiempo empleados.
Estructura de un octree
En un k-d�tree cada región es dividida en dos partes por un plano alineado con
los ejes. Un k-d tree puede realizar divisiones uniformes del espacio o variables
(existen también octrees con divisiones variables). Las divisiones variables ne-
cesitan mayor almacenamiento para la estructura pero se adaptan mejor a los
objetos.
© FUOC • PID_00185078 80 Videojuegos 3D
BSP trees
Un árbol de partición binaria del espacio es una estructura jerárquica que sub-
divide el espacio en celdas convexas. Cada nodo interno del árbol divide la
región convexa asociada con el nodo en dos regiones, utilizando para ello un
plano con orientación y posición arbitrarias. Es análogo a un k-d tree variable,
sin la restricción de que los planos estén orientados de modo ortogonal con
los ejes.
Lectura complementaria
Para abordar cómo elegir los planos sobre los que dividir el espacio para obtener una
composición óptima, podéis consultar:
B.� Naylor (1993). "Constructing good partitioning trees". Graphics Interface (pág.
181-191). Disponible en http://www.graphicsinterface.org/pre1996/93-Naylor.pdf
Como podemos apreciar en los diferentes proyectos que se han realizado con
Newton, no se trata de una librería para un uso específico en el campo de los
videojuegos. Está pensada para poder simular en tiempo real cualquier pro-
yecto donde tenga lugar la física.
Web
• Web Oficial:
http://www.newtondynamics.com/index.html
• Wiki no oficial:
http://walaber.com/newton_wiki/
© FUOC • PID_00185078 82 Videojuegos 3D
Descripción
ODE es un motor que permite simular físicas en cuerpos rígidos, y está espe-
cialmente indicado para detectar colisiones y fricción entre objetos, simular
vehículos, paisajes y personajes. Es independiente de la plataforma y de la API
gráfica que se use, y está implementado en C++.
Web
• Web Oficial:
http://www.ode.org/
• Presentación:
http://www.ode.org/slides/parc/dynamics.pdf
• Guía de usuario:
© FUOC • PID_00185078 83 Videojuegos 3D
http://www.ode.org/ode-latest-userguide.pdf
• Wiki OgreODE:
http://www.ogre3d.org/wiki/index.php/OgreODE
Está diseñado para la simulación en tiempo real, enfocado más en tener una
buena respuesta en tiempo que en conseguir unos resultados exactos. De todas
maneras, es un parámetro de entrada que podemos modificar a nuestro gusto.
Desarrollo
1)�Estructura�y�conceptos�básicos
De especial interés son los siguientes dos conceptos con los que trabaja ODE:
• ERP, Error Reduction Parameter. Tiene lugar cuando tenemos dos objetos
concatenados y permite definir el nivel de exactitud de contacto entre
éstos. Reduce el número de errores a la hora de calcular la dinámica que
pueda haber entre sendos objetos. Su valor oscila en el rango [0..1] de tal
manera que:
• CFM, Constraint Force Mixing. Este atributo hace que los cuerpos puedan
ser más o menos duros, para la interacción con el mundo y los demás
cuerpos que lo conforman.
• Un CFM=0 hará que el cuerpo sea duro, simulando lo que podría ser una
roca, por ejemplo.
• Un CFM>0 otorgará cierta flexibilidad y nos puede servir para simular por
ejemplo un objeto de plástico.
2)�Creación�del�mundo�dinámico
dWorldID dWorldCreate();
-9
Fijar el valor global de CFM, su valor suele oscilar entre 10 y 1. Por defecto
este es de 10-5.
3)�Creación�de�cuerpos�y�estados
Crear un cuerpo dentro de un mundo que cumplirá las reglas físicas que éste
contenga. Por defecto, sus coordenadas en el espacio serán (0, 0, 0):
Fijar los valores de posición, rotación, velocidad lineal y angular del cuerpo.
Fijar la masa�del�cuerpo.
4)�Creación�y�unión�de�joins
A continuación, describimos las funciones que permiten crear una nueva join
de un tipo determinado. Inicialmente no tendrá ningún efecto en la simula-
ción; para ello será necesario enlazarla a algún cuerpo. La join del contacto será
inicializada con la estructura del atributo dContact.
Para unir las joins a los cuerpos, asociamos una de las conexiones creadas an-
teriormente a dos cuerpos.
5)�Clases�de�geometría
El motor de física ODE acepta las siguientes clases de geometría: Sphere, Box,
Plane, Cylinder, Ray y Triangle Mesh.
También permite que el usuario defina sus propias clases geométricas. Para de-
finir una geometría personalizada, debemos modificar la librería o usar la fun-
ción dCreateGeomClass. En el caso que queramos crear nuestra propia geo-
metría, deberemos definir su comportamiento redefiniendo las funciones de
colisión propias para cada una de ellas.
6)�Loop
Durante el loop, ODE mira si algún objeto está en contacto con otro y calcula el
comportamiento de éstos. Como podemos ver en la siguiente tabla, no todos
los objetos reaccionan al chocar con otro.
Ray No
2 Yes Yes Yes Yes Yes Yes Yes Yes
Plane – No
2 Yes Yes Yes Yes Yes Yes No
2
Trimesh
3 – – – – – – Yes No Yes
Height- – – – – – – – – No
2
field
1. Esta funcionalidad tan sólo existe en versión SVN pendiente de revisar y no está incluida en la versión oficial.
2. No está planificado el hecho de ser implementada, pues no tiene mucho sentido en una simulación física.
3. No está habilitada por defecto, se necesita activar el flag dTRIMESH_ENABLED.
7)�Destrucción�del�mundo
Ejemplos
Proyectos de ejemplos sencillos que utilizan ODE que podemos encontrar junto a la distribución del código fuente.
© FUOC • PID_00185078 91 Videojuegos 3D
3. Programación gráfica 3D
Hasta ahora hemos descrito rutinas sencillas de OpenGL mediante las cuales
éramos capaces de recrear una escena sencilla. Por una parte, hemos definido
objetos 3D a partir de primitivas, utilizando comandos de vértices y colores.
Más tarde, comentamos la posibilidad de utilizar display lists para que el envío
de la información fuera más rápido.
Todo esto lo hemos hecho sin diferenciar y dejar claro, explícitamente, que
existen diferentes maneras de realizar la transferencia de datos a la tarjeta grá-
fica. Ahora que nos encontramos en un apartado de programación gráfica de
mayor complejidad, es el momento adecuado para exponerlo.
Otras estructuras de datos con las que las tarjetas gráficas pueden operar in-
ternamente son:
Este sistema es, por descontado, el más cómodo para el programador pero
también el más ineficiente. Trabaja con vértices y primitivas y se identifica
con el modelo de vista del cliente. Recordemos el aspecto de este modo con
el siguiente código:
glBegin(GL_QUADS);
glVertex3f(-1.0, 1.0, 0.0);
glVertex3f( 1.0, 1.0, 0.0);
glVertex3f( 1.0, -1.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glEnd();
Si este proceso lo realizamos byte a byte, la operación es mucho más lenta que
si lo hacemos utilizando buffers. Pues precisamente radica en este hecho la co-
rroboración de lo que acabamos de decir del modo inmediato. Cada operación
de vértice que tenemos en el ejemplo anterior supone lo que, en sistema de fi-
cheros, sería una llamada al sistema pero, en este caso, es con la tarjeta gráfica.
Las display lists son útiles para definir modelos estáticos. Si éstos sufren mo-
dificaciones, y quisiéramos seguir tratándolos de esta manera, sería necesario
rehacer cada vez la lista. Ante la necesidad de trabajar de manera eficiente con
objetos animados o dinámicos surgen los vertex array.
© FUOC • PID_00185078 93 Videojuegos 3D
Cuantos más valores especificamos por vértice (posición, color, normal, etc.),
más llamadas OpenGL son necesarias y, por tanto, necesitamos más tiempo.
Utilizando VAR pasamos un puntero a OpenGL y decidimos qué vértices pin-
tamos y cómo. A continuación, presentamos las funciones que nos permiten
trabajar con VAR.
Tenemos un array para cada tipo de información que queremos tratar. Para
habilitar y deshabilitar cada uno de éstos contamos con las siguientes fun-
ciones:
void glVertexPointer (GLint sizei, GLenum type, GLsizei stride, const GLvoid *pointer)
glNormalPointer (GLint sizei, GLenum type, GLsizei stride, const GLvoid *pointer)
glColorPointer (GLint sizei, GLenum type, GLsizei stride, const GLvoid *pointer)
glIndexPointer(GLint sizei, GLenum type, GLsizei stride, const GLvoid *pointer)
glTexCoordPointer (GLint sizei, GLenum type, GLsizei stride, const GLvoid *pointer)
glEdgeFlagPointer(GLint sizei, GLenum type, GLsizei stride, const GLvoid *pointer)
Para enviar las primitivas que tenemos en los datos de un array procedemos
de la siguiente manera:
void glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices)
Web
• Vertex�Buffer�Object (VBO):
http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_buffer_object.txt
http://www.spec.org/gpc/opc.static/vbo_whitepaper.html
• Pixel�Buffer�Object (PBO):
http://oss.sgi.com/projects/ogl-sample/registry/EXT/pixel_buffer_object.txt
• Frame�Buffer�Object (FBO):
http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
http://download.nvidia.com/developer/presentations/2005/GDC/OpenGL_Day/
OpenGL_FrameBuffer_Object.pdf
3.2. Iluminación
componente de esa luz que incide sobre todas las partes del objeto, aunque
no estén expuestas a ella directamente.
Cada foco de luz que incluyamos en la escena tiene tres componentes: luz
ambiental, luz difusa y luz especular. La proporción de cada componente de-
termina el tipo de luz.
Ejemplo
Un láser está casi totalmente formado por luz especular. Las componentes difusa y am-
biental son mínimas y se deben a la presencia de polvo en el ambiente. Una bombilla,
sin embargo, tiene una parte grande de luz ambiental y difusa, y una parte mínima de
luz especular.
Cuando se define un foco de luz, no sólo es necesario definir las tres compo-
nentes de la luz, sino también el color de cada componente (RGB).
para las componentes ambiental y difusa de la luz, pero baja para la especular,
se iluminará principalmente de manera ambiental y difusa, por muy especular
que sea la luz con el que lo iluminemos.
El cálculo del color final se realiza multiplicando los valores de cada compo-
nente de la luz por la reflectancia correspondiente a cada una de ellas. En el
caso de las componentes difusa y especular intervienen, además, los ángulos
de incidencia de la luz sobre cada superficie del objeto. Para obtener el valor
final basta con sumar los valores obtenidos para cada color (si se sobrepasa el
valor 1 se toma ese color como 1). Veamos un ejemplo práctico:
Obsérvese que estos valores no son el producto de los anteriores. Se debe a que en estos casos
interviene también el ángulo de incidencia de la luz.
A continuación veremos cómo añadir luz a una escena definida con OpenGL.
Nosotros debemos definir únicamente las luces y los materiales; OpenGL se
encarga de realizar todos los cálculos.
glEnable (GL_LIGHTING);
glDisable (GL_LIGHTING);
© FUOC • PID_00185078 98 Videojuegos 3D
Las luces se encuentran en una posición del espacio y brillan en una dirección.
Para colocar las luces en una posición será necesario definir no sólo las com-
ponentes de la luz, sino también su posición y la dirección en la que emiten
luz. OpenGL permite colocar hasta GL_MAX_LIGHTS luces diferentes en la
escena, cada una con la posición que ocupa y la dirección en la que emite la
luz (la constante GL_MAX_LIGHTS siempre es igual o superior a 8 y depende
de la implementación). Se nombran como GL_LIGHT0, GL_LIGHT1, etc.
La función que utilizaremos para fijar todos los parámetros de la luz es glLight,
que tiene varias versiones, aunque sólo utilizaremos dos:
El parámetro "luz" indica cuál de las luces estamos modificando. Puede valer
GL_LIGHT0, GL_LIGHT1, ..., GL_LIGHT7.
indica el ángulo desde el punto central del cono (marcado por la dirección
de la luz) y el lado del cono. Este ángulo debe valer entre 0.0º y 90.0º. Por
defecto, el ángulo es 180.0º, es decir, si no se indica, la luz se emite en
todas direcciones.
• GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION y
GL_QUADRATIC_ATTENUATION. Se utilizan para añadir atenuación a la
luz. Para dar mayor realismo a las escenas, a las luces se le puede añadir un
factor de atenuación, de manera que la luz es menos intensa conforme los
objetos se alejan del foco de luz, como ocurre en una escena real donde
la presencia de partículas en el aire hace que la luz no llegue a los objetos
más alejados. El factor de atenuación (fa) se define como:
Veamos un ejemplo en el que se coloca una luz en la posición (50, 50, 50), con
componente difusa de color verde y especular de color azul, pero sin compo-
nente ambiental. La luz brilla en dirección al punto (25, 100, 50) y el cono de
luz tiene una amplitud de 30 grados.
// Parámetros de la luz
GLfloat luzDifusa[] = {0.0, 1.0, 0.0, 1.0);
GLfloat luzEspecular[] = {0.0, 0.0, 1.0, 1.0);
GLfloat posicion[] = {50.0, 50.0, 50.0, 1.0};
// Activar iluminación
glEnable (GL_LIGHTING);
Como antes, "parámetro" será un valor real o vector de reales que indican el
valor correspondiente a la característica elegida:
• GL_SHININESS. Sirve para fijar el tamaño del brillo para la luz especular.
Se utiliza la primera versión, y el tercer parámetro es un real que puede
valer entre 0.0 y 128.0. Cuanto mayor es el valor, tanto más concentrado
y brillante es el punto.
glEnable (GL_COLOR_MATERIAL)
Los valores que pueden tomar estos parámetros son casi los mismos que pa-
ra la función glMaterial. El primero especifica a qué cara afecta el tracking
de color (GL_FRONT, GL_BACK o GL_FRONT_AND_BACK) y el segundo in-
dica qué característica va a depender del color (GL_AMBIENT, GL_DIFFUSE,
GL_SPECULAR, GL_EMISSION o GL_AMBIENT_AND_DIFFUSE).
El tracking de color es más rápido que el cambio de material, por lo que es re-
comendable siempre que sea posible, especialmente cuando se producen mu-
chos cambios de color pero no de otras propiedades del material.
glShadeModel(GL_SMOOTH);
3.3. Texturas
3.3.1. Multitexturing
Para poder trabajar con multitexturas en OpenGL son necesarios los siguientes
pasos:
• Declaramos dos nuevos punteros a funciones con "NULL" como valor ini-
cial.
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB=NULL;
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB=NULL;
UINT TextureArray[2];
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)
wglGetProcAddress("glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)
wglGetProcAddress("glMultiTexCoord2fARB");
LoadTexture(TextureArray,"texture/image1.bmp", 0);
LoadTexture(TextureArray,"texture/image2.bmp", 1);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureArray[0]);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureArray[1]);
glBegin(GL_QUADS);
// top left vertex
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex3f(-1, 1, 0);
3.3.2. Mipmapping
Este concepto proviene de las siglas MIP. Esta técnica surge para solventar el MIP
problema de la reducción de la calidad visual en la aplicación de texturas sobre
MIP son las siglas de la expre-
polígonos distantes y por ello más pequeños en pantalla. sión latina multum in parvo, cu-
yo significado es "mucho en
poco espacio".
La solución se basa en contar con muestras de texturas de diferentes tamaños
para utilizar una u otra según convenga. Este versionado de texturas se realiza
reduciendo el área por 0.25 hasta obtener la versión más pequeña posible.
OpenGL nos brinda la posibilidad de trabajar con esta técnica automáticamen- Ved también
te, si, a la hora de cargar la textura, en vez de utilizar el método glTexImage2D,
Podéis ver el método
empleamos el siguiente: glTexImage2D en el módulo
"Videojuegos 2D".
Los parámetros tienen el mismo significado que los de la función que vimos
con anterioridad.
© FUOC • PID_00185078 108 Videojuegos 3D
Filtro isotrópico
• Bilinear sin mipmapping. Elige como valor para un píxel el valor medio del
array 2x2 de texels más cercano al centro del píxel.
• Trilinear. Elige las dos texturas más cercanas, las interpola, y aplica el filtro
GL_LINEAR.
Filtro anisotrópico
Como hacen los filtros bilinear y trilinear, elimina los efectos de aliasing, pero
introduce menos distorsión (blur) y preserva un mayor detalle. Desde el punto
de vista computacional, es muy caro, y recientemente se ha convertido en una
funcionalidad estándar para las tarjetas gráficas.
Cuando se aplica la textura, este filtro escoge varios píxeles alrededor del punto
central, pero de una muestra sesgada conforme a la vista perspectiva. De este
modo, las partes más distantes de la textura contribuirán con menos muestras
y las más cercanas con mayor número.
Las expresiones del tipo AF 2x, AF 4x, AF 8x, etc. hacen referencia a este filtro
y el número indica la diferencia de calidad respecto a la imagen original.
Diferencias entre los filtros isotrópicos (bilinear, trilinear) y anisotrópicos (2x, 4x, 8x)
Utilización del blending para simular la transparencia del agua en el juego World of Warcraft.
Activar blending:
glEnable( GL_BLEND )
Para controlar el color y el valor alpha entre los objetos fuente y destino se
utiliza la siguiente función:
Las diferentes posibilidades que tenemos a escoger, para definir los dos factores
de esta función, se presentan en la siguiente tabla.
Una vez establecidos los factores fuente (A) y destino (B), el color final se cal-
cula como sigue:
// A = 1, B = 0
glBlendFunc (GL_ONE, GL_ZERO);
// A = 1-AlphaSource, B = AlphaSource
glBlendFunc (GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
// A = AlphaSource, B = 1
glBlendFunc (GL_SRC_ALPHA, GL_ONE);
Tres planos correctamente orientados simulando el modelo 3D de un árbol haciendo uso del alpha test.
glEnable ( GL_ALPHA_TEST );
Por ejemplo, para descartar todo aquel píxel que provenga de una compenente
alpha superior a 0.5, procederíamos de la siguiente manera:
La vegetación es abundante en según que juegos, como es el caso de Crysis, donde el alpha test tiene una
función importante.
Blending y alpha test combinados para ofrecer una IGU atractiva en el videojuego Imperium Galactica.
3.5. Navegación 3D
Para poder llevar a cabo esta tarea, es necesario que nos hagamos la siguiente
pregunta: ¿Qué significar navegar por un mundo virtual?
© FUOC • PID_00185078 114 Videojuegos 3D
A primera vista, nos puede parecer un tanto complicado qué responder e in-
cluso por qué pensar que la clave está en hacernos esta pregunta. Vayamos un
poco más allá y propongámonos otras preguntas que, sin duda, nos empeza-
rán a despejar dudas para volver a la primera pregunta.
Exponemos, a continuación, lo que podría ser una clase Camera que imple-
menta un sistema de navegación en primera persona.
class cCamera
{
private:
cVector3D Position;
cVector3D ViewDir;
bool ViewDirChanged;
GLfloat RotatedX, RotatedY, RotatedZ;
int width, height;
float speed;
public:
void Init(int w,int h,float s);
void Look()
void Rotate (cVector3D Angles);
void Update (bool keys[],int mouseX, int mouseY);
void GetPosition(cVector3D *pos);
void GetRotated(cVector3D *rot);
void SetPosition(cVector3D pos);
void MoveForwards(GLfloat distance);
private:
void GetViewDir (void);
void RotateX(GLfloat angle);
void RotateY(GLfloat angle);
void RotateZ(GLfloat angle);
ViewDirChanged = false;
RotatedX = RotatedY = RotatedZ = 0.0;
© FUOC • PID_00185078 116 Videojuegos 3D
//Screen
width = w;
height = h;
//Step length
speed = s;
}
void cCamera::Look()
{
glRotatef(-RotatedX , 1.0, 0.0, 0.0);
glRotatef(-RotatedY , 0.0, 1.0, 0.0);
glRotatef(-RotatedZ , 0.0, 0.0, 1.0);
glTranslatef(-Position.x,-Position.y,-Position.z );
}
if(mouseX!=middleX)
{
angle = (middleX - mouseX) / 50.0f;
RotateY(angle);
}
if(mouseY!=middleY)
{
angle = (middleY - mouseY) / 50.0f;
RotateX(angle);
}
void cCamera::GetViewDir(void)
{
cVector3D Step1, Step2;
//Rotate around Y-axis:
Step1.x = cos( (RotatedY + 90.0) * PIdiv180);
Step1.z = -sin( (RotatedY + 90.0) * PIdiv180);
//Rotate around X-axis:
double cosX = cos (RotatedX * PIdiv180);
Step2.x = Step1.x * cosX;
© FUOC • PID_00185078 118 Videojuegos 3D
Esquema de las transformaciones geométricas necesarias para implementar una cámara en tercera persona.
© FUOC • PID_00185078 120 Videojuegos 3D
void cPlayer::Look3P() {
cVector3D pos, rot;
Camera.GetPosition(&pos);
Camera.GetRotated(&rot);
//Camera configuration (3rd person view)
Camera.SetPosition(cVector3D(pos.x, pos.y+h, pos.z));
Camera.Rotate(cVector3D(-alfa, rot.y, 0));
Camera.MoveForwards(d);
Camera.Look();
//Restore camera to initial values
Camera.SetPosition(pos);
Camera.Rotate(rot);
}
3.6.1. Motivación
Ejemplo de tipo de juego donde un programador podría valerse por sí mismo sin la ayuda de un diseñador 3D.
Por tanto, es evidente que entre estos dos mundos tiene que haber un canal
de comunicación del que ambas partes saldrán beneficiadas. Como muestra la
siguiente ilustración, el trabajo del modelador será la entrada de datos para el
programador que le dará vida, ubicará en el mundo, etc.
Aparte de estos formatos, hay dos líneas existentes que se crearon hace pocos
años que pretenden consolidarse como un estándar: FBX y Collada.
Wavefront OBJ
Wavefront OBJ es uno de los formatos más utilizados. Casi todas las herra- Web
mientas importan y exportan a este formato. Permite trabajar con geometría
Podemos encontrar la sinta-
poligonal, curvas y superficies. xis de este modelo en:
http://www.csit.fsu.edu/~bur-
kardt/data/obj/
Algunas de sus especificaciones son: obj_format.txt
• Comentarios.
# some text
vt float float
• La normal del vértice. Se indexan de la misma manera que en los dos casos
anteriores.
• Una cara poligonal. Los números son índices dentro del vector de las posi-
ciones de los vértices, sus coordenadas de texturas y sus normales respec-
tivamente.
Web
Si queremos precisar de un
cargador de modelos de for-
mato OBJ, una posible solu-
ción es dirigirse a la página
web de Nate Robins, que es-
tá provista de un cargador a
tal efecto, que permite leer,
guardar y manipular OBJ. Es
necesario obtener el fichero
glm.c; allí tenemos la clase
GLMmodel.
http://
www.xmission.com/~na-
te/tutors.html
Milkshape (MS3D)
Milkshape es un editor muy sencillo y simple en prestaciones, pero que destaca Web
por el gran número de plugins exportadores e importadores que integra. La
La página web de Milkshape
versión actual es la 1.8.2 y es del octubre del 2007. es:
http://
chumbalum.swissquake.ch/
index.html
© FUOC • PID_00185078 125 Videojuegos 3D
A continuación mostramos los diferentes formatos para los cuales contiene al-
gún plugin de exportación o importación: Half-Life SMD, Half-Life MDL, Qua-
ke MDL, Quake II MD2, Quake III: Arena MD3, Unreal/UT Engine 3D, Un-
real/UT Engine Skeletal Mesh PSK, Vampire: the Masquerade NOD, Genesis3D
1.0 BDY, Genesis3D 1.0 MOT, Genesis3D 1.0 ACT, Serious Sam MDL, Se-
rious Sam LWO/SCR, Max Payne KF2, Max Payne KFS, Max Payne SKD, The
Sims SKN, Wavefront OBJ, 3D Studio ASC, LightWave LOW, LightWave 6.5x
LOW, AutoCAD DXF, POV-Ray INC, VRML1 WRL, VRML97 WRL, Autodesk
3DS, RAW Triangles, RenderMan RIB, Lithtech ABC v11, v12 (NOLF), Lithium
UnWrapper, Playstation TMD, BioVision Motion Capture BVH, Nebula Script,
Jedi Knight 3DO, GenEdit 3DT y DirectX 8.0.
• Una forma tiene vectores (Vec) y triángulos (Tri). También tiene aquellos
vectores normales que sean necesarios para la iluminación.
La relación que tiene lugar entre estas diferentes entidades queda reflejada en
la siguiente imagen:
Half-Life MDL
• Varios ficheros SMD que contienen las diferentes secuencias de las anima-
ciones.
Para este modelo, existe el Hal-Life Model Viewer, a partir del cual podemos
apreciar todas las características del modelo: animaciones, esqueletos, boun-
ding boxes, etc. A continuación, mostramos una imagen de la aplicación en
marcha.
FBX
Una vez solventado el punto anterior, podemos empezar a dar vida a nuestros
modelos dentro de nuestro videojuego. Para incluirlos será necesario instan-
ciarlos dentro de nuestro código y pintarlos cuando sea necesario en aquel
lugar del mundo donde se encuentren situados.
cModelBFX Model;
Model = new cModelFBX();
Model->Load("personaje.fbx");
if(visible)
{
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(roty, 0, 1, 0)
Model->Render();
glPopMatrix();
}
Model->AdvanceFrame(fps);
if(keys[GLUT_KEY_UP])
{
if(GetState()==STOP)
{
Model->SetSequence(RUN);
SetState(RUN);
}
}
else
© FUOC • PID_00185078 130 Videojuegos 3D
{
Model->SetSequence(STOP);
SetState(STOP);
}
3.7. Selección
• Redefinir el área de visualización, de tal manera que tan sólo una pequeña
área de la pantalla alrededor del ratón sea renderizada.
© FUOC • PID_00185078 132 Videojuegos 3D
• Renderizar la escena, ya sea con todas las primitivas o tan sólo aquellas que
consideremos relevantes para la operación de picking.
• Salir del modo de selección e identificar los objetos que fueron renderizados
en la pequeña área de la pantalla.
Para identificar los objetos renderizados previamente, deberán haber sido eti-
quetados. OpenGL nos da la posibilidad de dar un nombre a primitivas o a
conjuntos de primitivas. Cuando nos encontramos en el modo de selección,
un modo de renderizado especial de OpenGL, los objetos no son renderizados
en el framebuffer. En lugar de ello, las etiquetas de los objetos y la información
de profundidad son almacenadas en un array. Para aquellos objetos que no
hayan sido nombrados, tan sólo se almacena la información de profundidad.
Con todo lo visto, las tareas del programador radican en estos cuatro puntos:
Veamos a continuación las llamadas que OpenGL nos brinda para cada una
de estas etapas.
void glInitNames(void);
void glPopName();
#define BODY 1
#define HEAD 2
...
void RenderInSelectionMode()
{
glInitNames();
glPushName(BODY);
DrawBody();
glPopName();
glPushName(HEAD);
DrawHead();
DrawEyes();
glPopName();
DrawGround();
}
glMatrixMode(GL_PROJECTION);
glPushMatrix();
© FUOC • PID_00185078 134 Videojuegos 3D
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT, viewport);
gluPickMatrix(cursorX, viewport[3]-cursorY, 5, 5, viewport);
gluPerspective(45, ratio, 0.1, 1000);
glMatrixMode(GL_MODELVIEW);
glInitNames();
}
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
• Para procesar los posibles hits que se hayan producido, es necesario volver
al modo de render normal. Esto puede efectuarse mediante la llamada si-
guiente, que nos devuelve el número de hits que han tenido lugar durante
el renderizado en modo selección.
© FUOC • PID_00185078 135 Videojuegos 3D
hits = glRenderMode(GL_RENDER);
if (hits != 0)
{
ProcessHits(hits, select_buf);
}
Llegados a este punto, la tarea que nos queda por realizar es leer e interpretar el
resultado. Para ello, deberemos centrarnos en la estructura del buffer de selec-
ción, en el que tenemos almacenados los diferentes hits que se han producido
en orden secuencial. Esta información será variable en tamaño, ya que pueden
contener diferente número de nombres. El buffer contendrá una serie de hit
records cuya estructura es la que presentamos a continuación:
ptr += names+2;
}
printf ("The closest hit names are ");
ptr = ptrNames;
for (j = 0; j < numberOfNames; j++,ptr++)
{
printf ("%d ", *ptr);
}
printf ("\n");
}
3.8. Escenarios
3.8.1. Terrenos
glBegin( GL_QUADS );
y = Height(X,Y);
z = Y;
glVertex3i(x, y, -z);
glEnd();
index = x + (y * MAP_SIZE);
value = HeightMap[index];
return value;
}
Sin embargo, dado que los triángulos se forman por concatenación de los vér-
tices anteriormente creados, es necesario un tratamiento especial para aquellos
triángulos que se forman en los extremos. Para ello, debemos tratar la lectura
secuencial de los valores del mapa de alturas una vez en una dirección, y a la
siguiente, en el sentido contrario.
glBegin( GL_TRIANGLE_STRIP );
z = Y;
glVertex3i(x, y, -z);
glEnd();
3.8.2. El cielo
Todas ellas son similares, pues escogen una figura geométrica que envolverá Significado de SkyBox
todo el escenario donde tendrá lugar el juego y se mapea una textura sobre él.
La traducción directa de este
término que podemos hacer
Veamos la implementación de un SkyBox. Esta técnica consiste en generar una del inglés, nos pueda dar una
idea bien clara de que consiste
caja, o mejor dicho un cubo, que contendrá en cada una de sus caras la textura esta técnica: "caja" y "cielo".
de lo que podría ser, globalmente, una bóveda celestial. De esta manera, serán
necesarias 6 texturas, una para cada cara del cubo, predispuestas de tal manera
que exista una continuidad entre las caras que serán colindantes, como se
aprecia en los siguientes ejemplos:
© FUOC • PID_00185078 142 Videojuegos 3D
De izquierda a derecha y de arriba a abajo: bottom.bmp, forward.bmp, up.bmp, down.bmp, left.bmp y right.bmp
Aspecto de un SkyBox aplanado. A la izquierda, SkyBox formado a través de las texturas anteriores. A la derecha, otro ejemplo
con otras texturas.
Si juntamos las dos técnicas que acabamos de presentar para escenarios, height-
maps y skybox, el resultado obtenido es el siguiente:
© FUOC • PID_00185078 143 Videojuegos 3D
Los mapas de detalle o detail maps son una técnica que sirve para dotar
de mayor definición y realismo el aspecto de un modelo 3D.
Las texturas que aplicamos sobre los modelos no pueden ser enormes, ya que
puede provocar que el aspecto gráfico del modelo quede poco definido. La
utilización de una textura base sobre el modelo, acompañada de una segunda
que se replica por todo éste, es una buena solución. Comprobemos este hecho
en las siguientes ilustraciones.
Observación
La implementación de esta
técnica mediante OpenGL ca-
bría realizarla utilizando multi-
texturas.
Por otro lado, es necesario abordar cómo realizar el mapeo de la segunda tex-
tura, la textura de detalle, repetida varias veces. Para ello, utilizaremos la ma-
triz de textura a la hora de definir las diferentes matrices con las que contaba
OpenGL: matriz de proyección, matriz del modelo de vista y matriz de textura.
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(detail_level, detail_level, 1.0f);
glMatrixMode(GL_MODELVIEW);
3.8.4. La niebla
Los usos más comunes son la simulación de humos, la neblina, áreas de acción,
etc.
C = f · Ci + (1- f ) · Cf
Donde
Activar niebla:
glEnable(GL_FOG)
Configurar niebla:
glFogf(name, param)
GL_FOG_MODE: GL_LINEAR, GL_EXP (def), GL_EXP2
GL_FOG_DENSITY (por defecto: 1.0)
GL_FOG_START (por defecto: 0.0)
© FUOC • PID_00185078 146 Videojuegos 3D
Veamos tres casos prácticos sobre un mismo escenario y, en cada uno de ellos,
utilizando un factor diferente de niebla:
// a) GL_LINEAR
GLfloat color[4] = {0.7, 0.7, 0.7, 1.0};
glFogfv(GL_FOG_COLOR, color);
glFogf(GL_FOG_START, 0.5);
glFogf(GL_FOG_END, 2.0);
glFogi(GL_FOG_MODE, GL_LINEAR);
// b) GL_EXP
GLfloat color[4] = {0.7, 0.7, 0.7, 1.0};
glFogfv(GL_FOG_COLOR, color);
glFogf(GL_FOG_DENSITY, 1.0);
© FUOC • PID_00185078 147 Videojuegos 3D
glFogi(GL_FOG_MODE, GL_EXP);
// c) GL_EXP2
GLfloat color[4] = {0.7, 0.7, 0.7, 1.0};
glFogfv(GL_FOG_COLOR, color);
glFogf(GL_FOG_DENSITY, 1.0);
glFogi(GL_FOG_MODE, GL_EXP2);
Existe otro tipo de niebla, llamada niebla volumétrica, más comúnmente co-
nocida como volumetric fog. Ésta nos permite ubicar zonas de niebla en el esce-
nario ocupando un volumen en concreto. Es de especial interés cuando quere-
mos colocar niebla que tan sólo tenga presencia en diferentes áreas del terreno
o, por ejemplo, para marcar zonas de interés.
Para trabajar con niebla volumétrica con OpenGL, es necesario el uso de ex-
tensiones, como en el caso de las multitexturas.
Para comprobar que nuestra tarjeta viene provista de esta funcionalidad, de-
beremos tener la extensión llamada "GL_EXT_fog_coord".
© FUOC • PID_00185078 148 Videojuegos 3D
Acto seguido, deberemos decir a OpenGL que llevaremos a cabo niebla basada
en coordenadas de vértices invocando la siguiente instrucción:
Ahora, antes de cada vértice, análogamente a como hacemos con las coorde-
nadas de textura, será necesario explicitar la intensidad de niebla que tendrá
asociado ese vértice mediante la siguiente función:
glFogCoordfEXT ( value )
El valor de la intensidad de esta niebla dependerá del valor que hayamos intro-
ducido previamente mediante los atributos GL_FOG_START y GL_FOG_END
vistos con anterioridad, como si estuviéramos implementando una niebla de
factor lineal.
Así, por ejemplo, ante una inicialización de la niebla volumétrica de este estilo:
glFogCoordfEXT(25.0);
glVertex3f(1.0,1.0,1.0);
3.8.5. El agua
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, id);
glBegin(GL_QUADS);
glTexCoord2f( 0.0f, 1.0 + move);
glVertex3f( 0.0f, water_height, 0.0f);
glTexCoord2f( 0.0f, 0.0f + move);
glVertex3f( 0.0f, water_height, MAP_SIZE);
glTexCoord2f( 1.0f, 0.0f + move);glVertex3f(MAP_SIZE, water_height, MAP_SIZE);
glTexCoord2f( 1.0f, 1.0f + move);glVertex3f(MAP_SIZE, water_height, 0.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
move += 0.00005f;
Este tipo de agua puede ser satisfactorio, si bien es la técnica más sencilla de
todas. Podemos dotar a nuestro mar de un mayor realismo si añadimos la
reflexión de los elementos que tienen lugar en el escenario sobre ella.
La estrategia para implementar este efecto espejo consiste en realizar los si-
guientes pasos:
glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE0, reflect_plane);
glPushMatrix();
glTranslatef(0.0f, water_height*2.0f, 0.0f);
// flip the terrain upside-down (-1 flips it).
glScalef(1.0, -1.0, 1.0);
// render
SkyBox->Render();
Terrain->Render();
glPopMatrix();
glDisable(GL_CLIP_PLANE0);
En los dos casos que hemos tratado, estamos abarcando la visualización que
queremos obtener desde el exterior. ¿Y desde el interior? Si el usuario se intro-
duce dentro del agua, deberemos tratar de otra manera su simulación. Para
ello, podemos hacer uso de una simulación de cáusticas, mediante las cuales,
otorgaremos vida a nuestra agua y el factor de inmersión será mucho mayor.
Para hacer la simulación del agua reflejada en el terreno desde dentro de ella,
nos apoyaremos en una serie de bitmaps que contendrán la animación de las
cáusticas de manera precalculada. Estos bitmaps tendrán el aspecto siguiente.
Mostramos 4 de las 32 imágenes que contiene el juego de pruebas.
© FUOC • PID_00185078 152 Videojuegos 3D
El algoritmo que simulará el interior del agua deberá efectuar los siguientes
pasos:
2) Al igual que hicimos con la textura de detalle, ahora tendremos una tercera
textura que será renderizada repetidas veces.
3) Tan sólo renderizamos la parte del terreno que no sobresale del agua con
cáusticas.
La implementación queda como sigue:
// Animation
caust_delay--;
if(caust_delay == 0)
{
caust_seq++;
caust_seq %= CAUSTIC_NUM;
caust_delay = CAUSTIC_DELAY;
}
3.8.6. Lightmaps
Para poder llevar a cabo la implementación, será necesario trabajar con mul-
titexturas, como ya hemos explicado anteriormente. El aspecto de las texturas
de los lightmaps es como el que se muestra a continuación:
© FUOC • PID_00185078 155 Videojuegos 3D
Los sistemas de partículas ofrecen una solución para modelar objetos amorfos,
dinámicos y fluidos. Son la base de los efectos especiales de los videojuegos,
así como de las películas de hoy en día. Por tanto, pueden constituir un punto
muy a tener en cuenta dentro de un presupuesto.
© FUOC • PID_00185078 156 Videojuegos 3D
• Permite que un objeto sea representado como una nube� de� primitivas
(partículas) que definen su volumen en lugar de por polígonos que defi-
nirían su frontera.
Las partículas pueden ser tanto imágenes 2D como objetos 3D (cubos, esferas,
modelos, etc.). He aquí varios ejemplos:
© FUOC • PID_00185078 157 Videojuegos 3D
Ejemplos de partículas
Generación
Con este método, el número de partículas depende del tamaño del objeto en
pantalla.
Atributos
Inicializamos los atributos que pueda tener una partícula: posición inicial, ve-
locidad inicial, tamaño inicial, color inicial, transparencia inicial, forma, tiem-
po de vida, fuerza, etc.
Extinción
Lógica
La lógica de un sistema de partículas formado por un banco de peces en el videojuego WoW consiste
en describir trayectorias circulares con cierta irregularidad.
Visualización
Para estos casos, no tenemos un solo sistema de partículas, sino una estructura
algo más compleja para que este sistema tenga una continuidad visual desde
el emisor y no seamos capaces de ver, a primera vista, de dónde surge.
Para ello, es necesario crear una base a partir de varios polígonos que, median-
te transparencias dinámicas y transiciones de color, den vida a esa conexión
entre modelo y sistema de partículas. Éste último, además, puede verse descri-
to a partir de una jerarquía de él mismo (varias copias) o coexistir con otros,
ofreciendo un enriquecimiento visual.
Mostremos el ejemplo del turbo de una nave espacial, formado por dos siste-
mas de partículas idénticos y cuatro polígonos rectangulares que desempeña-
rán la función de base.
Base formada por 4 quads con blending (2 por cada) (A y B): sin textura (A) y con textura (B); base y dos sistema de
partículas (1 por cada) (C y D): sin textura (C) y con textura (D).
© FUOC • PID_00185078 161 Videojuegos 3D
• Definir los puntos de interés del modelo. Serán nuestros emisores, puntos
virtuales relativos a nuestro personaje, desde donde nacerá el sistema de
partículas. Normalmente se define mediante un valor concreto y un cier-
to valor aleatorio dentro de un intervalo. Por ejemplo, para el fuego de
la espalda podríamos tener el punto medio o central de su espalda y su
© FUOC • PID_00185078 162 Videojuegos 3D
variación en el eje Y positiva y negativa así como en el eje X para que las
partículas no se distribuyan en línea recta.
Modelo 3D Ragnaros del juego World of Wracraft emitiendo sistemas de partículas para dotarlo de una mayor dinamismo y
realismo.
Otra muestra significativa puede ser la siguiente imagen que recoge el aspecto
de un arma legendaria del juego Lord of the Rings On-line. El sistema de par-
tículas hace que el arma destaque y la haga más interesante.
Modelo 3D de un arma legendaria con un sistema de partículas asociado del juego Lord of the Rings On-line.
3.10. LOD's
La idea de los niveles de detalle o LOD (levels of detail) surge cuando nos en-
contramos en un contexto en el cual debemos trabajar con conjuntos de geo-
metría muy complejos y éstos deben ser renderizados en tiempo real. Es decir,
manteniendo un buen frame rate (mínimo o superior a 30 imágenes por se-
gundo). Este es un contexto que es fácil encontrarse en el caso de los video-
juegos y otras aplicaciones gráficas interactivas.
© FUOC • PID_00185078 164 Videojuegos 3D
Conviene formularse la siguiente pregunta: si algo está lejos, ¿por qué malgas-
tar número de polígonos en ello? La solución que se nos presenta nos lleva a
una simplificación de la geometría poligonal para objetos pequeños, distantes
o menos importantes. Ésta es precisamente la técnica de los niveles de detalle;
podemos encontrarla referenciada con otras nomenclaturas, como pueden ser:
• Polygonal simplification
• Geometric simplification
• Mesh reduction
• Decimation
• Multiresolution modeling
La reducción del número de polígonos puede llegar a ser muy considerable mediante diferentes LOD de un modelo.
3.10.1. Técnicas
Impostors–billboard
Discrete LOD
Al grupo Discrete LOD pertenecen los niveles de detalles estáticos. Esta técnica
consiste en almacenar varias versiones (típicamente tres) diferentes del mode-
lo, las llamadas baja, media y alta (low, medium, high) y escoger cuál enviar a
pintar según un criterio como, por ejemplo, la distancia.
• No depende del tamaño del modelo y, por ello, si nos encontramos ante
situaciones de modelos grandes o pequeños, la solución puede no adap-
tarse a necesidades específicas.
• Surge el popping effect, que es el cambio brusco que puede tener lugar justo
en el momento que cambiamos de visualización entre niveles de detalle
diferentes.
Es la técnica más costosa, dado que los cálculos se realizan en tiempo de ejecu-
ción; sin embargo, existen publicaciones que ofrecen buenos resultados, como
el paper "Progressive Meshes", de Hughe Poppe, basado en las operaciones de
vertex split (división de vértices) y edge collapse (unión de aristas) que podemos
apreciar en la siguiente ilustración:
© FUOC • PID_00185078 166 Videojuegos 3D
Las operaciones vertex split y edge collapse asociadas a la técnica de los niveles de detalle continuos.
3.10.2. Criterios
Distancia
La distancia puede ser un buen criterio para definir el nivel de detalle necesario para visualizar un modelo.
© FUOC • PID_00185078 167 Videojuegos 3D
Tamaño
Condiciones medioambientales
En escenarios donde las condiciones de ambiente inviten a ello, no es necesario un gran nivel de detalle, pues será
imperceptible para el usuario.
Frame-rate
Los terrenos son uno de los ámbitos de utilización de niveles de detalles más
necesitados. Hacen uso de terrenos: simuladores de vuelo, videojuegos basa-
dos en outdoors, geographic information systems (GIS), aplicaciones de turismo
virtual, etc.
Regular grids
Las regular grids son estructuras que contienen un array uniforme de alturas.
Son simples de almacenar y manipular y suelen estar codificadas en formatos
raster (DEM, GeoTIFF, RAW). Las principales características que podemos citar
de este modelo son:
Bintree y quadtree
Geomipmapping
Aparición de agujeros en las zonas donde encontramos T-junctions, como en los casos A y B.
Para solucionar estos casos, el algoritmo del geomipmapping elimina estos vér-
tices. La estructura resultante queda como sigue:
Para determinar el LOD de cada patch, cada vez que el usuario se mueva por
el terreno, el proceso de actualización deberá:
3.11. Visibilidad
3.11.2. Culling
• Frustum culling: eliminación de los objetos que no son visibles por nuestro
frustum, o cono de visión, definido por la cámara.
Frustum culling
Esta técnica consiste en seleccionar aquellos objetos que podamos ver a partir
de nuestra pirámide de visión (frustrum). Para ello, será necesario construir los
6 planos que conforman nuestro frustum y hacer test sencillos in/out. Para los
objetos de la escena, son suficientes las estructuras bounding spheres o bounding
cubes.
void ExtractFrustum()
{
float p[16]; // Projection Matrix
float m[16]; // Modelview Matrix
float c[16]; // Clipping
float t;
// RIGHT plane
f[0][0] = c[3] - c[0];
f[0][1] = c[7] - c[4];
f[0][2] = c[11] - c[8];
f[0][3] = c[15] - c[12];
// LEFT plane
f[1][0] = c[3] + c[0];
f[1][1] = c[7] + c[4];
f[1][2] = c[11] + c[8];
f[1][3] = c[15] + c[12];
// BOTTOM plane
f[2][0] = c[3] + c[1];
f[2][1] = c[7] + c[5];
f[2][2] = c[11] + c[9];
f[2][3] = c[15] + c[13];
// TOP plane
f[3][0] = c[3] - c[1];
f[3][1] = c[7] - c[5];
f[3][2] = c[11] - c[9];
f[3][3] = c[15] - c[13];
// FAR plane
f[4][0] = c[3] - c[2];
f[4][1] = c[7] - c[6];
f[4][2] = c[11] - c[10];
© FUOC • PID_00185078 177 Videojuegos 3D
// NEAR plane
f[5][0] = c[3] + c[2];
f[5][1] = c[7] + c[6];
f[5][2] = c[11] + c[10];
f[5][3] = c[15] + c[14];
for(int i=0;i<6;i++) {
normalize(f[i]);
}
}
Occlusion Culling
Con esta finalidad, se han creado algoritmos de occlusion culling en dos direc-
ciones:
Lecturas complementarias
Sobre los algoritmos que trabajan en espacio-imagen, podéis consultar: H.� Zhang;� D.
Manocha;�T.�Hudson;�K.�Hoff�III (1997). "Visibility culling using hierarchical occlusion
© FUOC • PID_00185078 178 Videojuegos 3D
maps". En: T. Whitted (ed.). Computer Graphics (SIGGRAPH '97 Proceedings) (vol. 24, pág.
77-88).
Con este código en mente, y sin entrar en más detalle, mostremos las cuestio-
nes que se plantean:
Portal culling
Esta técnica divide el mundo en celdas (por ejemplo, habitaciones) y éstas son
conectadas mediante portales (por ejemplo, ventanas, puertas). Un grafo de
adyacencias describe las conexiones.
De color rojo tenemos los objetos que no serán pintados y las habitaciones
que no consultaremos. En color gris, tenemos los portales sobre los cuales nos
movemos con mayor intensidad según el índice de recursividad. Por último,
de color negro, aparecen los objetos que serán enviados a renderizar.
3.12. Shaders
• Otros usos, fuera del contexto gráfico, como puede ser la detección de
colisiones (filosofía GPGPU, general purpose gaphics process unit).
void main()
{
lightDir=normalize(vec3(gl_LightSource[0].position));
normal = gl_NormalMatrix * gl_Normal;
gl_Position = ftransform();
}
void main()
{
float intensity;
vec4 color;
vec3 n = normalize(normal);
intensity = dot(lightDir,n);
if (intensity > 0.95)
color = vec4(1.0,0.5,0.5,1.0);
else if (intensity > 0.5)
color = vec4(0.6,0.3,0.3,1.0);
else if (intensity > 0.25)
color = vec4(0.4,0.2,0.2,1.0);
else
color = vec4(0.2,0.1,0.1,1.0);
gl_FragColor = color;
}
Parallax mapping es una técnica que, además de un normal map, cuenta con un
mapa de alturas. A partir de éste podemos modificar las coordinadas de textura
y simular, por ejemplo, grandes concavidades (inexistentes geométricamente
hablando).
3.12.4. Glow
Este efecto permite simular el efecto glow. En este caso, la tarea del shader ra-
dica en realizar un motion blur en dirección horizontal y vertical en aquellas
zonas donde interese. Veamos aquí una escena donde predomina el uso de
esta técnica.
3.12.5. HDR
HDR son las siglas de High Dynamic Range y también podemos encontrarlo
mediante la referencia HDRR (HDR Rendering). Es una técnica de iluminación
que consiste en ampliar el rango de iluminación antiguamente restringido
entre los valores 0 (negro) y 1 (blanco). Con este efecto podemos simular el
efecto de la sobre-exposición y hacer que aquellas zonas más oscuras sean más
negras y aquellas que son claras iluminarlas aún más.
Con esta técnica es posible obtener resultados espectaculares tal y como de-
muestran las siguientes imágenes.
Diferencias del renderizado de una escena del juego Half-Life 2 sin HDR (izquierda) y con HDR (derecha).
© FUOC • PID_00185078 187 Videojuegos 3D
Diferencias del renderizado de una escena del juego Half-Life 2 sin HDR (arriba) y con HDR (abajo).
© FUOC • PID_00185078 189 Videojuegos 3D
Bibliografía
Coorg, S.; Teller, S. (1996). "A spatially and temporally coherent object space visibility
algorithm". Technical Report TM (núm. 546).
Luebke, D.; Georges, C. (1995). "Portals and mirrors: Simple, fast evaluation of potentially
visible sets". En: Proceedings of the 1995 symposium on Interactive 3D Graphics (pág. 105).
Naylor, B. (1993). "Constructing good partitioning tres". Graphics Interface (pág. 181-191).
Disponible en: http://www.graphicsinterface.org/pre1996/93-Naylor.pdf
Richard, S.; Wright, Jr.; Lipchak, Benjamin (2005). OpenGL SuperBible. Anaya Multi-
media
Watt, A.; Policarpo, F. (2001). 3D Games: Real-Time Rendering and Software Technology (2
vol.). Boston, MA: Addison Wesley.
Wright R. S.; Lipchak, Benjamin (2005). OpenGL SuperBible. Madrid: Anaya Multimedia.
Zhang, H.; Manocha, D.; Hudson, T.; Hoff III, K. (1997, agosto). "Visibility culling
using hierarchical occlusion maps". En: T. Whitted (ed.). Computer Graphics (SIGGRAPH '97
Proceedings) (vol. 24, pág. 77-88).