Mapping y Hammer

Crear texturas custom para GMod: VTF y VMT explicados

Texturas custom para Hammer y GMod: guarda la imagen como VTF, escribe el VMT, coloca bien los archivos en materials y corrige los errores típicos.

Una imagen tuya se convierte en textura cuando la guardas como VTF y le añades un pequeño archivo de texto .vmt que describe el material. Los dos archivos van en una subcarpeta de garrysmod/materials/. Hammer y el juego trabajan siempre con el material, el VMT, que apunta al VTF. Con el tamaño de imagen, el shader y la ruta correctos, la textura aparece en el Texture Browser y en el juego.

Dos archivos: VTF y VMT

El VTF (Valve Texture Format) contiene los datos de la imagen: los píxeles y los mipmaps, versiones más pequeñas para usar a distancia. El VMT es un script de texto. Define qué shader dibuja la superficie, qué texturas usa y cómo se comporta físicamente la superficie, por ejemplo su sonido de pisadas.

El motor no accede directamente a un VTF, solo a través de un material. Por eso en Hammer eliges materiales, no archivos de imagen. Varios VMT pueden usar el mismo VTF, por ejemplo uno para brushes y otro para modelos.

Preparar la imagen: tamaño y formato

El ancho y el alto tienen que ser cada uno una potencia de dos, por ejemplo 256, 512, 1024 o 2048 píxeles, normalmente 4096 como máximo. La imagen no tiene que ser cuadrada, 512 × 256 funciona. Guarda la imagen de origen sin pérdida, por ejemplo como TGA o PNG. Un JPG trae consigo artefactos que se vuelven a comprimir durante la conversión.

Al guardar como VTF eliges un formato de imagen. Cuatro de ellos cubren casi todo:

FormatoBits por píxelCanal alfaAdecuado para
DXT141 bit como máximotexturas opacas normales
DXT58sítexturas con transparencia
BGR88824nodegradados muy finos, normal maps
BGRA888832sídegradados finos con canal alfa

Los formatos DXT comprimen con pérdida, los otros dos no. El precio es el tamaño: sin mipmaps, una textura de 1024 × 1024 ocupa medio megabyte como DXT1 y tres como BGR888. Así que usa DXT1 o DXT5 por defecto y los formatos sin comprimir solo donde la compresión moleste a la vista. Para las texturas del mundo 3D, haz que se generen mipmaps.

Convertir la imagen a VTF

Hay dos vías habituales:

  • VTFEdit y sus sucesores. VTFEdit es un programa gráfico. Cargas la imagen con File > Import y eliges el formato en el diálogo de importación, en «Normal format» y «Alpha format». Según la Valve Developer Community, el original ya no se mantiene. La comunidad lo continúa como VTFEdit Reloaded y VTFEdit++.
  • vtex. El programa de línea de comandos de Valve viene con GMod en la carpeta bin. Convierte archivos TGA y los espera en garrysmod/materialsrc/. El VTF acaba en la subcarpeta del mismo nombre dentro de materials/. Ajustes como nocompress 1 van en un archivo de texto con el mismo nombre que la imagen.

Al guardar, fíjate en la versión del VTF: la 7.4 o una anterior es la opción segura. La versión 7.5 viene de una rama más reciente del motor, y para GMod la Valve Developer Community solo dice que la compatibilidad es posible.

Escribir el VMT

Un VMT se puede crear con cualquier editor de texto. El material de pared más pequeño que tiene sentido es este:

LightmappedGeneric
{
	$basetexture "myname/mymap/wall_concrete01"
	$surfaceprop concrete
	%keywords "mymap"
}

La primera línea indica el shader, y cada línea entre las llaves contiene un parámetro y su valor. Las comillas solo hacen falta cuando un valor contiene espacios. Estos son los parámetros que necesitas primero:

  • $basetexture: la ruta al VTF, relativa a materials/ y sin extensión de archivo.
  • $surfaceprop: el tipo de superficie, por ejemplo concrete, metal, wood, dirt, glass o tile. Determina los sonidos de pisadas, los efectos de impacto de bala y otras propiedades físicas.
  • $bumpmap: un normal map que da relieve a la superficie bajo la luz. Si lo añades más tarde, vuelve a compilar el mapa, porque esas superficies reciben lightmaps adicionales.
  • $envmap env_cubemap: reflejos del env_cubemap más cercano. Solo aparecen una vez generados los cubemaps. Más en el artículo sobre arreglar los reflejos de los cubemaps.
  • $translucent 1 o $alphatest 1: los dos usan el canal alfa de la textura. $translucent permite transiciones suaves como en el cristal, pero puede producir errores de ordenación entre superficies que se solapan. $alphatest solo distingue entre visible e invisible, es mucho más rápido y encaja con vallas y rejas.
  • %keywords: palabras clave separadas por comas para el campo «Keywords» del Texture Browser de Hammer.

