FANDOM

1.057 Páginas

El motor de renderizado de Doom (Doom rendering engine) es el núcleo del motor del juego que sostiene a Doom y sus secuelas y que fue utilizado como base para alimentar otros juegos de id Software, notablemente Heretic, Hexen y Strife. Fue creado por John Carmack, con funciones auxiliares escritas por John Romero, Dave Taylor y Paul Radek 1 . Originalmente desarrollado en computadoras NeXT, fue portado a DOS para el lanzamiento inicial de Doom y posteriormente portado a otros sistemas operativos y consolas de juegos. El código fuente de la versión para Linux de los juegos Doom fue lanzado al público en 1997 bajo una licencia que concede derechos al uso no comercial y re-lanzado bajo la Licencia Pública General GNU en 1999. Como resultado, decenas de usuarios-desarrolladores han creado source ports, que permiten a Doom funcionar en sistemas operativos no compatibles con anterioridad, a menudo corregir errores (incluyendo los límites estáticos que se indican a continuación), y a veces ampliar radicalmente la funcionalidad del motor con nuevas características.

No es un verdadero motor "3D" ya que no es posible mirar hacia arriba y abajo correctamente, y un sector no puede colocarse por encima o por debajo de otro, pero sin embargo es un sistema bastante elegante que permite la representación de un pseudo-3D. Cuando se publicó por primera vez, Doom fue revolucionario y casi único en su capacidad de proporcionar un entorno 3D de textura rápida mapeada en el hardware moderno de esa época (los últimos modelos 386 y los primeros 486), sin necesidad de contar con hardware de gráficos en 3D especializado, funcionando a frecuencias de reloj de alrededor 25-33MHz .

A pesar de la simplicidad y la velocidad de renderizado, tiene sus limitaciones. El renderizado de la base depende de 16.16 números de puntos fijos (números enteros entre -32.768 y 32.767 con fracciones limitadas a múltiplos de 1 / 65.536). Debido a estas limitaciones, la precisión en unidades pequeñas se pierde como la limitada precisión dificulta la precisión especialmente cuando se multiplica y divide. Las altas resoluciones causan más problemas  gráficos, sobre todo por encima del rango de resolución de 5.000 píxeles, algunos fallos aparecen como campo de visión distorsionados, junto con pisos y techos que se extienden hacia el horizonte.

Estructura de nivel

La siguiente es sólo una descripción general de la estructura básica de un nivel en el motor de Doom. La mayor parte de las estructuras de datos que figuran aquí tienen propiedades adicionales, tales como las compensaciones de textura, o banderas para restringir los movimientos del jugador o los monstruos.

Mirados desde arriba hacia abajo, todos los niveles son en realidad de dos dimensiones, lo que demuestra una de las limitaciones principales del motor: no es posible tener "salas por encima de las salas".

Esta limitación, sin embargo, tiene un lado positivo: se puede visualizar fácilmente un modo mapa que representa las paredes y la posición del jugador, como se muestra esquemáticamente en la primera imagen de la derecha (en contraste, el modo mapa de Descent contemporáneo del Doom, que utiliza un motor 3D sin restricciones era extremadamente difícil de interpretar).

Diagrama esquemático que muestra cómo Doom representa internamente los niveles.

Doom formato mapa

Vista del mapa en el editor

Elementos mapeo

Vista en el juego

Objetos básicos

  • La unidad base es el vértice, que significa un único punto 2D. En el diagrama de la derecha, cada pequeño cuadrado verde es un vértice.
  • Los vértices (o "vertexes", como se les conoce internamente) se unen entonces para formar líneas, conocidas como linedefs.
  • Cada linedef puede tener uno o dos lados, que son conocidos como sidedefs.
  • Los sidedefs se agrupan para formar polígonos; estos son los llamados sectores.

Sectores

Los sectores representan determinadas áreas 2D de un nivel. Cada sector tiene una serie de propiedades requeridas: una altura del piso, una altura del techo, un nivel de luz, una textura del suelo y una textura del techo.

Para poner dos niveles de luz diferentes en la misma habitación, por ejemplo, debe crearse un nuevo sector para la segunda zona. Un sector debe estar completamente rodeado por sidedefs; por lo tanto, las linedefs unilaterales representan paredes sólidas, mientras que las linedefs de dos caras representan líneas limítrofes entre sectores.

Sidedefs

Las sidedefs se utilizan para almacenar las texturas de la pared, que son completamente independientes de las texturas del piso y de techo. Cada sidedef puede tener hasta tres texturas; llamadas media (o "normal"), superior y baja. En linedefs de un solo lado, sólo la textura media se utiliza para la textura de la pared. En linedefs de dos caras, la situación es más compleja. Las texturas superiores e inferiores se utilizan para llenar los vacíos en los sectores adyacentes que tienen diferentes alturas de piso y techo: las texturas inferiores se utilizan para las escaleras, por ejemplo.

La mayoría de las sidedefs no tendrán una textura media, aunque algunos lo hacen; esto se utiliza para hacer texturas que "cuelgan" en el aire. Por ejemplo, cuando una barra de textura transparente se usa en la conformación de una jaula, una textura media ha sido utilizada en un linedef de dos caras.

