# Statue

> A weathered low-poly stone statue on a stepped plinth with a bronze name plaque. Pick a knight resting both hands on a planted sword with a flowing cape, a praying angel with spread feathered wings, or a classical bearded bust on a column pedestal. Recolor the figure and plinth stone and add creeping moss for ruins. A strong focal point for plazas, castle halls, gardens and graveyards.

![Statue preview](https://codels.download/m/statue.png)

Multi-view sheet (3/4, front, side, top): https://codels.download/m/statue.sheet.png

## Facts

- Category: Props › Decor
- Size (W × H × D): 1.00 × 2.70 × 1.00 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 984 · Meshes: 43 · Materials: 5
- License: CC0-1.0 (Codels built-in)
- Tags: angel, knight, ruins, statue, low-poly, stylized, ancient, fantasy, medieval, castle, city, garden, adventure, rpg, decoration, landmark, stone, symmetric, tall, mobile-friendly, parametric, color-gray, size-medium, poly-low
- Page: https://codels.download/models/statue

## Files

| Format | URL |
|---|---|
| three.js ES module (`createStatue()`) | https://codels.download/m/statue.js |
| React Three Fiber component (`<Statue />`) | https://codels.download/m/statue.jsx |
| Instancing module (`createStatueInstances(count, place)`, one draw call per material) | https://codels.download/m/statue.instanced.js |
| Standalone HTML demo | https://codels.download/m/statue.html |
| glTF binary | https://codels.download/m/statue.glb |
| glTF binary, Meshopt-compressed (2–3× smaller; GLTFLoader needs `setMeshoptDecoder(MeshoptDecoder)`) | https://codels.download/m/statue.glb?compress=meshopt |
| glTF JSON | https://codels.download/m/statue.gltf |
| OBJ (vertex colors) + MTL | https://codels.download/m/statue.obj · https://codels.download/m/statue.mtl |
| STL | https://codels.download/m/statue.stl |
| CodelSpec JSON | https://codels.download/m/statue.json |

## Parameters

Append them as query parameters to any URL above to get a customized variant (e.g. `?style=...`).

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `style` | select | knight \| angel \| bust | knight | knight |
| `stone` | color | #rrggbb | #aca699 | #aca699 |
| `plinth` | color | #rrggbb | #8e887f | #8e887f |
| `moss` | boolean | true \| false | false | false |

## Parts

- step (box · trim)
- baseMolding (box · trim)
- plinth (box · plinth)
- cap (box · trim)
- plaque (box · plaque)
- inscription (box · carve)
- inscription (box · carve)
- inscription (box · carve)
- knight (group)
  - foot (box · stone)
  - greave (cylinder · stone)
  - kneeGuard (box · stone)
  - thigh (cylinder · stone)
  - foot (box · stone)
  - greave (cylinder · stone)
  - kneeGuard (box · stone)
  - thigh (cylinder · stone)
  - tabard (cylinder · stone)
  - breastplate (cylinder · stone)
  - belt (cylinder · stone)
  - chestRidge (box · stone)
  - pauldron (sphere · stone)
  - pauldron (sphere · stone)
  - gorget (cylinder · stone)
  - helm (cylinder · stone)
  - helmTop (sphere · stone)
  - crest (box · stone)
  - visorSlit (box · carve)
  - visorNose (box · carve)
  - upperArm (cylinder · stone)
  - elbow (sphere · stone)
  - forearm (cylinder · stone)
  - gauntlet (box · stone)
  - upperArm (cylinder · stone)
  - elbow (sphere · stone)
  - forearm (cylinder · stone)
  - gauntlet (box · stone)
  - blade (box · stone)
  - bladeTip (cylinder · stone)
  - fuller (box · carve)

## How to use

Save the code below as `statue.js`, then:

```js
import { createStatue } from './statue.js';
const model = createStatue();
scene.add(model);
```

## Code

```js
/**
 * Statue — Codels 3D model library (https://codels.download/models/statue)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 984 · Size (W × H × D): 1.00 × 2.70 × 1.00 m
 *
 * Usage:
 *   import { createStatue } from './statue.js';
 *   
 *   const model = createStatue();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Revolve a 2D profile [[radius, y], ...] around the Y axis.
function lathe(points, segments, phiStart = 0, phiLength = Math.PI * 2) {
  return new THREE.LatheGeometry(points.map(([x, y]) => new THREE.Vector2(x, y)), segments, phiStart, phiLength);
}

export function createStatue() {
  const root = new THREE.Group();
  root.name = 'Statue';

  // Materials
  const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0xaca699, roughness: 0.85, flatShading: true });
  const carveMat = new THREE.MeshStandardMaterial({ name: 'carve', color: 0x646059, roughness: 0.95, flatShading: true });
  const plinthMat = new THREE.MeshStandardMaterial({ name: 'plinth', color: 0x8e887f, roughness: 0.9, flatShading: true });
  const trimMat = new THREE.MeshStandardMaterial({ name: 'trim', color: 0x726d66, roughness: 0.92, flatShading: true });
  const plaqueMat = new THREE.MeshStandardMaterial({ name: 'plaque', color: 0x8c6a3a, roughness: 0.4, metalness: 0.6, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.13, 0.08, 0.27);
  const cylinderGeo = new THREE.CylinderGeometry(0.078, 0.062, 0.44, 7);
  const boxGeo2 = new THREE.BoxGeometry(0.11, 0.09, 0.05);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.095, 0.08, 0.3601, 7);
  const sphereGeo = new THREE.SphereGeometry(0.105, 7, 5);
  const cylinderGeo3 = new THREE.CylinderGeometry(0.056, 0.064, 0.2526, 7);
  const sphereGeo2 = new THREE.SphereGeometry(0.06, 6, 4);
  const cylinderGeo4 = new THREE.CylinderGeometry(0.046, 0.056, 0.3212, 7);
  const boxGeo3 = new THREE.BoxGeometry(0.075, 0.085, 0.09);

  // Parts
  const step = new THREE.Mesh(new THREE.BoxGeometry(1, 0.14, 1), trimMat);
  step.name = 'step';
  step.position.set(0, 0.07, 0);
  root.add(step);
  const baseMolding = new THREE.Mesh(new THREE.BoxGeometry(0.84, 0.06, 0.84), trimMat);
  baseMolding.name = 'baseMolding';
  baseMolding.position.set(0, 0.17, 0);
  root.add(baseMolding);
  const plinth = new THREE.Mesh(new THREE.BoxGeometry(0.78, 0.66, 0.78), plinthMat);
  plinth.name = 'plinth';
  plinth.position.set(0, 0.47, 0);
  root.add(plinth);
  const cap = new THREE.Mesh(new THREE.BoxGeometry(0.88, 0.1, 0.88), trimMat);
  cap.name = 'cap';
  cap.position.set(0, 0.85, 0);
  root.add(cap);
  const plaque = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.2, 0.012), plaqueMat);
  plaque.name = 'plaque';
  plaque.position.set(0, 0.5, 0.396);
  root.add(plaque);
  const inscription = new THREE.Mesh(new THREE.BoxGeometry(0.28, 0.016, 0.004), carveMat);
  inscription.name = 'inscription';
  inscription.position.set(0, 0.54, 0.403);
  root.add(inscription);
  const inscription2 = new THREE.Mesh(new THREE.BoxGeometry(0.22, 0.016, 0.004), carveMat);
  inscription2.name = 'inscription';
  inscription2.position.set(0, 0.5, 0.403);
  root.add(inscription2);
  const inscription3 = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.016, 0.004), carveMat);
  inscription3.name = 'inscription';
  inscription3.position.set(0, 0.46, 0.403);
  root.add(inscription3);
  const knight = new THREE.Group();
  knight.name = 'knight';
  knight.position.set(0, 0.9, 0);
  root.add(knight);
  const foot = new THREE.Mesh(boxGeo, stoneMat);
  foot.name = 'foot';
  foot.position.set(0.11, 0.04, 0.03);
  knight.add(foot);
  const greave = new THREE.Mesh(cylinderGeo, stoneMat);
  greave.name = 'greave';
  greave.position.set(0.11, 0.28, 0);
  knight.add(greave);
  const kneeGuard = new THREE.Mesh(boxGeo2, stoneMat);
  kneeGuard.name = 'kneeGuard';
  kneeGuard.position.set(0.11, 0.5, 0.07);
  knight.add(kneeGuard);
  const thigh = new THREE.Mesh(cylinderGeo2, stoneMat);
  thigh.name = 'thigh';
  thigh.position.set(0.115, 0.66, 0);
  thigh.rotation.set(0, 0, deg(-1.5911));
  knight.add(thigh);
  const foot2 = new THREE.Mesh(boxGeo, stoneMat);
  foot2.name = 'foot';
  foot2.position.set(-0.11, 0.04, 0.03);
  knight.add(foot2);
  const greave2 = new THREE.Mesh(cylinderGeo, stoneMat);
  greave2.name = 'greave';
  greave2.position.set(-0.11, 0.28, 0);
  knight.add(greave2);
  const kneeGuard2 = new THREE.Mesh(boxGeo2, stoneMat);
  kneeGuard2.name = 'kneeGuard';
  kneeGuard2.position.set(-0.11, 0.5, 0.07);
  knight.add(kneeGuard2);
  const thigh2 = new THREE.Mesh(cylinderGeo2, stoneMat);
  thigh2.name = 'thigh';
  thigh2.position.set(-0.115, 0.66, 0);
  thigh2.rotation.set(0, 0, deg(1.5911));
  knight.add(thigh2);
  const tabard = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.26, 0.34, 8, 1, false, 0.3927), stoneMat);
  tabard.name = 'tabard';
  tabard.position.set(0, 0.75, 0);
  tabard.scale.set(1, 1, 0.74);
  knight.add(tabard);
  const breastplate = new THREE.Mesh(new THREE.CylinderGeometry(0.25, 0.19, 0.52, 8, 1, false, 0.3927), stoneMat);
  breastplate.name = 'breastplate';
  breastplate.position.set(0, 1.16, 0);
  breastplate.scale.set(1, 1, 0.66);
  knight.add(breastplate);
  const belt = new THREE.Mesh(new THREE.CylinderGeometry(0.205, 0.205, 0.06, 8, 1, false, 0.3927), stoneMat);
  belt.name = 'belt';
  belt.position.set(0, 0.91, 0);
  belt.scale.set(1, 1, 0.72);
  knight.add(belt);
  const chestRidge = new THREE.Mesh(new THREE.BoxGeometry(0.05, 0.42, 0.03), stoneMat);
  chestRidge.name = 'chestRidge';
  chestRidge.position.set(0, 1.15, 0.13);
  chestRidge.rotation.set(deg(-6), 0, 0);
  knight.add(chestRidge);
  const pauldron = new THREE.Mesh(sphereGeo, stoneMat);
  pauldron.name = 'pauldron';
  pauldron.position.set(0.25, 1.36, 0);
  pauldron.scale.set(1, 0.75, 0.95);
  knight.add(pauldron);
  const pauldron2 = new THREE.Mesh(sphereGeo, stoneMat);
  pauldron2.name = 'pauldron';
  pauldron2.position.set(-0.25, 1.36, 0);
  pauldron2.scale.set(1, 0.75, 0.95);
  knight.add(pauldron2);
  const gorget = new THREE.Mesh(new THREE.CylinderGeometry(0.085, 0.11, 0.08, 8), stoneMat);
  gorget.name = 'gorget';
  gorget.position.set(0, 1.44, 0);
  knight.add(gorget);
  const helm = new THREE.Mesh(new THREE.CylinderGeometry(0.11, 0.105, 0.2, 8, 1, false, 0.3927), stoneMat);
  helm.name = 'helm';
  helm.position.set(0, 1.56, 0);
  knight.add(helm);
  const helmTop = new THREE.Mesh(new THREE.SphereGeometry(0.11, 8, 3, 0, Math.PI * 2, 0, Math.PI / 2), stoneMat);
  helmTop.name = 'helmTop';
  helmTop.position.set(0, 1.66, 0);
  helmTop.rotation.set(0, deg(22.5), 0);
  knight.add(helmTop);
  const crest = new THREE.Mesh(new THREE.BoxGeometry(0.03, 0.07, 0.22), stoneMat);
  crest.name = 'crest';
  crest.position.set(0, 1.765, -0.01);
  knight.add(crest);
  const visorSlit = new THREE.Mesh(new THREE.BoxGeometry(0.17, 0.022, 0.02), carveMat);
  visorSlit.name = 'visorSlit';
  visorSlit.position.set(0, 1.6, 0.096);
  knight.add(visorSlit);
  const visorNose = new THREE.Mesh(new THREE.BoxGeometry(0.024, 0.07, 0.02), carveMat);
  visorNose.name = 'visorNose';
  visorNose.position.set(0, 1.55, 0.096);
  knight.add(visorNose);
  const upperArm = new THREE.Mesh(cylinderGeo3, stoneMat);
  upperArm.name = 'upperArm';
  upperArm.position.set(0.285, 1.215, 0.05);
  upperArm.rotation.set(deg(152.2605), deg(-31.7253), deg(-8.0268));
  knight.add(upperArm);
  const elbow = new THREE.Mesh(sphereGeo2, stoneMat);
  elbow.name = 'elbow';
  elbow.position.set(0.3, 1.1, 0.1);
  knight.add(elbow);
  const forearm = new THREE.Mesh(cylinderGeo4, stoneMat);
  forearm.name = 'forearm';
  forearm.position.set(0.17, 1.05, 0.18);
  forearm.rotation.set(deg(37.8985), deg(35.8238), deg(86.5428));
  knight.add(forearm);
  const gauntlet = new THREE.Mesh(boxGeo3, stoneMat);
  gauntlet.name = 'gauntlet';
  gauntlet.position.set(0.04, 1, 0.26);
  knight.add(gauntlet);
  const upperArm2 = new THREE.Mesh(cylinderGeo3, stoneMat);
  upperArm2.name = 'upperArm';
  upperArm2.position.set(-0.285, 1.215, 0.05);
  upperArm2.rotation.set(deg(152.2605), deg(31.7253), deg(8.0268));
  knight.add(upperArm2);
  const elbow2 = new THREE.Mesh(sphereGeo2, stoneMat);
  elbow2.name = 'elbow';
  elbow2.position.set(-0.3, 1.1, 0.1);
  knight.add(elbow2);
  const forearm2 = new THREE.Mesh(cylinderGeo4, stoneMat);
  forearm2.name = 'forearm';
  forearm2.position.set(-0.17, 1.05, 0.18);
  forearm2.rotation.set(deg(37.8985), deg(-35.8238), deg(-86.5428));
  knight.add(forearm2);
  const gauntlet2 = new THREE.Mesh(boxGeo3, stoneMat);
  gauntlet2.name = 'gauntlet';
  gauntlet2.position.set(-0.04, 1, 0.26);
  knight.add(gauntlet2);
  const blade = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.8, 0.016), stoneMat);
  blade.name = 'blade';
  blade.position.set(0, 0.5, 0.26);
  knight.add(blade);
  const bladeTip = new THREE.Mesh(new THREE.CylinderGeometry(0.03, 0.001, 0.1, 4, 1, false, Math.PI / 4), stoneMat);
  bladeTip.name = 'bladeTip';
  bladeTip.position.set(0, 0.05, 0.26);
  bladeTip.scale.set(1.414, 1, 0.38);
  knight.add(bladeTip);
  const fuller = new THREE.Mesh(new THREE.BoxGeometry(0.012, 0.6, 0.004), carveMat);
  fuller.name = 'fuller';
  fuller.position.set(0, 0.56, 0.269);
  knight.add(fuller);
  const crossguard = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.035, 0.045), stoneMat);
  crossguard.name = 'crossguard';
  crossguard.position.set(0, 0.9175, 0.26);
  knight.add(crossguard);
  const grip = new THREE.Mesh(new THREE.CylinderGeometry(0.017, 0.017, 0.12, 6), stoneMat);
  grip.name = 'grip';
  grip.position.set(0, 0.995, 0.26);
  knight.add(grip);
  const pommel = new THREE.Mesh(new THREE.SphereGeometry(0.032, 6, 4), stoneMat);
  pommel.name = 'pommel';
  pommel.position.set(0, 1.075, 0.26);
  knight.add(pommel);
  const cape = new THREE.Mesh(lathe([[0.37, 0.16], [0.25, 1.36], [0.215, 1.36], [0.335, 0.16], [0.37, 0.16]], 6, Math.PI / 2, Math.PI), stoneMat);
  cape.name = 'cape';
  cape.position.set(0, 0, -0.01);
  cape.scale.set(1, 1, 0.72);
  knight.add(cape);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createStatue;
```

---
Codels — 3D models as code for three.js. Search more: https://codels.download/api/v1/models?q=<query> · Guide: https://codels.download/llms.txt
