Skip to content

Models: 3D Artist's corner

Andrei Stepanov edited this page Apr 27, 2017 · 17 revisions

Welcome to the 3D Artist's corner. Here you can learn about creating 3D models for qfusion.

This page is still very much work in progress, and there seems to be little actual information on creating new 3D models and visual effects for qfusion


1. File formats used

  • The model formats more often used in qfusion development are: IQM (Inter-Quake Model Format), MD3 (for animated meshes) and LWO and ASE (for static meshes).

2. Creating a player model

The preferred format for qfusion is IQM A format that is also used by some other open-source games like Xonotic and Cube2 based games. So you might be able to use some documentation from these games too. Here is a tutorial how to get a .iqm playermodel into Xonotic which should work very similarly in qfusion.

2.1. Tags

qfusion doesn't use specific bone names for things, but "tags" bones as tagmasks like this:

tagmask "Bip01 R Hand" "tag_weapon" -2 0 0 // numbers mean offset forward, right and up

You can perfectly call "Bip01 R Hand" absolutely anything as long as you show it in the animation.cfg file.

2.2. Textures

Playermodel textures usually are 512 x 512 or 1024x1024 etc. and there are usually 3 textures on each model, head, torso, and legs. There are also diffuse, norm, gloss/specmap and colorpass/mask. A colorpass is a texture overlayed onto the model that tells what parts will be colors when you choose your team colors and player colors. Colorpasses have alpha channels, and everything painted white gets full color, while grey to black are less and less colorful.

For example: *padpork_head.tga *padpork_head_colorpass_fb.tga *padpork_head_norm.tga and:

  • padpork_legs.tga
  • padpork_legs_colorpass.tga
  • padpork_legs_colorpass_fb.tga
  • padpork_legs_norm.tga

Padpork doesn't have a colorpass texture on his head because his head stays pink when not fullbright (fb).

Note that many textures in the game have been converted to .ktx a special OpenGL compressed texture format similar to .dds. The engine will look first for these and if none are found will fall back on uncompressed .tga.

2.3. Animations

Animations are 1 big animation. Frames are specified for each animation from a text file (animation.cfg). A partially outdated (from before .iqm was used) file definition can be found here.

General details

There is a root bone from where the upper animation is played. The code works works basically like this:

  • It gets the bones for the main animation (run, walk, etc).
  • It gets the bones for the upper animation (shoot, pain, etc).
  • Mixes them in one new bunch of bones picking depending on the root bone.
  • (it could add here another frames to be blended for animation transitions, but this step wasn't really needed here)
  • Add special manipulations (rotate spine and head according to looking direction)
  • Mount the skeleton.
  • Feed it to the renderer as is (skipping renderer interpolation).

3. Testing model in-game

Here are console commands that help to test model in-game:

  • Start a local server by devmap <mapname>
  • Toggle third person view by cg_thirdPerson 1
  • Adjust view angle and range by cg_thirdpersonrange & cg_thirdpersonangle respectively

Following config script allows to use END button to toggle third person view & keyboard arrows for adjusting view angle and range:

bind END "thirdperson"
aliasa thirdperson "thirdperson_in"
aliasa thirdperson_in "cg_thirdPerson 1; cg_showHud 0; aliasa thirdperson thirdperson_out"
aliasa thirdperson_out "cg_thirdPerson 0; cg_showHud 1; aliasa thirdperson thirdperson_in"

bind UPARROW "rangep"
bind DOWNARROW "rangem"
seta cg_thirdpersonrange "90"
alias rangep range07
alias rangem range05

aliasa range12 "seta cg_thirdpersonrange 40; aliasa rangem range11; aliasa rangep range12; echo ^2Third Person Range = ^740 ^4Min"
aliasa range11 "seta cg_thirdpersonrange 50; aliasa rangem range10; aliasa rangep range12; echo ^2Third Person Range = ^750"
aliasa range10 "seta cg_thirdpersonrange 60; aliasa rangem range09; aliasa rangep range11; echo ^2Third Person Range = ^760"
aliasa range09 "seta cg_thirdpersonrange 70; aliasa rangem range08; aliasa rangep range10; echo ^2Third Person Range = ^770"
aliasa range08 "seta cg_thirdpersonrange 80; aliasa rangem range07; aliasa rangep range09; echo ^2Third Person Range = ^780"
aliasa range07 "seta cg_thirdpersonrange 90; aliasa rangem range06; aliasa rangep range08; echo ^2Third Person Range = ^790 ^4Default"
aliasa range06 "seta cg_thirdpersonrange 100; aliasa rangem range05; aliasa rangep range07; echo ^2Third Person Range = ^7100"
aliasa range05 "seta cg_thirdpersonrange 110; aliasa rangem range04; aliasa rangep range06; echo ^2Third Person Range = ^7110"
aliasa range04 "seta cg_thirdpersonrange 120; aliasa rangem range03; aliasa rangep range05; echo ^2Third Person Range = ^7120"
aliasa range03 "seta cg_thirdpersonrange 130; aliasa rangem range02; aliasa rangep range04; echo ^2Third Person Range = ^7130"
aliasa range02 "seta cg_thirdpersonrange 140; aliasa rangem range01; aliasa rangep range03; echo ^2Third Person Range = ^7140"
aliasa range01 "seta cg_thirdpersonrange 150; aliasa rangem range00; aliasa rangep range02; echo ^2Third Person Range = ^7150"
aliasa range00 "seta cg_thirdpersonrange 160; aliasa rangem range00; aliasa rangep range01; echo ^2Third Person Range = ^7160 ^4Max"

bind LEFTARROW "Anglep"
bind RIGHTARROW "Anglem"
seta cg_thirdpersonangle "0"
alias Anglep Angle05
alias Anglem Angle03

aliasa Angle08 "seta cg_thirdpersonangle 180; aliasa Anglem Angle07; aliasa Anglep Angle01; echo ^2Third Person Angle = ^7180"
aliasa Angle07 "seta cg_thirdpersonangle 135; aliasa Anglem Angle06; aliasa Anglep Angle08; echo ^2Third Person Angle = ^7135"
aliasa Angle06 "seta cg_thirdpersonangle 90; aliasa Anglem Angle05; aliasa Anglep Angle07; echo ^2Third Person Angle = ^790"
aliasa Angle05 "seta cg_thirdpersonangle 45; aliasa Anglem Angle04; aliasa Anglep Angle06; echo ^2Third Person Angle = ^745"
aliasa Angle04 "seta cg_thirdpersonangle 0; aliasa Anglem Angle03; aliasa Anglep Angle05; echo ^2Third Person Angle = ^70 ^4Default"
aliasa Angle03 "seta cg_thirdpersonangle -45; aliasa Anglem Angle02; aliasa Anglep Angle04; echo ^2Third Person Angle = ^7315"
aliasa Angle02 "seta cg_thirdpersonangle -90; aliasa Anglem Angle01; aliasa Anglep Angle03; echo ^2Third Person Angle = ^7270"
aliasa Angle01 "seta cg_thirdpersonangle -135; aliasa Anglem Angle08; aliasa Anglep Angle02; echo ^2Third Person Angle = ^7225"
Clone this wiki locally