Una textura superior o inferior en un linedef de un solo lado, o en un linedef de dos caras cuyos sectores contiguos  siempre tienen las mismas alturas de piso y techo, es muy inusual e incluso puede causar problemas de representación si no es manejada con cuidado por el diseñador de nivel.

Cosas (Things)

Por último, hay una lista de objetos esencialmente no-arquitectónicos en el nivel llamados cosas. Estas se utilizan para colocar jugadores, monstruos, potenciadores, objetos decorativos, obstáculos, etc. Cada cosa tiene un par  de coordenadas 2D, como con los vértices. Las cosas se colocan automáticamente en el piso o el techo, según corresponda a su tipo general.

Construyendo nodos

El motor de Doom hace uso de un sistema conocido como partición binaria del espacio (BSP). Debe utilizarse una herramienta conocida como Constructor de nodos, para generar los datos BSP para un nivel antes de que se puede jugar en él. Dependiendo del tamaño y la complejidad del nivel, este proceso puede durar bastante tiempo. BSP divide el nivel en un árbol binario: cada ubicación en el árbol es un nodo que representa un área particular del nivel (con el nodo raíz que representa a todo el nivel). En cada rama del árbol hay una línea divisoria que separa la zona del nodo en dos subnodos. Al mismo tiempo, la línea divisoria divide linedefs en segmentos llamados SEGs.

En las hojas del árbol hay polígonos convexos, donde no es útil dividir el nivel llegue más lejos. Estos polígonos convexos se conocen como subsectores (o SSECTORS) y están unidos a un sector en particular. Cada subsector tiene una lista de segs asociados.

SubSectores E1M1

Subsectores en E1M1: Hangar, mostrando colores codificados.

El sistema BSP es realmente una manera muy inteligente de clasificación de los subsectores en el orden correcto para su representación. El algoritmo es bastante simple:

  1. Comience en el nodo raíz.
  2. Dibuje los nodos secundarios de este nodo de forma recursiva. El nodo hijo cercano a la cámara se dibuja primero. Esto se puede encontrar buscando en qué lado de la línea divisoria de un nodo dado está encendida la cámara.
  3. Cuando se alcanza un subsector, dibujarlo.

Para una columna dada de píxeles, el proceso se termina cuando se llena toda la columna (es decir, no hay más espacios a la izquierda). Este orden asegura que durante el juego real, no se pierde tiempo dibujando objetos que no son visibles; como resultado, los mapas pueden llegar a ser muy grandes sin penalización alguna de la velocidad.

Cuando un nivel se revisa usando un editor, los datos BSP deben ser solamente actualizados si se ha hecho un cambio estructural (el nivel todavía se puede utilizar sin la reconstrucción de sus nodos, pero sólo los cambios no estructurales será tenidos en cuenta por el motor) . En este contexto, los cambios estructurales incluyen:

  • Añadir, eliminar o mover vértices.
  • Adición o eliminación de linedefs.
  • Adición o eliminación de sidedefs.
  • Adición o eliminación de sectores, o el cambio de los sectores con los que sidedefs dados están asociados.

Las siguientes no se consideran cambios estructurales:

  • Cualquier cambio que implica únicamente cosas.
  • Adición o eliminación de texturas de pared, o la sustitución de una textura con otra.
  • Cambio de las acciones de linedefs o sectores, o etiquetas de reordenación.
  • Cambio de alturas de suelo o techo.

Representación (rendering)

Dibujo de paredes

El motor de Doom representa las paredes a medida que atraviesa el árbol BSP, dibujando subsectores por orden de distancia de la cámara (es decir, los segs más cercanos se dibujan primero).

A medida que se dibujan los segs, se almacenan en una lista de enlaces. Esto se utiliza para recortar otros segs prestados más adelante, reduciendo el sobredibujo. La lista también se utiliza posteriormente para recortar los bordes de los sprites.

Para reducir la carga en el rendimiento del motor, algo que se había vuelto esencial en los años 90 cuando el juego fue desarrollado y publicado, hay un límite estático a cuántos segs puede volverse a la vez, que es de 256. El excedente de segs simplemente no son dibujados, dejando huecos visibles en las paredes y la generando el error conocido como Efecto sala de espejos. Afortunadamente, debido al orden en el que se dibujan los segs, las lagunas están fuera en la distancia, donde se notan menos.

Dibujo de pisos y techos

El sistema para dibujo de pisos y techos ( "planos") es menos elegante que el utilizado para las paredes. Los pisos se dibujan con un algoritmo de relleno por difusión. Debido a esto, a veces es posible (si se ha utilizado un constructor de nodos con errores) ver "agujeros" en los que la textura del piso o del techo sangra hasta el borde de la pantalla. Esta es también la razón por la que, si el jugador se desplaza fuera del nivel adecuado utilizando el código de trucos sin recorte, los pisos y techos aparecerá estirarse hacia fuera de la habitación más cercana (s) a través del espacio vacío.

