# Trophy

> A shiny low-poly trophy on a two-tier base with an engraved plaque. Pick a classic two-handled loving cup with a turned stem, a beveled star on a column, or a victory figure raising a laurel wreath, in gold, silver or bronze finish. Scale it from a desk award to a grand championship cup — ideal for reward screens, collectibles, trophy shelves, sports clubs and game-over podiums.

![Trophy preview](https://codels.download/m/trophy.png)

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

## Facts

- Category: Props › Decor
- Size (W × H × D): 0.33 × 0.39 × 0.22 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 816 · Meshes: 10 · Materials: 6
- License: CC0-1.0 (Codels built-in)
- Tags: cup, reward, star, trophy, cartoon, low-poly, stylized, modern, sports, interior, party-game, racing-game, sports-game, collectible, decoration, goal, gold, metal, symmetric, tall, mobile-friendly, parametric, color-brown, color-orange, size-small, poly-low
- Page: https://codels.download/models/trophy

## Files

| Format | URL |
|---|---|
| three.js ES module (`createTrophy()`) | https://codels.download/m/trophy.js |
| React Three Fiber component (`<Trophy />`) | https://codels.download/m/trophy.jsx |
| Instancing module (`createTrophyInstances(count, place)`, one draw call per material) | https://codels.download/m/trophy.instanced.js |
| Standalone HTML demo | https://codels.download/m/trophy.html |
| glTF binary | https://codels.download/m/trophy.glb |
| glTF binary, Meshopt-compressed (2–3× smaller; GLTFLoader needs `setMeshoptDecoder(MeshoptDecoder)`) | https://codels.download/m/trophy.glb?compress=meshopt |
| glTF JSON | https://codels.download/m/trophy.gltf |
| OBJ (vertex colors) + MTL | https://codels.download/m/trophy.obj · https://codels.download/m/trophy.mtl |
| STL | https://codels.download/m/trophy.stl |
| CodelSpec JSON | https://codels.download/m/trophy.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 | cup \| star \| figure | cup | cup |
| `finish` | select | gold \| silver \| bronze | gold | gold |
| `base` | color | #rrggbb | #3a2a22 | #3a2a22 |
| `height` | number | 0.25 – 0.8 | 0.42 | 0.42 |

## Parts

- trophy (group)
  - baseLower (box · base)
  - baseTrim (box · baseTrim)
  - baseUpper (box · base)
  - plaque (box · plaque)
  - engraving (box · ink)
  - engraving (box · ink)
  - cup (lathe · metal)
  - cupBand (lathe · metalDark)
  - handle (tube · metal)
  - handle (tube · metal)

## How to use

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

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

## Code

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

// 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);
}

// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
  const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
  return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}

export function createTrophy() {
  const root = new THREE.Group();
  root.name = 'Trophy';

  // Materials
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0xe2b13c, roughness: 0.28, metalness: 0.6, flatShading: true });
  const metalDarkMat = new THREE.MeshStandardMaterial({ name: 'metalDark', color: 0x9e7c2a, roughness: 0.35, metalness: 0.6, flatShading: true });
  const baseMat = new THREE.MeshStandardMaterial({ name: 'base', color: 0x3a2a22, roughness: 0.55, flatShading: true });
  const baseTrimMat = new THREE.MeshStandardMaterial({ name: 'baseTrim', color: 0x5d504a, roughness: 0.55, flatShading: true });
  const plaqueMat = new THREE.MeshStandardMaterial({ name: 'plaque', color: 0xd9c48a, roughness: 0.35, metalness: 0.5, flatShading: true });
  const inkMat = new THREE.MeshStandardMaterial({ name: 'ink', color: 0x3b3226, roughness: 0.8, flatShading: true });

  // Parts
  const trophy = new THREE.Group();
  trophy.name = 'trophy';
  root.add(trophy);
  const baseLower = new THREE.Mesh(new THREE.BoxGeometry(0.17, 0.05, 0.17), baseMat);
  baseLower.name = 'baseLower';
  baseLower.position.set(0, 0.025, 0);
  trophy.add(baseLower);
  const baseTrim = new THREE.Mesh(new THREE.BoxGeometry(0.176, 0.008, 0.176), baseTrimMat);
  baseTrim.name = 'baseTrim';
  baseTrim.position.set(0, 0.054, 0);
  trophy.add(baseTrim);
  const baseUpper = new THREE.Mesh(new THREE.BoxGeometry(0.13, 0.045, 0.13), baseMat);
  baseUpper.name = 'baseUpper';
  baseUpper.position.set(0, 0.0805, 0);
  trophy.add(baseUpper);
  const plaque = new THREE.Mesh(new THREE.BoxGeometry(0.09, 0.03, 0.004), plaqueMat);
  plaque.name = 'plaque';
  plaque.position.set(0, 0.025, 0.086);
  trophy.add(plaque);
  const engraving = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.004, 0.002), inkMat);
  engraving.name = 'engraving';
  engraving.position.set(0, 0.031, 0.0885);
  trophy.add(engraving);
  const engraving2 = new THREE.Mesh(new THREE.BoxGeometry(0.04, 0.004, 0.002), inkMat);
  engraving2.name = 'engraving';
  engraving2.position.set(0, 0.019, 0.0885);
  trophy.add(engraving2);
  const cup = new THREE.Mesh(lathe([[0, 0], [0.058, 0], [0.058, 0.012], [0.046, 0.02], [0.022, 0.03], [0.015, 0.06], [0.024, 0.08], [0.014, 0.1], [0.02, 0.115], [0.05, 0.13], [0.082, 0.165], [0.097, 0.215], [0.1, 0.265], [0.109, 0.282], [0.103, 0.288], [0.093, 0.276], [0.087, 0.215], [0.07, 0.17], [0, 0.148]], 12), metalMat);
  cup.name = 'cup';
  cup.position.set(0, 0.103, 0);
  trophy.add(cup);
  const cupBand = new THREE.Mesh(lathe([[0.0985, 0.236], [0.1015, 0.24], [0.1015, 0.248], [0.0995, 0.252]], 12), metalDarkMat);
  cupBand.name = 'cupBand';
  cupBand.position.set(0, 0.103, 0);
  trophy.add(cupBand);
  const handle = new THREE.Mesh(tube([[0.094, 0.361, 0], [0.135, 0.371, 0], [0.158, 0.338, 0], [0.142, 0.293, 0], [0.085, 0.275, 0]], 0.009, 12, 5), metalMat);
  handle.name = 'handle';
  trophy.add(handle);
  const handle2 = new THREE.Mesh(tube([[-0.094, 0.361, 0], [-0.135, 0.371, 0], [-0.158, 0.338, 0], [-0.142, 0.293, 0], [-0.085, 0.275, 0]], 0.009, 12, 5), metalMat);
  handle2.name = 'handle';
  trophy.add(handle2);

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

export default createTrophy;
```

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