# Stone Wall

> A modular stone wall segment built from irregular, staggered stone blocks over a dark mortar core, finished with capstones or a crenellated castle parapet with walkway. Flat ends let segments tile in a row; adjust length, height and stone color and sprinkle optional moss for ruins, castles, farms and garden borders.

![Stone Wall preview](https://codels.download/m/stone-wall.png)

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

## Facts

- Category: Buildings › Structures
- Size (W × H × D): 3.02 × 1.44 × 0.85 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 384 · Meshes: 30 · Materials: 4
- License: CC0-1.0 (Codels built-in)
- Tags: castle-part, stone-wall, wall, low-poly, stylized, fantasy, farm, medieval, castle, garden, village, rpg, strategy, tower-defense, building, modular, obstacle, stone, mobile-friendly, parametric, color-gray, size-large, poly-low
- Page: https://codels.download/models/stone-wall

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `length` | number | 1 – 6 | 3 | 3 |
| `height` | number | 0.6 – 3.5 | 1.4 | 1.4 |
| `crenellations` | boolean | true \| false | false | false |
| `color` | color | #rrggbb | #8e887d | #8e887d |
| `moss` | boolean | true \| false | true | true |

## Parts

- core (box · mortar)
- block (box · stone)
- block (box · stone)
- block (box · stone2)
- block (box · stone)
- block (box · stone)
- block (box · stone2)
- block (box · stone)
- block (box · stone)
- block (box · stone)
- block (box · stone2)
- block (box · stone)
- block (box · stone)
- block (box · stone2)
- block (box · stone)
- block (box · stone2)
- block (box · stone2)
- block (box · stone2)
- block (box · stone)
- block (box · stone2)
- block (box · stone2)
- block (box · stone2)
- block (box · stone2)
- capstone (box · stone2)
- capstone (box · stone2)
- capstone (box · stone2)
- capstone (box · stone2)
- moss (icosahedron · moss)
- moss (icosahedron · moss)
- moss (icosahedron · moss)

## How to use

Save the code below as `stone-wall.js`, then:

```js
import { createStoneWall } from './stone-wall.js';
const model = createStoneWall();
scene.add(model);
```

## Code

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

const deg = THREE.MathUtils.degToRad;

// Deterministic vertex displacement (organic low-poly look).
function jitter(geometry, amount, seed) {
  const pos = geometry.attributes.position;
  const h = (a, b, c, s) => {
    let x = Math.imul(a, 73856093) ^ Math.imul(b, 19349663) ^ Math.imul(c, 83492791) ^ Math.imul(s, 2654435761);
    x = Math.imul(x ^ (x >>> 16), 2246822507);
    x = Math.imul(x ^ (x >>> 13), 3266489909);
    return ((x ^ (x >>> 16)) >>> 0) / 4294967295 - 0.5;
  };
  for (let i = 0; i < pos.count; i++) {
    const x = pos.getX(i), y = pos.getY(i), z = pos.getZ(i);
    const qx = Math.round(x * 1000), qy = Math.round(y * 1000), qz = Math.round(z * 1000);
    pos.setXYZ(i, x + h(qx, qy, qz, seed) * 2 * amount, y + h(qx, qy, qz, seed + 1) * 2 * amount, z + h(qx, qy, qz, seed + 2) * 2 * amount);
  }
  pos.needsUpdate = true;
  geometry.computeVertexNormals();
  return geometry;
}

export function createStoneWall() {
  const root = new THREE.Group();
  root.name = 'StoneWall';

  // Materials
  const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0x8e887d, roughness: 0.95, flatShading: true });
  const stone2Mat = new THREE.MeshStandardMaterial({ name: 'stone2', color: 0x7a756c, roughness: 0.95, flatShading: true });
  const mortarMat = new THREE.MeshStandardMaterial({ name: 'mortar', color: 0x4e4b45, roughness: 1, flatShading: true });
  const mossMat = new THREE.MeshStandardMaterial({ name: 'moss', color: 0x5b7a37, roughness: 1, flatShading: true });

  // Parts
  const core = new THREE.Mesh(new THREE.BoxGeometry(2.93, 1.25, 0.512), mortarMat);
  core.name = 'core';
  core.position.set(0, 0.625, 0);
  root.add(core);
  const block = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6803, 0.2925, 0.6125), 0.02, 1), stoneMat);
  block.name = 'block';
  block.position.set(-1.1473, 0.1588, 0);
  block.rotation.set(0, deg(0.0989), deg(0.5632));
  root.add(block);
  const block2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.5819, 0.2925, 0.6369), 0.02, 2), stoneMat);
  block2.name = 'block';
  block2.position.set(-0.4912, 0.1588, 0);
  block2.rotation.set(0, deg(-1.0618), deg(0.3352));
  root.add(block2);
  const block3 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.711, 0.2925, 0.6018), 0.02, 3), stone2Mat);
  block3.name = 'block';
  block3.position.set(0.1802, 0.1588, 0);
  block3.rotation.set(0, deg(1.096), deg(-0.1499));
  root.add(block3);
  const block4 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4758, 0.2925, 0.5978), 0.02, 4), stoneMat);
  block4.name = 'block';
  block4.position.set(0.7986, 0.1588, 0);
  block4.rotation.set(0, deg(0.743), deg(-0.3041));
  root.add(block4);
  const block5 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4259, 0.2925, 0.612), 0.02, 5), stoneMat);
  block5.name = 'block';
  block5.position.set(1.2745, 0.1588, 0);
  block5.rotation.set(0, deg(-0.6807), deg(-0.191));
  root.add(block5);
  const block6 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.2176, 0.2925, 0.6107), 0.02, 6), stone2Mat);
  block6.name = 'block';
  block6.position.set(-1.3787, 0.4763, 0);
  block6.rotation.set(0, deg(-1.1099), deg(0.5614));
  root.add(block6);
  const block7 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4632, 0.2925, 0.5839), 0.02, 7), stoneMat);
  block7.name = 'block';
  block7.position.set(-1.0133, 0.4763, 0);
  block7.rotation.set(0, deg(-0.049), deg(-0.0029));
  root.add(block7);
  const block8 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6826, 0.2925, 0.595), 0.02, 8), stoneMat);
  block8.name = 'block';
  block8.position.set(-0.4154, 0.4763, 0);
  block8.rotation.set(0, deg(-0.1016), deg(0.0866));
  root.add(block8);
  const block9 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.463, 0.2925, 0.5935), 0.02, 9), stoneMat);
  block9.name = 'block';
  block9.position.set(0.1824, 0.4763, 0);
  block9.rotation.set(0, deg(0.1023), deg(-0.3771));
  root.add(block9);
  const block10 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.7284, 0.2925, 0.6248), 0.02, 10), stone2Mat);
  block10.name = 'block';
  block10.position.set(0.8031, 0.4763, 0);
  block10.rotation.set(0, deg(-1.1092), deg(-0.4251));
  root.add(block10);
  const block11 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.2952, 0.2925, 0.612), 0.02, 11), stoneMat);
  block11.name = 'block';
  block11.position.set(1.3399, 0.4763, 0);
  block11.rotation.set(0, deg(-0.7598), deg(0.1005));
  root.add(block11);
  const block12 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4629, 0.2925, 0.6057), 0.02, 12), stoneMat);
  block12.name = 'block';
  block12.position.set(-1.2561, 0.7938, 0);
  block12.rotation.set(0, deg(0.6504), deg(-0.1738));
  root.add(block12);
  const block13 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.7103, 0.2925, 0.5877), 0.02, 13), stone2Mat);
  block13.name = 'block';
  block13.position.set(-0.6445, 0.7938, 0);
  block13.rotation.set(0, deg(0.1548), deg(0.6535));
  root.add(block13);
  const block14 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.7416, 0.2925, 0.6179), 0.02, 14), stoneMat);
  block14.name = 'block';
  block14.position.set(0.1064, 0.7938, 0);
  block14.rotation.set(0, deg(-0.5181), deg(0.161));
  root.add(block14);
  const block15 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.5061, 0.2925, 0.6184), 0.02, 15), stone2Mat);
  block15.name = 'block';
  block15.position.set(0.7553, 0.7938, 0);
  block15.rotation.set(0, deg(-0.5735), deg(0.6759));
  root.add(block15);
  const block16 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4542, 0.2925, 0.612), 0.02, 16), stone2Mat);
  block16.name = 'block';
  block16.position.set(1.2604, 0.7938, 0);
  block16.rotation.set(0, deg(-0.7038), deg(0.7416));
  root.add(block16);
  const block17 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.2483, 0.2925, 0.6257), 0.02, 17), stone2Mat);
  block17.name = 'block';
  block17.position.set(-1.3634, 1.1113, 0);
  block17.rotation.set(0, deg(-0.2758), deg(0.1835));
  root.add(block17);
  const block18 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.5035, 0.2925, 0.6316), 0.02, 18), stoneMat);
  block18.name = 'block';
  block18.position.set(-0.9625, 1.1113, 0);
  block18.rotation.set(0, deg(0.2628), deg(0.6122));
  root.add(block18);
  const block19 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4123, 0.2925, 0.638), 0.02, 19), stone2Mat);
  block19.name = 'block';
  block19.position.set(-0.4796, 1.1113, 0);
  block19.rotation.set(0, deg(0.0413), deg(-0.6989));
  root.add(block19);
  const block20 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.7444, 0.2925, 0.6186), 0.02, 20), stone2Mat);
  block20.name = 'block';
  block20.position.set(0.1238, 1.1113, 0);
  block20.rotation.set(0, deg(0.1827), deg(-0.3459));
  root.add(block20);
  const block21 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6327, 0.2925, 0.615), 0.02, 21), stone2Mat);
  block21.name = 'block';
  block21.position.set(0.8373, 1.1113, 0);
  block21.rotation.set(0, deg(-0.5608), deg(0.5673));
  root.add(block21);
  const block22 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.3088, 0.2925, 0.612), 0.02, 22), stone2Mat);
  block22.name = 'block';
  block22.position.set(1.3331, 1.1113, 0);
  block22.rotation.set(0, deg(1.1414), deg(-0.0016));
  root.add(block22);
  const capstone = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.875, 0.13, 0.712), 0.012, 23), stone2Mat);
  capstone.name = 'capstone';
  capstone.position.set(-1.0525, 1.335, 0.0089);
  capstone.rotation.set(0, 0, deg(-0.0245));
  root.add(capstone);
  const capstone2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.8076, 0.13, 0.712), 0.012, 24), stone2Mat);
  capstone2.name = 'capstone';
  capstone2.position.set(-0.1913, 1.335, -0.01);
  capstone2.rotation.set(0, 0, deg(-0.3341));
  root.add(capstone2);
  const capstone3 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6019, 0.13, 0.712), 0.012, 25), stone2Mat);
  capstone3.name = 'capstone';
  capstone3.position.set(0.5335, 1.335, 0.0138);
  capstone3.rotation.set(0, 0, deg(0.5904));
  root.add(capstone3);
  const capstone4 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6356, 0.13, 0.712), 0.012, 26), stone2Mat);
  capstone4.name = 'capstone';
  capstone4.position.set(1.1722, 1.335, -0.0122);
  capstone4.rotation.set(0, 0, deg(0.0443));
  root.add(capstone4);
  const moss = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.2195, 0), 0.0263, 27), mossMat);
  moss.name = 'moss';
  moss.position.set(-0.0293, 1.3671, -0.0059);
  moss.scale.set(1.4, 0.35, 1.1);
  root.add(moss);
  const moss2 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.1649, 0), 0.0198, 28), mossMat);
  moss2.name = 'moss';
  moss2.position.set(0.8754, 1.3753, -0.1108);
  moss2.scale.set(1.4, 0.35, 1.1);
  root.add(moss2);
  const moss3 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.2043, 0), 0.0245, 29), mossMat);
  moss3.name = 'moss';
  moss3.position.set(-0.4244, 0.1306, 0.326);
  moss3.scale.set(1.3, 0.6, 0.8);
  root.add(moss3);

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

export default createStoneWall;
```

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