Los pisos y techos se dibujan como "visplanes", que representan tramos horizontales de textura, dan un piso o techo a una altura determinada, el nivel de luz y textura (si dos sectores adyacentes tienen el mismo piso exacto, estos pueden ser fusionadas en un solo visplane) . Cada posición X en el visplane tiene una línea vertical particular de textura que ha de ser elaborada.

Debido a la obligación de elaborar una sola línea vertical en cada posición X, a veces es necesario dividir un visplane en múltiples visplanes. Por ejemplo, considerar la búsqueda de un piso con dos cuadrados concéntricos. La plaza interior dividirá verticalmente el suelo circundante, y dentro del rango horizontal de la plaza interior, se necesitan dos visplanes para el suelo circundante.

Para limitar la carga del sistema con los diseños de nivel, los programadores del motor añaden un límite estático de 128 visplanes simultáneas. Esto luego frustró a diseñadores de niveles de comunidad de fans que intentaron niveles grandes o muy detallados durante un tiempo hasta que fue liberado el código fuente, lo que permitió elevar modificaciones o eliminar el límite. Si se supera el límite, el juego inmediatamente sale a DOS con el mensaje "No más visplanes (No more visplanes)". Una forma fácil de invocar el límite visplane es un gran patrón de piso como tablero de ajedrez, que crea un número considerable de visplanes.

A media que se renderizan los segs, también se añaden visplanes, que va desde los bordes de las segs hacia los bordes verticales de la pantalla. Estos se extienden hasta alcanzar otros visplanes existentes. Este sistema depende de las segs que van siendo representados en orden por el motor; es necesario llamar a visplanes cercanos primero, para que puedan ser "cortados" por los más distantes. Si se desenganchan, el piso o el techo van a "sangrar" hacia el borde de la pantalla, como se describió anteriormente. Con el tiempo, los visplanes forman un "mapa" de las áreas particulares de la pantalla en el que dibujar texturas particulares.

Mientras que los visplanes están construidos esencialmente de "tiras" verticales, la representación real de bajo nivel se realiza en la forma de "vanos" horizontales de textura. Después de que todos los visplanes se han construido, se convierten en vanos que luego son prestados a la pantalla. Esto parece ser una solución de compromiso: el tiempo de cálculo se guarda mediante la construcción de visplanes como tiras verticales, pero con el fin de disminuir el número de cálculos realizados en perspectiva, es más fácil para atraerlos como tiras horizontales. Así como una sola tira vertical de pared está a una distancia constante de la cámara, una sola tira horizontal de un piso o el techo está a una distancia constante, y por lo tanto algunos cálculos de renderizado pueden hacerse una vez y se utilizan para un tramo entero.

Dibujo de cosas (sprites)

Cada sector en el nivel tiene enlazada una lista de cosas almacenadas en ese sector. Cuando se dibuja cada sector, los sprites de los objetos se colocan en una lista de sprites que se elaborará. Se ignoran los sprites fuera del campo de visión.

Los bordes de los sprites se recortan marcando la lista de segs previamente elaborada. Los sprites del motor de Doom se almacenan en el mismo formato basado en columnas como las texturas de pared, que a su vez es útil para el renderizador: las mismas funciones se pueden usar para dibujar paredes y sprites por igual.

Mientras los subsectores están garantizados para estar en orden, los sprites dentro de ellos no lo están. El motor almacena una lista de sprites que se puede dibujar ("vissprites") y ordena esta lista antes de renderizar cualquier Cosa.

Los sprites distantes se dibujan antes que los cercanos; esto causa algun sobredibujo, pero por lo general es insignificante. El número de sprites que se permite dibujar a la vez se limita a un máximo de 128. Si hay más de 128 sprites en vista a la vez, las cantidades en exceso simplemente no serán dibujados, lo que provoca el efecto de las cosas que pasan dentro y fuera de la existencia, con los mayores número de sprites desapareciendo si hay  cantidades mayores de cosas presentes.

Hay una última cuestión que involucra texturas medias en linedefs de dos caras, partes que pueden ser transparente (y por lo tanto no pueden recortar sprites como otra pared lo haría). Tales texturas se enumeran y se dibujan con los sprites al final del proceso de renderización, en lugar de con el resto de las paredes. Este esquema de dibujo alternativo explica por qué el efecto Medusa se produce sólo con las texturas medias en linedefs a dos caras.

Notas

1.   Otro programador, Michael Abrash, aparece en la pantalla de créditos de The Ultimate Doom aunque él afirma que se unió a id Software para trabajar en Quake a principios de marzo de 1995. Sin embargo, el libro Masters of Doom de David Kushner hace notar (pág. 189) que los programadores de id leían con atención las obras publicadas por Abrash sobre la programación gráfica mientras desarrollaban sus juegos anteriores.

¡Interferencia de bloqueo de anuncios detectada!


Wikia es un sitio libre de uso que hace dinero de la publicidad. Contamos con una experiencia modificada para los visitantes que utilizan el bloqueo de anuncios

Wikia no es accesible si se han hecho aún más modificaciones. Si se quita el bloqueador de anuncios personalizado, la página cargará como se esperaba.

También en FANDOM

Wiki al azar