# Warp Pipe

> A chunky green warp pipe in classic platformer style: a faceted body under a wider rim lip, glossy highlight strips and a dark hollow opening you can actually look into. Height and diameter snap to the grid, and the color can be changed for themed worlds.

![Warp Pipe preview](https://codels.download/m/warp-pipe.png)

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

## Facts

- Category: Game Kit › Platforms
- Size (W × H × D): 2.00 × 2.00 × 2.00 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 408 · Meshes: 7 · Materials: 3
- License: CC0-1.0 (Codels built-in)
- Tags: pipe, tube, cartoon, low-poly, retro, stylized, party-game, platformer, landmark, obstacle, platform, plastic, round, tall, game-ready, mobile-friendly, parametric, color-green, size-medium, poly-low
- Page: https://codels.download/models/warp-pipe

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `height` | number | 1 – 6 | 2 | 2 |
| `diameter` | int | 1 – 4 | 2 | 2 |
| `color` | color | #rrggbb | #38b54a | #38b54a |

## Parts

- body (cylinder · pipe)
- lip (lathe · pipe)
- opening (lathe · inside)
- shineBody1 (box · shine)
- shineLip1 (box · shine)
- shineBody2 (box · shine)
- shineLip2 (box · shine)

## How to use

Save the code below as `warp-pipe.js`, then:

```js
import { createWarpPipe } from './warp-pipe.js';
const model = createWarpPipe();
scene.add(model);
```

## Code

```js
/**
 * Warp Pipe — Codels 3D model library (https://codels.download/models/warp-pipe)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 408 · Size (W × H × D): 2.00 × 2.00 × 2.00 m
 *
 * Usage:
 *   import { createWarpPipe } from './warp-pipe.js';
 *   
 *   const model = createWarpPipe();
 *   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 createWarpPipe() {
  const root = new THREE.Group();
  root.name = 'WarpPipe';

  // Materials
  const pipeMat = new THREE.MeshStandardMaterial({ name: 'pipe', color: 0x38b54a, roughness: 0.35, flatShading: true });
  const shineMat = new THREE.MeshStandardMaterial({ name: 'shine', color: 0x9cdaa5, roughness: 0.3, flatShading: true });
  const insideMat = new THREE.MeshStandardMaterial({ name: 'inside', color: 0x0f3116, roughness: 0.9, flatShading: true });

  // Parts
  const body = new THREE.Mesh(new THREE.CylinderGeometry(0.86, 0.86, 1.56, 20, 1, true), pipeMat);
  body.name = 'body';
  body.position.set(0, 0.78, 0);
  root.add(body);
  const lip = new THREE.Mesh(lathe([[0.84, 1.5], [1, 1.5], [1, 1.95], [0.95, 2], [0.77, 2], [0.74, 1.97], [0.74, 1.82]], 20), pipeMat);
  lip.name = 'lip';
  root.add(lip);
  const opening = new THREE.Mesh(lathe([[0.74, 1.82], [0.74, 0.6], [0, 0.6]], 20), insideMat);
  opening.name = 'opening';
  root.add(opening);
  const shineBody1 = new THREE.Mesh(new THREE.BoxGeometry(0.16, 1.38, 0.02), shineMat);
  shineBody1.name = 'shineBody1';
  shineBody1.position.set(-0.3874, 0.75, 0.7604);
  shineBody1.rotation.set(0, deg(-27), 0);
  root.add(shineBody1);
  const shineLip1 = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.37, 0.02), shineMat);
  shineLip1.name = 'shineLip1';
  shineLip1.position.set(-0.4502, 1.725, 0.8836);
  shineLip1.rotation.set(0, deg(-27), 0);
  root.add(shineLip1);
  const shineBody2 = new THREE.Mesh(new THREE.BoxGeometry(0.06, 1.38, 0.02), shineMat);
  shineBody2.name = 'shineBody2';
  shineBody2.position.set(-0.1335, 0.75, 0.8429);
  shineBody2.rotation.set(0, deg(-9), 0);
  root.add(shineBody2);
  const shineLip2 = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.37, 0.02), shineMat);
  shineLip2.name = 'shineLip2';
  shineLip2.position.set(-0.1551, 1.725, 0.9795);
  shineLip2.rotation.set(0, deg(-9), 0);
  root.add(shineLip2);

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

export default createWarpPipe;
```

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