# Road Sign

> A European-style traffic sign on a galvanized post with an aluminum back and clamp brackets. Pick the type and the colors follow it: red-bordered yield triangle, round speed limit with a settable number, red no-entry disc, blue pedestrian crossing square or blue parking sign. Set the speed and height to sign streets, junctions and parking lots in city builders and driving games.

![Road Sign preview](https://codels.download/m/road-sign.png)

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

## Facts

- Category: Urban & Street › Traffic
- Size (W × H × D): 0.60 × 2.56 × 0.20 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 302 · Meshes: 21 · Materials: 7
- License: CC0-1.0 (Codels built-in)
- Tags: sign, traffic-sign, low-poly, stylized, modern, city, road, city-builder, racing-game, prop, signage, street-furniture, metal, tall, game-ready, instancing-friendly, mobile-friendly, parametric, color-gray, size-medium, poly-low
- Page: https://codels.download/models/road-sign

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `type` | select | yield \| speed-limit \| no-entry \| pedestrian \| parking | speed-limit | speed-limit |
| `speed` | number | 10 – 130 | 50 | 50 |
| `height` | number | 1.8 – 3 | 2.2 | 2.2 |

## Parts

- footing (cylinder · concrete)
- post (cylinder · post)
- postCap (sphere · post)
- bracket (box · dark)
- clamp (box · dark)
- bracket (box · dark)
- clamp (box · dark)
- sign (group)
  - signBack (cylinder · back)
  - signFace (circle · red)
  - signInner (circle · white)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)
  - paint (plane · black)

## How to use

Save the code below as `road-sign.js`, then:

```js
import { createRoadSign } from './road-sign.js';
const model = createRoadSign();
scene.add(model);
```

## Code

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

const deg = THREE.MathUtils.degToRad;

export function createRoadSign() {
  const root = new THREE.Group();
  root.name = 'RoadSign';

  // Materials
  const postMat = new THREE.MeshStandardMaterial({ name: 'post', color: 0x9aa1a6, roughness: 0.45, metalness: 0.6, flatShading: true });
  const concreteMat = new THREE.MeshStandardMaterial({ name: 'concrete', color: 0x9c998f, roughness: 0.95, flatShading: true });
  const backMat = new THREE.MeshStandardMaterial({ name: 'back', color: 0x8e949a, roughness: 0.5, metalness: 0.5, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x3a3f44, roughness: 0.6, metalness: 0.4, flatShading: true });
  const whiteMat = new THREE.MeshStandardMaterial({ name: 'white', color: 0xf3f3ee, roughness: 0.45, flatShading: true });
  const redMat = new THREE.MeshStandardMaterial({ name: 'red', color: 0xc3161c, roughness: 0.45, flatShading: true });
  const blackMat = new THREE.MeshStandardMaterial({ name: 'black', color: 0x1c1d20, roughness: 0.5, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.1, 0.035, 0.03);
  const boxGeo2 = new THREE.BoxGeometry(0.075, 0.03, 0.016);
  const planeGeo = new THREE.PlaneGeometry(0.1064, 0.0323);
  const planeGeo2 = new THREE.PlaneGeometry(0.0323, 0.095);

  // Parts
  const footing = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.1, 0.06, 8), concreteMat);
  footing.name = 'footing';
  footing.position.set(0, 0.03, 0);
  root.add(footing);
  const post = new THREE.Mesh(new THREE.CylinderGeometry(0.03, 0.03, 2.38, 8), postMat);
  post.name = 'post';
  post.position.set(0, 1.25, 0);
  root.add(post);
  const postCap = new THREE.Mesh(new THREE.SphereGeometry(0.033, 8, 2, 0, Math.PI * 2, 0, Math.PI / 2), postMat);
  postCap.name = 'postCap';
  postCap.position.set(0, 2.44, 0);
  root.add(postCap);
  const bracket = new THREE.Mesh(boxGeo, darkMat);
  bracket.name = 'bracket';
  bracket.position.set(0, 2.11, 0.03);
  root.add(bracket);
  const clamp = new THREE.Mesh(boxGeo2, darkMat);
  clamp.name = 'clamp';
  clamp.position.set(0, 2.11, -0.035);
  root.add(clamp);
  const bracket2 = new THREE.Mesh(boxGeo, darkMat);
  bracket2.name = 'bracket';
  bracket2.position.set(0, 2.41, 0.03);
  root.add(bracket2);
  const clamp2 = new THREE.Mesh(boxGeo2, darkMat);
  clamp2.name = 'clamp';
  clamp2.position.set(0, 2.41, -0.035);
  root.add(clamp2);
  const sign = new THREE.Group();
  sign.name = 'sign';
  sign.position.set(0, 2.26, 0.045);
  root.add(sign);
  const signBack = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.3, 0.01, 24), backMat);
  signBack.name = 'signBack';
  signBack.position.set(0, 0, 0.0055);
  signBack.rotation.set(deg(90), 0, 0);
  sign.add(signBack);
  const signFace = new THREE.Mesh(new THREE.CircleGeometry(0.298, 24), redMat);
  signFace.name = 'signFace';
  signFace.position.set(0, 0, 0.0127);
  sign.add(signFace);
  const signInner = new THREE.Mesh(new THREE.CircleGeometry(0.225, 24), whiteMat);
  signInner.name = 'signInner';
  signInner.position.set(0, 0, 0.0139);
  sign.add(signInner);
  const paint = new THREE.Mesh(planeGeo, blackMat);
  paint.name = 'paint';
  paint.position.set(-0.0702, 0.0789, 0.0151);
  sign.add(paint);
  const paint2 = new THREE.Mesh(planeGeo2, blackMat);
  paint2.name = 'paint';
  paint2.position.set(-0.1073, 0.0475, 0.0151);
  sign.add(paint2);
  const paint3 = new THREE.Mesh(planeGeo, blackMat);
  paint3.name = 'paint';
  paint3.position.set(-0.0702, 0, 0.0151);
  sign.add(paint3);
  const paint4 = new THREE.Mesh(planeGeo2, blackMat);
  paint4.name = 'paint';
  paint4.position.set(-0.0332, -0.0475, 0.0151);
  sign.add(paint4);
  const paint5 = new THREE.Mesh(planeGeo, blackMat);
  paint5.name = 'paint';
  paint5.position.set(-0.0702, -0.0788, 0.0151);
  sign.add(paint5);
  const paint6 = new THREE.Mesh(planeGeo, blackMat);
  paint6.name = 'paint';
  paint6.position.set(0.0702, 0.0789, 0.0151);
  sign.add(paint6);
  const paint7 = new THREE.Mesh(planeGeo2, blackMat);
  paint7.name = 'paint';
  paint7.position.set(0.1073, 0.0475, 0.0151);
  sign.add(paint7);
  const paint8 = new THREE.Mesh(planeGeo2, blackMat);
  paint8.name = 'paint';
  paint8.position.set(0.1073, -0.0475, 0.0151);
  sign.add(paint8);
  const paint9 = new THREE.Mesh(planeGeo, blackMat);
  paint9.name = 'paint';
  paint9.position.set(0.0702, -0.0788, 0.0151);
  sign.add(paint9);
  const paint10 = new THREE.Mesh(planeGeo2, blackMat);
  paint10.name = 'paint';
  paint10.position.set(0.0332, -0.0475, 0.0151);
  sign.add(paint10);
  const paint11 = new THREE.Mesh(planeGeo2, blackMat);
  paint11.name = 'paint';
  paint11.position.set(0.0332, 0.0475, 0.0151);
  sign.add(paint11);

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

export default createRoadSign;
```

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