Carpetas y rutas

garrysmod/materials/myname/mymap/wall_concrete01.vmt
garrysmod/materials/myname/mymap/wall_concrete01.vtf
garrysmod/materials/myname/mymap/wall_concrete01_normal.vtf

El nombre del material en Hammer es la ruta del VMT a partir de materials/, aquí myname/mymap/wall_concrete01. Dónde está el VTF y cómo se llama da igual técnicamente, siempre que $basetexture apunte ahí. Que los nombres coincidan es solo la convención habitual.

Dos reglas te ahorran problemas:

  1. Ponlo todo en una subcarpeta propia. Así no sobrescribes los materiales de nadie y vuelves a encontrar tus archivos al empaquetar.
  2. Escribe los nombres de carpetas y archivos en minúsculas, sin espacios ni caracteres especiales. Los servidores Linux distinguen entre mayúsculas y minúsculas.

GMod también carga todo lo que hay en garrysmod/addons/<name>/materials/. Si un material nuevo no aparece en el Texture Browser, en la práctica ayuda reiniciar Hammer.

Brushes y modelos: el shader correcto

LightmappedGeneric está pensado para brushes y displacements. Estas superficies se iluminan con los lightmaps que calcula VRAD. VertexLitGeneric es el shader para modelos, cuya luz se determina por vértice.

Si los confundes, la iluminación sale mal. Según la Valve Developer Community, un material VertexLitGeneric en un brush se muestra como una superficie completamente negra, que parpadea o que cambia de brillo según el ángulo de visión. Por eso los materiales de la carpeta models/ no deben ir en brushes. A la inversa, los modelos no pueden usar LightmappedGeneric. Para tener la misma imagen en un brush y en un modelo, escribe dos VMT que apunten al mismo VTF. Por lo general solo cambia la primera línea.

Errores típicos y su causa

SíntomaCausaSolución
Cuadros rosas y negrosFalta el VMT o $basetexture no apunta a ningún VTFRevisa la ruta a partir de materials/ y cómo está escrita
Malla de alambre blancaEl shader de la primera línea no existeCorrige el nombre del shader
Tú lo ves, los demás noLos archivos solo existen en tu PCEntrega el material junto con el mapa
Superficie negra o que parpadeaVertexLitGeneric en un brushUsa LightmappedGeneric
La superficie brilla sin sombrasShader UnlitGeneric, que dibuja sin iluminaciónCambia el shader
Sonido de pisadas equivocadoFalta $surfaceprop o no encajaPon un valor adecuado

Si es el mapa entero el que se ve uniformemente brillante y no solo una superficie, faltan los datos de iluminación. De eso trata la guía de iluminación de Source Engine. Si has cambiado un VMT con el juego en marcha, el comando de consola mat_reloadmaterial seguido del nombre del VMT lo recarga.

El caso «los demás no lo ven» es el más frecuente. Los materiales custom solo existen en tu carpeta del juego hasta que los entregas. Cómo hacerlo se explica en empaquetar contenido custom en un BSP, y el lado del jugador, en solucionar texturas faltantes y modelos ERROR. Usa solo imágenes sobre las que tengas los derechos: tus propias fotos y gráficos, o fuentes cuya licencia permita la redistribución. Lo básico está en los fundamentos de los derechos de autor en mapas de GMod.

Preguntas frecuentes

¿Qué resolución debería tener una textura?

Depende de la superficie. Hammer aplica las texturas nuevas con una escala de 0,25, así que un píxel cubre un cuarto de unidad y una textura de 512 píxeles de ancho se repite cada 128 unidades. Las resoluciones más altas se ven más nítidas de cerca, pero cuestan memoria y tamaño de archivo.

¿Cómo hago que se vea a través de una valla o una reja?

La imagen necesita un canal alfa en el que los huecos sean negros, y el VTF, un formato que lo guarde, normalmente DXT5. En el VMT escribes $alphatest 1. El ejemplo de la Valve Developer Community también pone $alphatestreference 0.5 como umbral entre visible e invisible. Si la superficie debe verse desde los dos lados, añade $nocull 1.

¿Necesita cada textura un normal map?

No. Un material funciona con $basetexture y $surfaceprop. Un normal map cuesta otro VTF, y las superficies con $bumpmap reciben cuatro lightmaps en lugar de uno. Compensa allí donde la luz rasante deba revelar el relieve.