# Teleporter Pad

> A circular sci-fi teleporter pad: a stepped white platform with a dark transmission disc of concentric glowing rings and a hex emitter, ringed by curved focusing pylons tipped with glowing crystals, with a translucent column of energy and floating rings when active. Set the diameter, pylon count and glow color or switch it off — perfect for warp points, level exits and fast travel in sci-fi games.

![Teleporter Pad preview](https://codels.download/m/teleporter-pad.png)

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

## Facts

- Category: Sci-Fi › Sci-Fi Props
- Size (W × H × D): 3.64 × 2.71 × 3.93 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 1,448 · Meshes: 48 · Materials: 8
- License: CC0-1.0 (Codels built-in)
- Tags: pad, portal, teleporter, low-poly, stylized, sci-fi, space, adventure, platformer, space-shooter, checkpoint, goal, interactable, platform, prop, energy, metal, round, symmetric, emissive, game-ready, mobile-friendly, parametric, transparent-parts, color-blue, color-cyan, color-gray, size-large, poly-low
- Page: https://codels.download/models/teleporter-pad

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `diameter` | number | 2 – 4 | 3 | 3 |
| `pylons` | int | 3 – 6 | 4 | 4 |
| `glowColor` | color | #rrggbb | #4fd8ff | #4fd8ff |
| `powered` | boolean | true \| false | true | true |

## Parts

- platform (lathe · shell)
- transmissionDisc (cylinder · dark)
- discRim (cylinder · dark)
- ring1 (ring · glow)
- ring2 (ring · glowDim)
- ring3 (ring · glow)
- emitter (cylinder · glow)
- emitterCore (cylinder · dark)
- step (box · shell)
- stepLight (box · glow)
- pylon1 (group)
  - foot (box · dark)
  - fin (extrude · shell)
  - spine (extrude · dark)
  - strip (box · glow)
  - crystal (octahedron · crystal)
  - crystalMount (cylinder · metal)
- pylon2 (group)
  - foot (box · dark)
  - fin (extrude · shell)
  - spine (extrude · dark)
  - strip (box · glow)
  - crystal (octahedron · crystal)
  - crystalMount (cylinder · metal)
- pylon3 (group)
  - foot (box · dark)
  - fin (extrude · shell)
  - spine (extrude · dark)
  - strip (box · glow)
  - crystal (octahedron · crystal)
  - crystalMount (cylinder · metal)
- pylon4 (group)
  - foot (box · dark)
  - fin (extrude · shell)
  - spine (extrude · dark)
  - strip (box · glow)
  - crystal (octahedron · crystal)
  - crystalMount (cylinder · metal)
- energyColumn (cylinder · beam)
- floatRing1 (torus · ringLight)

## How to use

Save the code below as `teleporter-pad.js`, then:

```js
import { createTeleporterPad } from './teleporter-pad.js';
const model = createTeleporterPad();
scene.add(model);
```

## Code

```js
/**
 * Teleporter Pad — Codels 3D model library (https://codels.download/models/teleporter-pad)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,448 · Size (W × H × D): 3.64 × 2.71 × 3.93 m
 *
 * Usage:
 *   import { createTeleporterPad } from './teleporter-pad.js';
 *   
 *   const model = createTeleporterPad();
 *   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);
}

// Extrude a 2D outline along Z (centered). bevel = [thickness, size, segments].
function extrude(outline, depth, holes = [], bevel = null) {
  const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
  for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
  const options = bevel
    ? { depth, bevelEnabled: true, bevelThickness: bevel[0], bevelSize: bevel[1], bevelSegments: bevel[2] }
    : { depth, bevelEnabled: false };
  return new THREE.ExtrudeGeometry(shape, options).translate(0, 0, -depth / 2);
}

export function createTeleporterPad() {
  const root = new THREE.Group();
  root.name = 'TeleporterPad';

  // Materials
  const shellMat = new THREE.MeshStandardMaterial({ name: 'shell', color: 0xd0d6de, roughness: 0.45, metalness: 0.3, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2b3038, roughness: 0.55, metalness: 0.4, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x7d858f, roughness: 0.4, metalness: 0.6, flatShading: true });
  const glowMat = new THREE.MeshStandardMaterial({ name: 'glow', color: 0x4fd8ff, roughness: 0.4, emissive: 0x4fd8ff, emissiveIntensity: 1.3, flatShading: true });
  const glowDimMat = new THREE.MeshStandardMaterial({ name: 'glowDim', color: 0x3a8fac, roughness: 0.4, emissive: 0x4fd8ff, emissiveIntensity: 0.6, flatShading: true });
  const crystalMat = new THREE.MeshStandardMaterial({ name: 'crystal', color: 0x95e8ff, roughness: 0.2, emissive: 0x4fd8ff, emissiveIntensity: 1.2, flatShading: true });
  const beamMat = new THREE.MeshStandardMaterial({ name: 'beam', color: 0x4fd8ff, roughness: 0.3, emissive: 0x4fd8ff, emissiveIntensity: 0.6, transparent: true, opacity: 0.18, flatShading: true });
  const ringLightMat = new THREE.MeshStandardMaterial({ name: 'ringLight', color: 0xa7ecff, roughness: 0.3, emissive: 0x84e4ff, emissiveIntensity: 1.2, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.03, 0.02, 0.16);
  const boxGeo2 = new THREE.BoxGeometry(0.4, 0.12, 0.34);
  const extrudeGeo = extrude([[-0.16, 0], [0.14, 0], [0.1, 0.85], [0.3, 1.45], [0.4, 1.66], [0.26, 1.72], [-0.04, 1.25], [-0.12, 0.85]], 0.18);
  const extrudeGeo2 = extrude([[-0.074, 0.14], [0.046, 0.14], [0.03, 0.871], [0.11, 1.387], [0.15, 1.5676], [0.094, 1.6192], [-0.026, 1.215], [-0.058, 0.871]], 0.22);
  const boxGeo3 = new THREE.BoxGeometry(0.03, 0.62, 0.1);
  const octahedronGeo = new THREE.OctahedronGeometry(0.14, 0);
  const cylinderGeo = new THREE.CylinderGeometry(0.07, 0.09, 0.1, 6);

  // Parts
  const platform = new THREE.Mesh(lathe([[0, 0], [1.82, 0], [1.8, 0.06], [1.68, 0.16], [1.55, 0.16], [1.52, 0.28], [0, 0.28]], 20), shellMat);
  platform.name = 'platform';
  root.add(platform);
  const transmissionDisc = new THREE.Mesh(new THREE.CylinderGeometry(1.44, 1.46, 0.03, 20), darkMat);
  transmissionDisc.name = 'transmissionDisc';
  transmissionDisc.position.set(0, 0.29, 0);
  root.add(transmissionDisc);
  const discRim = new THREE.Mesh(new THREE.CylinderGeometry(1.54, 1.54, 0.04, 20, 1, true), darkMat);
  discRim.name = 'discRim';
  discRim.position.set(0, 0.29, 0);
  root.add(discRim);
  const ring1 = new THREE.Mesh(new THREE.RingGeometry(1.26, 1.38, 20), glowMat);
  ring1.name = 'ring1';
  ring1.position.set(0, 0.31, 0);
  ring1.rotation.set(deg(-90), 0, 0);
  root.add(ring1);
  const ring2 = new THREE.Mesh(new THREE.RingGeometry(0.84, 0.93, 20), glowDimMat);
  ring2.name = 'ring2';
  ring2.position.set(0, 0.31, 0);
  ring2.rotation.set(deg(-90), 0, 0);
  root.add(ring2);
  const ring3 = new THREE.Mesh(new THREE.RingGeometry(0.45, 0.525, 20), glowMat);
  ring3.name = 'ring3';
  ring3.position.set(0, 0.31, 0);
  ring3.rotation.set(deg(-90), 0, 0);
  root.add(ring3);
  const emitter = new THREE.Mesh(new THREE.CylinderGeometry(0.27, 0.3, 0.05, 6), glowMat);
  emitter.name = 'emitter';
  emitter.position.set(0, 0.325, 0);
  root.add(emitter);
  const emitterCore = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.15, 0.06, 6), darkMat);
  emitterCore.name = 'emitterCore';
  emitterCore.position.set(0, 0.34, 0);
  root.add(emitterCore);
  const box9 = new THREE.Mesh(boxGeo, darkMat);
  box9.position.set(0.4975, 0.165, 1.5312);
  box9.rotation.set(0, deg(18), 0);
  root.add(box9);
  const box10 = new THREE.Mesh(boxGeo, darkMat);
  box10.position.set(1.3025, 0.165, 0.9463);
  box10.rotation.set(0, deg(54), 0);
  root.add(box10);
  const box11 = new THREE.Mesh(boxGeo, darkMat);
  box11.position.set(1.61, 0.165, 0);
  box11.rotation.set(0, deg(90), 0);
  root.add(box11);
  const box12 = new THREE.Mesh(boxGeo, darkMat);
  box12.position.set(1.3025, 0.165, -0.9463);
  box12.rotation.set(0, deg(126), 0);
  root.add(box12);
  const box13 = new THREE.Mesh(boxGeo, darkMat);
  box13.position.set(0.4975, 0.165, -1.5312);
  box13.rotation.set(0, deg(162), 0);
  root.add(box13);
  const box14 = new THREE.Mesh(boxGeo, darkMat);
  box14.position.set(-0.4975, 0.165, -1.5312);
  box14.rotation.set(0, deg(198), 0);
  root.add(box14);
  const box15 = new THREE.Mesh(boxGeo, darkMat);
  box15.position.set(-1.3025, 0.165, -0.9463);
  box15.rotation.set(0, deg(234), 0);
  root.add(box15);
  const box16 = new THREE.Mesh(boxGeo, darkMat);
  box16.position.set(-1.61, 0.165, 0);
  box16.rotation.set(0, deg(270), 0);
  root.add(box16);
  const box17 = new THREE.Mesh(boxGeo, darkMat);
  box17.position.set(-1.3025, 0.165, 0.9463);
  box17.rotation.set(0, deg(306), 0);
  root.add(box17);
  const box18 = new THREE.Mesh(boxGeo, darkMat);
  box18.position.set(-0.4975, 0.165, 1.5312);
  box18.rotation.set(0, deg(342), 0);
  root.add(box18);
  const step = new THREE.Mesh(new THREE.BoxGeometry(0.9, 0.14, 0.36), shellMat);
  step.name = 'step';
  step.position.set(0, 0.07, 1.9);
  root.add(step);
  const stepLight = new THREE.Mesh(new THREE.BoxGeometry(0.7, 0.02, 0.04), glowMat);
  stepLight.name = 'stepLight';
  stepLight.position.set(0, 0.13, 2.09);
  root.add(stepLight);
  const pylon1 = new THREE.Group();
  pylon1.name = 'pylon1';
  pylon1.position.set(1.1314, 0.16, 1.1314);
  pylon1.rotation.set(0, deg(135), 0);
  root.add(pylon1);
  const foot = new THREE.Mesh(boxGeo2, darkMat);
  foot.name = 'foot';
  foot.position.set(0, 0.06, 0);
  pylon1.add(foot);
  const fin = new THREE.Mesh(extrudeGeo, shellMat);
  fin.name = 'fin';
  fin.position.set(0, 0.1, 0);
  pylon1.add(fin);
  const spine = new THREE.Mesh(extrudeGeo2, darkMat);
  spine.name = 'spine';
  spine.position.set(0, 0.08, 0);
  pylon1.add(spine);
  const strip = new THREE.Mesh(boxGeo3, glowMat);
  strip.name = 'strip';
  strip.position.set(0.115, 0.55, 0);
  strip.rotation.set(0, 0, deg(2.7));
  pylon1.add(strip);
  const crystal = new THREE.Mesh(octahedronGeo, crystalMat);
  crystal.name = 'crystal';
  crystal.position.set(0.47, 1.8, 0);
  crystal.rotation.set(0, 0, deg(-62));
  crystal.scale.set(1, 1.7, 1);
  pylon1.add(crystal);
  const crystalMount = new THREE.Mesh(cylinderGeo, metalMat);
  crystalMount.name = 'crystalMount';
  crystalMount.position.set(0.36, 1.74, 0);
  crystalMount.rotation.set(0, 0, deg(-62));
  pylon1.add(crystalMount);
  const pylon2 = new THREE.Group();
  pylon2.name = 'pylon2';
  pylon2.position.set(1.1314, 0.16, -1.1314);
  pylon2.rotation.set(0, deg(225), 0);
  root.add(pylon2);
  const foot2 = new THREE.Mesh(boxGeo2, darkMat);
  foot2.name = 'foot';
  foot2.position.set(0, 0.06, 0);
  pylon2.add(foot2);
  const fin2 = new THREE.Mesh(extrudeGeo, shellMat);
  fin2.name = 'fin';
  fin2.position.set(0, 0.1, 0);
  pylon2.add(fin2);
  const spine2 = new THREE.Mesh(extrudeGeo2, darkMat);
  spine2.name = 'spine';
  spine2.position.set(0, 0.08, 0);
  pylon2.add(spine2);
  const strip2 = new THREE.Mesh(boxGeo3, glowMat);
  strip2.name = 'strip';
  strip2.position.set(0.115, 0.55, 0);
  strip2.rotation.set(0, 0, deg(2.7));
  pylon2.add(strip2);
  const crystal2 = new THREE.Mesh(octahedronGeo, crystalMat);
  crystal2.name = 'crystal';
  crystal2.position.set(0.47, 1.8, 0);
  crystal2.rotation.set(0, 0, deg(-62));
  crystal2.scale.set(1, 1.7, 1);
  pylon2.add(crystal2);
  const crystalMount2 = new THREE.Mesh(cylinderGeo, metalMat);
  crystalMount2.name = 'crystalMount';
  crystalMount2.position.set(0.36, 1.74, 0);
  crystalMount2.rotation.set(0, 0, deg(-62));
  pylon2.add(crystalMount2);
  const pylon3 = new THREE.Group();
  pylon3.name = 'pylon3';
  pylon3.position.set(-1.1314, 0.16, -1.1314);
  pylon3.rotation.set(0, deg(315), 0);
  root.add(pylon3);
  const foot3 = new THREE.Mesh(boxGeo2, darkMat);
  foot3.name = 'foot';
  foot3.position.set(0, 0.06, 0);
  pylon3.add(foot3);
  const fin3 = new THREE.Mesh(extrudeGeo, shellMat);
  fin3.name = 'fin';
  fin3.position.set(0, 0.1, 0);
  pylon3.add(fin3);
  const spine3 = new THREE.Mesh(extrudeGeo2, darkMat);
  spine3.name = 'spine';
  spine3.position.set(0, 0.08, 0);
  pylon3.add(spine3);
  const strip3 = new THREE.Mesh(boxGeo3, glowMat);
  strip3.name = 'strip';
  strip3.position.set(0.115, 0.55, 0);
  strip3.rotation.set(0, 0, deg(2.7));
  pylon3.add(strip3);
  const crystal3 = new THREE.Mesh(octahedronGeo, crystalMat);
  crystal3.name = 'crystal';
  crystal3.position.set(0.47, 1.8, 0);
  crystal3.rotation.set(0, 0, deg(-62));
  crystal3.scale.set(1, 1.7, 1);
  pylon3.add(crystal3);
  const crystalMount3 = new THREE.Mesh(cylinderGeo, metalMat);
  crystalMount3.name = 'crystalMount';
  crystalMount3.position.set(0.36, 1.74, 0);
  crystalMount3.rotation.set(0, 0, deg(-62));
  pylon3.add(crystalMount3);
  const pylon4 = new THREE.Group();
  pylon4.name = 'pylon4';
  pylon4.position.set(-1.1314, 0.16, 1.1314);
  pylon4.rotation.set(0, deg(405), 0);
  root.add(pylon4);
  const foot4 = new THREE.Mesh(boxGeo2, darkMat);
  foot4.name = 'foot';
  foot4.position.set(0, 0.06, 0);
  pylon4.add(foot4);
  const fin4 = new THREE.Mesh(extrudeGeo, shellMat);
  fin4.name = 'fin';
  fin4.position.set(0, 0.1, 0);
  pylon4.add(fin4);
  const spine4 = new THREE.Mesh(extrudeGeo2, darkMat);
  spine4.name = 'spine';
  spine4.position.set(0, 0.08, 0);
  pylon4.add(spine4);
  const strip4 = new THREE.Mesh(boxGeo3, glowMat);
  strip4.name = 'strip';
  strip4.position.set(0.115, 0.55, 0);
  strip4.rotation.set(0, 0, deg(2.7));
  pylon4.add(strip4);
  const crystal4 = new THREE.Mesh(octahedronGeo, crystalMat);
  crystal4.name = 'crystal';
  crystal4.position.set(0.47, 1.8, 0);
  crystal4.rotation.set(0, 0, deg(-62));
  crystal4.scale.set(1, 1.7, 1);
  pylon4.add(crystal4);
  const crystalMount4 = new THREE.Mesh(cylinderGeo, metalMat);
  crystalMount4.name = 'crystalMount';
  crystalMount4.position.set(0.36, 1.74, 0);
  crystalMount4.rotation.set(0, 0, deg(-62));
  pylon4.add(crystalMount4);
  const energyColumn = new THREE.Mesh(new THREE.CylinderGeometry(1.23, 1.23, 2.4, 20, 1, true), beamMat);
  energyColumn.name = 'energyColumn';
  energyColumn.position.set(0, 1.51, 0);
  root.add(energyColumn);
  const floatRing1 = new THREE.Mesh(new THREE.TorusGeometry(1.17, 0.018, 3, 16), ringLightMat);
  floatRing1.name = 'floatRing1';
  floatRing1.position.set(0, 0.98, 0);
  floatRing1.rotation.set(deg(90), 0, 0);
  root.add(floatRing1);
  const floatRing2 = new THREE.Mesh(new THREE.TorusGeometry(1.08, 0.018, 3, 16), ringLightMat);
  floatRing2.name = 'floatRing2';
  floatRing2.position.set(0, 1.63, 0);
  floatRing2.rotation.set(deg(90), 0, 0);
  root.add(floatRing2);
  const floatRing3 = new THREE.Mesh(new THREE.TorusGeometry(0.99, 0.018, 3, 16), ringLightMat);
  floatRing3.name = 'floatRing3';
  floatRing3.position.set(0, 2.28, 0);
  floatRing3.rotation.set(deg(90), 0, 0);
  root.add(floatRing3);

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

export default createTeleporterPad;
```

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