# Apple

> A juicy low-poly apple turned from a smooth lathe profile, with dimples at the top and bottom, a curved woody stem and a single leaf. Choose a red, green or golden variety; real-world size by default (about 8 cm), scalable up for oversized collectibles.

![Apple preview](https://codels.download/m/apple.png)

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

## Facts

- Category: Food & Drink › Fruits & Vegetables
- Size (W × H × D): 0.08 × 0.09 × 0.08 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 496 · Meshes: 3 · Materials: 3
- License: CC0-1.0 (Codels built-in)
- Tags: apple, fruit, cartoon, low-poly, stylized, farm, kitchen, farming-sim, rpg, survival, collectible, food, pickup, prop, organic, round, game-ready, instancing-friendly, mobile-friendly, parametric, color-red, size-tiny, poly-low
- Page: https://codels.download/models/apple

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `variety` | select | red \| green \| golden | red | red |
| `size` | number | 0.05 – 0.3 | 0.08 | 0.08 |
| `leaf` | boolean | true \| false | true | true |

## Parts

- apple (group)
  - body (lathe · skin)
  - stem (tube · stem)
  - leaf (extrude · leaf)

## How to use

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

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

## Code

```js
/**
 * Apple — Codels 3D model library (https://codels.download/models/apple)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 496 · Size (W × H × D): 0.08 × 0.09 × 0.08 m
 *
 * Usage:
 *   import { createApple } from './apple.js';
 *   
 *   const model = createApple();
 *   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);
}

// 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 createApple() {
  const root = new THREE.Group();
  root.name = 'Apple';

  // Materials
  const skinMat = new THREE.MeshStandardMaterial({ name: 'skin', color: 0xd42a2a, roughness: 0.45 });
  const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0x6b4527, roughness: 0.9, flatShading: true });
  const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x4f9a2e, roughness: 0.7, flatShading: true });

  // Parts
  const apple = new THREE.Group();
  apple.name = 'apple';
  apple.scale.setScalar(0.08);
  root.add(apple);
  const body = new THREE.Mesh(lathe([[0, 0.07], [0.08, 0.035], [0.18, 0], [0.3, 0.025], [0.4, 0.095], [0.47, 0.21], [0.5, 0.35], [0.495, 0.49], [0.46, 0.62], [0.39, 0.73], [0.29, 0.8], [0.18, 0.82], [0.09, 0.79], [0, 0.71]], 14), skinMat);
  body.name = 'body';
  apple.add(body);
  const stem = new THREE.Mesh(tube([[0, 0.68, 0], [0.01, 0.82, 0], [0.04, 0.95, 0.01], [0.08, 1.02, 0.02]], 0.028, 8, 5), stemMat);
  stem.name = 'stem';
  apple.add(stem);
  const leaf = new THREE.Mesh(extrude([[0, 0], [0.06, 0.0615], [0.12, 0.0986], [0.18, 0.1176], [0.24, 0.1176], [0.3, 0.0986], [0.36, 0.0615], [0.42, 0], [0.36, -0.0615], [0.3, -0.0986], [0.24, -0.1176], [0.18, -0.1176], [0.12, -0.0986], [0.06, -0.0615]], 0.012), leafMat);
  leaf.name = 'leaf';
  leaf.position.set(0.03, 0.86, 0.01);
  leaf.rotation.set(deg(-70), deg(-35), deg(25));
  apple.add(leaf);

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

export default createApple;
```

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