Local asset authoring · 3.0.0
Mouth & Teeth Studio
Start with a species, then sculpt its flesh, individual crowns and tongue. Export textured assets in meters.
AI / backend controls
Instructions (TXT): people & AI agents · HTTP API schema
Use the existing stateless HTTP API or window.MouthStudio. No account, API key or credentials are required. HTTP GLB is geometry-only; browser textured GLB embeds PNG albedo, normal and ORM.
Randomization requests & recipe editing examples
Send Content-Type: application/json; the complete body must be at most 256 KiB. Successful validate/randomize responses supply a full normalized recipe. See the TXT guide for all scopes, locks and errors.
POST /api/game-assets/mouth/preset
{"config":{},"id":"cat","scope":"mouth","preserveStyle":false}
POST /api/game-assets/mouth/random-preset
{"config":{},"options":{"seed":174,"strength":0.35,"preserveStyle":false}}
New random mouth chooses a complete animal profile. Vary keeps the current profile; Preserve anatomy protects its tooth classes, counts, rows, gaps, dental pad, beak type and whole-mouth art style. Turn it off for freeform experiments.
POST /api/game-assets/mouth/randomize
{"config":{"shape":{"jawOpenDeg":35}},"options":{"scope":"all","seed":174,"strength":0.35,"locks":{"teeth":true}}}
POST /api/game-assets/mouth/randomize
{"config":{},"options":{"scope":"tooth","seed":175,"strength":0.35,"locks":{"teeth":false},"toothId":"upper-r0-t3"}}
Scopes: all, shape, teeth, tongue, textures, style, tooth. HTTP tooth scope requires options.toothId and respects the teeth lock. Omit options.locks to use the recipe's locks.
A part recipe uses defaults for omitted fields; HTTP does not merge with an earlier request or the browser editor:
POST /api/game-assets/mouth/validate
{"config":{"tongue":{"curl":0.3}}}
For a full recipe edit, obtain a normalized recipe (or load your saved one), change a field, validate it and generate geometry. This same-origin browser example preserves its other categories:
const base = "/api/game-assets/mouth/";
async function post(route, body) {
const response = await fetch(base + route, {
method: "POST", headers: {"Content-Type": "application/json"},
body: JSON.stringify(body)
});
const data = await response.json();
if (!response.ok) throw new Error(data.error.message);
return data;
}
const full = (await post("validate", {config:{}})).config;
full.tongue.curl = 0.3;
const checked = await post("validate", {config:full});
const generated = await post("generate", {config:checked.config,tier:"preview"});
Browser randomization example after ready: MouthStudio.randomize({scope:"tongue",seed:174,strength:0.35,locks:{shape:true},variationBand:"natural"}). variationBand is subtle, natural, bold or wild. MouthStudio.randomPreset({seed:174,strength:0.35,variationBand:"bold",family:"living"}) starts a new mouth; omit family for every species, or pass a catalog family, living, prehistoric or fantasy. MouthStudio.listPartPresets("teeth"|"tongue"|"gums") and MouthStudio.setPartPreset(scope,id) read and apply one part. Choosing a species or part preset does not change the asset until Apply. Use MouthStudio.exportTexturedGLB({tier:"game"}) for embedded PBR maps; HTTP /export.glb returns geometry-only bytes.
Loading the mouth model. If loading does not finish, read the guide and reload.
Preparing the local 3D preview…
Drag to orbit · Scroll or pinch to zoom · +Y up · +Z forward
Preparing geometry…
Quality
Detail, map size and preview triangles appear after the model builds.
Low-poly, Game and Detailed set geometry detail and the shared map size. They do not change art style. Custom means the current detail or map size is not one of those presets. Figures above are the values in use.
Studio lighting & background
Studio illumination is a viewing aid. Exported PBR materials respond to the destination scene's lights.
Selected texture size is the actual shared atlas width and height. Geometry sliders reuse its cached maps. Click a tooth or choose any slot, including absent teeth.