Repository navigation
Genome
A Genome sets the heritable traits of a humanoid. It sets the skin's tone, the hair's and the eyes' color, the frame's proportions, and the shape of the head and the face. Give a genome to HumanoidSpec to select these visual and template controls.
For engineering use and representation limits, see Humanoid fidelity.

The module is extensions/humanoid/genome.mojo. This is not a three.js port. See Extensions.
from extensions.humanoid.athleticism import TONED
from extensions.humanoid.genome import (
MELANIN,
NOSE_LENGTH,
Expression,
Genome,
offspring,
random_genome,
)
from extensions.humanoid.sex import FEMALE, MALE
from extensions.humanoid.spec import HumanoidSpec
from units.si import FOOT, Length
var genome = Genome().with_gene(MELANIN, Expression(0.6)).with_gene(
NOSE_LENGTH, Expression(-0.3)
)
var person = HumanoidSpec(Length(6.0, FOOT), MALE, TONED, genome)
var cousin = HumanoidSpec(Length(5.5, FOOT), FEMALE, TONED, random_genome(7))
var child = offspring(genome, random_genome(7), 3)Genome() is the template: every gene at zero. A spec without a genome holds the template, so a body made before genomes existed does not change shape.
Each gene takes an Expression from -1 through 1. Zero is the template. The sign says which way the trait moves. At 1 or -1 a trait is near the edge of the adult range. It is not past it.
A bare integer for a gene is a compile error, and so is a bare float for an expression. with_gene raises for a gene that is not named or an expression outside -1 through 1. Every boundary that reads a genome calls check_genome, which refuses one that is not valid.
| Gene | At -1 | At 1 | What it moves |
|---|---|---|---|
MELANIN |
Very fair skin | Very dark skin | The skin's tone, from Fitzpatrick type I to type VI |
UNDERTONE |
Cool, pink | Warm, olive | The skin's hue |
FRECKLES |
None | Many | Freckles in the skin's map, fewer on dark skin |
HAIR_MELANIN |
Platinum blond | Black | The hair's and the brows' color |
HAIR_REDNESS |
No red | Auburn, copper | The hair's red |
IRIS_MELANIN |
Blue | Dark brown | The iris's color |
EYE_SIZE |
Small | Large | The eyeball and the opening of the lids |
EYE_SPACING |
Close-set | Wide-set | The orbits, the eyes and the lids |
EYE_TILT |
Outer corners down | Outer corners up | The canthal tilt |
EYE_DEPTH |
Prominent | Deep-set | The eyes in their orbits |
BROW_HEIGHT |
Low | High | The brows over the eyes |
BROW_THICKNESS |
Fine | Full | The eyebrows' hair |
BROW_ARCH |
Flat | Arched | The middle of each brow |
NOSE_LENGTH |
Short | Long | The nose from its root to its tip |
NOSE_WIDTH |
Narrow | Broad | The wings of the nose |
NOSE_PROJECTION |
Flat | Projecting | The tip, forward from the face |
NOSE_BRIDGE |
Low | High | The bridge between the eyes |
MOUTH_WIDTH |
Narrow | Wide | The mouth from corner to corner |
LIP_FULLNESS |
Thin | Full | Both lips |
EAR_SIZE |
Small | Large | The auricle |
EAR_PROTRUSION |
Close to the head | Standing out | The flare of each ear's back edge |
EAR_LOBE |
Attached | Large and free | The lobe |
HEAD_WIDTH |
Narrow | Broad | The cranium's breadth |
HEAD_LENGTH |
Short | Long | The cranium from front to back |
HEAD_HEIGHT |
Low | Tall | The vault above the ears |
JAW_WIDTH |
Narrow | Broad | The mandible at its angles |
CHIN |
Receding | Strong | The chin forward and down |
CHEEKBONES |
Flat | High, prominent | The cheekbones out and forward |
BROW_RIDGE |
Smooth | Heavy | The brow ridge over the eyes |
NECK_LENGTH |
Short | Long | The neck between its base and the skull |
SHOULDER_BREADTH |
Narrow | Broad | The rib cage and the shoulders |
CHEST_DEPTH |
Shallow | Deep | The rib cage from front to back |
ARM_LENGTH |
Short | Long | The upper arm and the forearm |
HAIR_LENGTH |
Cropped close | A bob to the jaw | The scalp's hair |
FACE_SHAPE_1 to FACE_SHAPE_8
|
-2.2 standard deviations | +2.2 standard deviations | The whole face, along one mode of the scanned face model each |
HAIR_CURL |
Straight | Tightly coiled | The scalp's hair: straight to zero, wavy at a third, curly at two thirds |
named_genes() returns every gene in this order. Hair is cut as well as grown, so HAIR_LENGTH is a look more than a trait. gene_label(gene) returns its lowercase name.
The face shape genes weigh the first eight identity modes of the ICT Face Model. Each mode is a direction in which real faces differ. One mode moves many features at once, as a real face does: a longer face, say, with a narrower jaw and a higher brow. The authored genes above still move one feature each, on top of the modes. The modes reshape the head and fade out down the neck, so the body's genes still shape the neck's base. The eyeballs move with the scan's orbits.
The genes are authored controls. They are not a model of the loci that set these traits in people. Many small genes set each trait, and growth and the environment change them too.
The skin's genes set its looks. skin_tone(genome) walks a ramp of six swatches for MELANIN, then moves the result toward pink or olive for UNDERTONE. skin_albedo(size, genome) adds broad blotches of redness and pigment, pores, freckles and a rare mole. hair_tone and iris_tone do the same for the hair and the iris. See Head.
The head's and the face's genes move the head's landmarks. Each landmark is authored in centimeters on the six-foot template, and HeadMorph moves it before the frame places it. Each gene is a smooth displacement in its own region. The nose's genes move the points near the nose, and the eyes' genes the points round each orbit. These authored controls move several layers through one frame.
The separate scanned identity modes do not deform every anatomical layer. Containment is not guaranteed. Below the base of the neck the morph does nothing, so the neck still meets the torso.
The ears are skin and cartilage alone, so the skin shapes them itself. warp_ear(point, size, protrusion, lobe) moves each point of the scanned ear: it grows about its root, its back edge stands out, and its lobe hangs lower. ear_weight(point) says how much of the ear a point is. See Head.
The frame's genes change the torso's frame. SHOULDER_BREADTH widens the rib cage and the shoulder girdle, most at the shoulders and not at all at the waist. The arms hang from the wider girdle. CHEST_DEPTH deepens the rib cage in front of and behind the spine. ARM_LENGTH stretches the upper arm and the forearm. The hand keeps its size.
The female template's face differs from the male one's as the averages of the two differ. It has a smaller brow ridge and nose, a narrower jaw and a smaller chin. It has slightly larger eyes, fuller lips and a longer neck. HeadMorph adds those offsets to the genes.
random_genome(seed) draws a plausible genome. The same seed always gives the same genome. Most traits land near the template. The pigment genes are linked as they are in people: dark skin rarely comes with blond hair, freckles or blue eyes. Very dark skin often comes with tightly curled hair.
offspring(mother, father, seed) returns a child. Each gene lands between the two parents' expressions, with a small mutation of at most 0.1. It raises if a parent's genome is not valid.
add_complexion(assets, genome, whole_body) stores the looks one genome asks for and returns their ids in a Complexion:
| Field | Look |
|---|---|
skin |
skin_physical with the tone, a tiled color map and pore relief, tinted by the face's zones, with light through thin skin |
hair |
hair_physical with a map of strands |
eyes |
eye_physical with the iris's map |
Pass whole_body=True for the skin of add_body, which is taller than the head's and tiles more times up it. Each tile is about as wide around the skin as it is tall, so a pore is round and not a streak. body_skin_mesh measures every vertex's v over the whole body's height. The head's tiles are then the size of the body's, and the two meet on the neck.
Pass size to set the skin color map's width in texels, from 8 through 512. The default is 512. The relief and the hair's map are half that size. A smaller map is faster to make and blurrier.
The skin is tinted: every mesh it paints must carry a color attribute. The head's skin and the body's skin carry one. untinted(geometry) gives another mesh a white one. See Head.
examples/genomes.mojo draws six heads from six genomes and turns each a little to each side. It writes out/genomes.png.
examples/family.mojo draws two parents and their two grown children, whole, and turns them. Each child is the offspring of the parents. It writes out/family.png.

.venv/bin/mojo run -I . examples/genomes.mojo out/genomes.png high 24
.venv/bin/mojo run -I . examples/family.mojo out/family.png high 36Set THREEMOJO_ASSET_ROOT when a compiled program runs outside the repository.
Its value is the path to the assets directory.
Use an absolute path to make lookup independent of the working directory.
A relative path is allowed. It is relative to the working directory at each lookup.
High-level scanned heads and named scanned hairstyles read data from this root.
export THREEMOJO_ASSET_ROOT="/path/to/ThreeMojo/assets"
/path/to/compiled-exampleWhen the variable is unset or empty, the existing repository-relative paths
remain in use. FaceModel(path) still reads the explicit path you pass.
Missing data raises the loader's file error. A configured root never falls back
to the repository's data. The setting does not download data.
Tutorials
How-to
Reference
- Scene graph
- Rotations
- Cameras
- Geometry
- Geometry addons
- Lofts and clipping groups
- Sculptor
- Procedural generators
- Meshes and assets
- Lines
- Points and sprites
- Helpers
- Scene objects
- Animated objects
- Raycasting
- Curves and paths
- Animation
- Skinning
- Materials
- Node materials
- TSL functions
- Lights
- Lighting addons
- Fog
- Textures
- Renderer
- Renderer hooks and material flags
- Rasterization
- GPU backend
- Render target
- Post-processing
- GPU computation
- Compute nodes
- Progressive light map
- Gaussian splats
- Voxel global illumination
- SVG renderer
- Image files
- Image decode queue
- Model files
- More model files
- Exporters
- Scene JSON
- Windowing and controls
- Math
- Norm consumers
- Math addons
- Units
- Coverage tool
- Commands
- Examples
- Benchmarks
- Extensions
- Shared physics
- Physics query snapshots
- Continuous collision
- Tick force restoration
- Water
- Animals
- Buildings
- CARLA
- Femur
- Tibia
- Fibula
- Patella
- Knee
- Muscles
- Vessels
- Lymph
- Nerves
- Integument
- Leg
- Foot
- Pelvis
- Torso
- Arm
- Hand
- Head
- Genome
- Game humanoid
- Humanoid fidelity
- Audio-aligned game faces
- Converted assets
- Mesh quality
- Segment inertia
Explanation
- Software rasterizer
- Scene graph as an array
- Linear color
- Normals are not colors
- Perspective correction
- Fixed-point coverage
- Per-fragment shading
- Mipmaps
- Sorted transparency
- Types and checks
- Render hooks as a trait
- Shared CPU and GPU code
- Bands and threads
- PNG structure
- Extensions beside the port
- CUDA teardown hang
- Mojo compiler hang