# Apple Tree

> A friendly low-poly apple tree with a short, sturdy trunk, three forked limbs and a full round crown of faceted leaf clusters dotted with shiny apples, plus a few windfalls in the grass. Toggle the fruit, pick apple and leaf colors and set the height for orchards, farms, cottage gardens and harvest games.

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

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

## Facts

- Category: Nature › Trees
- Size (W × H × D): 2.67 × 4.00 × 2.59 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 2,388 · Meshes: 43 · Materials: 7
- License: CC0-1.0 (Codels built-in)
- Tags: apple, deciduous, fruit, orchard, tree, low-poly, stylized, farm, garden, grassland, village, farming-sim, rpg, background, decoration, vegetation, foliage-material, wood, round, game-ready, parametric, color-green, size-large, poly-medium
- Page: https://codels.download/models/apple-tree

## Files

| Format | URL |
|---|---|
| three.js ES module (`createAppleTree()`) | https://codels.download/m/apple-tree.js |
| React Three Fiber component (`<AppleTree />`) | https://codels.download/m/apple-tree.jsx |
| Instancing module (`createAppleTreeInstances(count, place)`, one draw call per material) | https://codels.download/m/apple-tree.instanced.js |
| Standalone HTML demo | https://codels.download/m/apple-tree.html |
| glTF binary | https://codels.download/m/apple-tree.glb |
| glTF binary, Meshopt-compressed (2–3× smaller; GLTFLoader needs `setMeshoptDecoder(MeshoptDecoder)`) | https://codels.download/m/apple-tree.glb?compress=meshopt |
| glTF JSON | https://codels.download/m/apple-tree.gltf |
| OBJ (vertex colors) + MTL | https://codels.download/m/apple-tree.obj · https://codels.download/m/apple-tree.mtl |
| STL | https://codels.download/m/apple-tree.stl |
| CodelSpec JSON | https://codels.download/m/apple-tree.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 | 2.5 – 7 | 4 | 4 |
| `apples` | boolean | true \| false | true | true |
| `fruit` | color | #rrggbb | #d4362b | #d4362b |
| `leaves` | color | #rrggbb | #5a9a3c | #5a9a3c |
| `seed` | int | 1 – 20 | 4 | 4 |

## Parts

- trunk (lathe · bark)
- root1 (cylinder · bark)
- root2 (cylinder · bark)
- root3 (cylinder · bark)
- limb1 (cylinder · bark)
- limb2 (cylinder · bark)
- limb3 (cylinder · bark)
- crownCore (icosahedron · leaf)
- leaves1 (icosahedron · leafLight)
- leaves2 (icosahedron · leafLight)
- leaves3 (icosahedron · leafLight)
- leaves4 (icosahedron · leafLight)
- leaves5 (icosahedron · leafLight)
- leaves6 (icosahedron · leaf)
- leaves7 (icosahedron · leafLight)
- leaves8 (icosahedron · leafLight)
- leaves9 (icosahedron · leafDark)
- leaves10 (icosahedron · leafDark)
- leaves11 (icosahedron · leafDark)
- apple1 (sphere · appleDark)
- apple2 (sphere · apple)
- apple3 (sphere · apple)
- apple4 (sphere · appleDark)
- apple5 (sphere · apple)
- apple6 (sphere · apple)
- apple7 (sphere · appleDark)
- apple8 (sphere · apple)
- apple9 (sphere · apple)
- apple10 (sphere · appleDark)
- apple11 (sphere · apple)
- apple12 (sphere · apple)
- apple13 (sphere · appleDark)
- apple14 (sphere · apple)
- apple15 (sphere · apple)
- apple16 (sphere · appleDark)
- apple17 (sphere · apple)
- apple18 (sphere · apple)
- fallen1 (group)
  - fruit (sphere · apple)
  - stem (cylinder · stem)

## How to use

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

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

## Code

```js
/**
 * Apple Tree — Codels 3D model library (https://codels.download/models/apple-tree)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 2,388 · Size (W × H × D): 2.67 × 4.00 × 2.59 m
 *
 * Usage:
 *   import { createAppleTree } from './apple-tree.js';
 *   
 *   const model = createAppleTree();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Deterministic vertex displacement (organic low-poly look).
function jitter(geometry, amount, seed) {
  const pos = geometry.attributes.position;
  const h = (a, b, c, s) => {
    let x = Math.imul(a, 73856093) ^ Math.imul(b, 19349663) ^ Math.imul(c, 83492791) ^ Math.imul(s, 2654435761);
    x = Math.imul(x ^ (x >>> 16), 2246822507);
    x = Math.imul(x ^ (x >>> 13), 3266489909);
    return ((x ^ (x >>> 16)) >>> 0) / 4294967295 - 0.5;
  };
  for (let i = 0; i < pos.count; i++) {
    const x = pos.getX(i), y = pos.getY(i), z = pos.getZ(i);
    const qx = Math.round(x * 1000), qy = Math.round(y * 1000), qz = Math.round(z * 1000);
    pos.setXYZ(i, x + h(qx, qy, qz, seed) * 2 * amount, y + h(qx, qy, qz, seed + 1) * 2 * amount, z + h(qx, qy, qz, seed + 2) * 2 * amount);
  }
  pos.needsUpdate = true;
  geometry.computeVertexNormals();
  return geometry;
}

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

  // Materials
  const barkMat = new THREE.MeshStandardMaterial({ name: 'bark', color: 0x6e5038, roughness: 0.95, flatShading: true });
  const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x5a9a3c, roughness: 0.85, flatShading: true });
  const leafLightMat = new THREE.MeshStandardMaterial({ name: 'leafLight', color: 0x64aa4f, roughness: 0.85, flatShading: true });
  const leafDarkMat = new THREE.MeshStandardMaterial({ name: 'leafDark', color: 0x4b782f, roughness: 0.9, flatShading: true });
  const appleMat = new THREE.MeshStandardMaterial({ name: 'apple', color: 0xd4362b, roughness: 0.45, flatShading: true });
  const appleDarkMat = new THREE.MeshStandardMaterial({ name: 'appleDark', color: 0xaa2b22, roughness: 0.5, flatShading: true });
  const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0x4b3a26, roughness: 0.9, flatShading: true });

  // Shared geometries
  const sphereGeo = new THREE.SphereGeometry(0.116, 7, 5);
  const cylinderGeo = new THREE.CylinderGeometry(0.0081, 0.0116, 0.0522, 4);

  // Parts
  const trunk = new THREE.Mesh(lathe([[0, 0], [0.345, 0], [0.2576, 0.16], [0.2254, 0.816], [0.1955, 1.36], [0.138, 1.56], [0, 1.56]], 7), barkMat);
  trunk.name = 'trunk';
  root.add(trunk);
  const root1 = new THREE.Mesh(new THREE.CylinderGeometry(0.0322, 0.115, 0.3602, 5), barkMat);
  root1.name = 'root1';
  root1.position.set(0.1801, 0.0966, 0.1878);
  root1.rotation.set(deg(66.4925), deg(-42.7023), deg(-61.6174));
  root.add(root1);
  const root2 = new THREE.Mesh(new THREE.CylinderGeometry(0.0322, 0.115, 0.4011, 5), barkMat);
  root2.name = 'root2';
  root2.position.set(-0.2794, 0.0966, -0.0374);
  root2.rotation.set(deg(-7.3368), deg(-10.0137), deg(107.6059));
  root.add(root2);
  const root3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0322, 0.115, 0.4227, 5), barkMat);
  root3.name = 'root3';
  root3.position.set(0.0581, 0.0966, -0.2875);
  root3.rotation.set(deg(-105.1917), deg(14.6739), deg(-11.2462));
  root.add(root3);
  const limb1 = new THREE.Mesh(new THREE.CylinderGeometry(0.046, 0.115, 1.931, 5), barkMat);
  limb1.name = 'limb1';
  limb1.position.set(0.3379, 2.1545, 0.0457);
  limb1.rotation.set(deg(2.7124), deg(-0.4903), deg(-20.4877));
  root.add(limb1);
  const limb2 = new THREE.Mesh(new THREE.CylinderGeometry(0.046, 0.115, 1.7293, 5), barkMat);
  limb2.name = 'limb2';
  limb2.position.set(-0.1244, 2.0458, 0.3175);
  limb2.rotation.set(deg(21.5501), deg(1.5781), deg(8.2781));
  root.add(limb2);
  const limb3 = new THREE.Mesh(new THREE.CylinderGeometry(0.046, 0.115, 1.8031, 5), barkMat);
  limb3.name = 'limb3';
  limb3.position.set(-0.1587, 2.0858, -0.3018);
  limb3.rotation.set(deg(-19.5686), deg(-1.7536), deg(10.1429));
  root.add(limb3);
  const crownCore = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.9672, 1), 0.062, 4), leafMat);
  crownCore.name = 'crownCore';
  crownCore.position.set(0, 3.008, 0);
  crownCore.scale.set(1.08, 0.92, 1.08);
  root.add(crownCore);
  const leaves1 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.512, 1), 0.0512, 92), leafLightMat);
  leaves1.name = 'leaves1';
  leaves1.position.set(0.4582, 3.4986, -0.0851);
  leaves1.rotation.set(deg(53.0219), deg(228.5711), 0);
  root.add(leaves1);
  const leaves2 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5681, 1), 0.0568, 93), leafLightMat);
  leaves2.name = 'leaves2';
  leaves2.position.set(-0.3581, 3.4191, 0.4477);
  leaves2.rotation.set(deg(38.1911), deg(22.1435), 0);
  root.add(leaves2);
  const leaves3 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5799, 1), 0.058, 94), leafLightMat);
  leaves3.name = 'leaves3';
  leaves3.position.set(0.1351, 3.3143, -0.5877);
  leaves3.rotation.set(deg(8.3226), deg(198.2588), 0);
  root.add(leaves3);
  const leaves4 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5462, 1), 0.0546, 95), leafLightMat);
  leaves4.name = 'leaves4';
  leaves4.position.set(0.3002, 3.2566, 0.6405);
  leaves4.rotation.set(deg(46.9313), deg(23.5565), 0);
  root.add(leaves4);
  const leaves5 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5864, 1), 0.0586, 96), leafLightMat);
  leaves5.name = 'leaves5';
  leaves5.position.set(-0.7554, 3.1769, -0.1043);
  leaves5.rotation.set(deg(51.8991), deg(197.8031), 0);
  root.add(leaves5);
  const leaves6 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5534, 1), 0.0553, 97), leafMat);
  leaves6.name = 'leaves6';
  leaves6.position.set(0.5894, 3.086, -0.4521);
  leaves6.rotation.set(deg(12.8004), deg(56.5183), 0);
  root.add(leaves6);
  const leaves7 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5035, 1), 0.0503, 98), leafLightMat);
  leaves7.name = 'leaves7';
  leaves7.position.set(-0.0889, 3.0034, 0.7978);
  leaves7.rotation.set(deg(56.9267), deg(55.7596), 0);
  root.add(leaves7);
  const leaves8 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5657, 1), 0.0566, 99), leafLightMat);
  leaves8.name = 'leaves8';
  leaves8.position.set(-0.4113, 2.9215, -0.6167);
  leaves8.rotation.set(deg(10.1129), deg(146.8497), 0);
  root.add(leaves8);
  const leaves9 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5329, 1), 0.0533, 100), leafDarkMat);
  leaves9.name = 'leaves9';
  leaves9.position.set(0.7389, 2.8336, 0.0944);
  leaves9.rotation.set(deg(29.6162), deg(211.3327), 0);
  root.add(leaves9);
  const leaves10 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5691, 1), 0.0569, 101), leafDarkMat);
  leaves10.name = 'leaves10';
  leaves10.position.set(-0.6144, 2.7639, 0.2584);
  leaves10.rotation.set(deg(42.246), deg(160.6963), 0);
  root.add(leaves10);
  const leaves11 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.5568, 1), 0.0557, 102), leafDarkMat);
  leaves11.name = 'leaves11';
  leaves11.position.set(0.1943, 2.655, -0.6418);
  leaves11.rotation.set(deg(36.708), deg(302.9581), 0);
  root.add(leaves11);
  const apple1 = new THREE.Mesh(sphereGeo, appleDarkMat);
  apple1.name = 'apple1';
  apple1.position.set(0.9769, 3.5798, 0.0153);
  apple1.rotation.set(deg(6.1867), deg(350.6099), deg(-3.8436));
  apple1.scale.set(1, 0.9, 1);
  root.add(apple1);
  const apple2 = new THREE.Mesh(sphereGeo, appleMat);
  apple2.name = 'apple2';
  apple2.position.set(-0.8887, 3.5699, 0.7025);
  apple2.rotation.set(deg(-6.0816), deg(13.2021), deg(-10.594));
  apple2.scale.set(1, 0.9, 1);
  root.add(apple2);
  const apple3 = new THREE.Mesh(sphereGeo, appleMat);
  apple3.name = 'apple3';
  apple3.position.set(0.237, 3.4854, -1.1625);
  apple3.rotation.set(deg(-10.0741), deg(11.2302), deg(2.6435));
  apple3.scale.set(1, 0.9, 1);
  root.add(apple3);
  const apple4 = new THREE.Mesh(sphereGeo, appleDarkMat);
  apple4.name = 'apple4';
  apple4.position.set(0.8072, 3.3912, 0.7012);
  apple4.rotation.set(deg(13.1927), deg(268.7531), deg(-5.7122));
  apple4.scale.set(1, 0.9, 1);
  root.add(apple4);
  const apple5 = new THREE.Mesh(sphereGeo, appleMat);
  apple5.name = 'apple5';
  apple5.position.set(-1.3028, 3.3919, -0.3069);
  apple5.rotation.set(deg(-13.6133), deg(235.8538), deg(6.1153));
  apple5.scale.set(1, 0.9, 1);
  root.add(apple5);
  const apple6 = new THREE.Mesh(sphereGeo, appleMat);
  apple6.name = 'apple6';
  apple6.position.set(1.054, 3.284, -0.7243);
  apple6.rotation.set(deg(12.8069), deg(49.7371), deg(12.8316));
  apple6.scale.set(1, 0.9, 1);
  root.add(apple6);
  const apple7 = new THREE.Mesh(sphereGeo, appleDarkMat);
  apple7.name = 'apple7';
  apple7.position.set(-0.4473, 3.2174, 1.1109);
  apple7.rotation.set(deg(11.776), deg(181.7371), deg(-5.7422));
  apple7.scale.set(1, 0.9, 1);
  root.add(apple7);
  const apple8 = new THREE.Mesh(sphereGeo, appleMat);
  apple8.name = 'apple8';
  apple8.position.set(-0.6484, 3.155, -1.1265);
  apple8.rotation.set(deg(-11.4301), deg(183.9222), deg(5.9587));
  apple8.scale.set(1, 0.9, 1);
  root.add(apple8);
  const apple9 = new THREE.Mesh(sphereGeo, appleMat);
  apple9.name = 'apple9';
  apple9.position.set(1.0764, 3.0692, 0.4135);
  apple9.rotation.set(deg(7.0065), deg(95.6757), deg(-6.2942));
  apple9.scale.set(1, 0.9, 1);
  root.add(apple9);
  const apple10 = new THREE.Mesh(sphereGeo, appleDarkMat);
  apple10.name = 'apple10';
  apple10.position.set(-1.0951, 2.9975, 0.5414);
  apple10.rotation.set(deg(12.578), deg(279.699), deg(14.7624));
  apple10.scale.set(1, 0.9, 1);
  root.add(apple10);
  const apple11 = new THREE.Mesh(sphereGeo, appleMat);
  apple11.name = 'apple11';
  apple11.position.set(0.7344, 2.9042, -1.0554);
  apple11.rotation.set(deg(-11.0893), deg(320.8158), deg(12.3799));
  apple11.scale.set(1, 0.9, 1);
  root.add(apple11);
  const apple12 = new THREE.Mesh(sphereGeo, appleMat);
  apple12.name = 'apple12';
  apple12.position.set(0.3317, 2.8527, 1.086);
  apple12.rotation.set(deg(-9.5596), deg(233.8928), deg(5.4382));
  apple12.scale.set(1, 0.9, 1);
  root.add(apple12);
  const apple13 = new THREE.Mesh(sphereGeo, appleDarkMat);
  apple13.name = 'apple13';
  apple13.position.set(-1.134, 2.7438, -0.393);
  apple13.rotation.set(deg(10.668), deg(134.6898), deg(3.1837));
  apple13.scale.set(1, 0.9, 1);
  root.add(apple13);
  const apple14 = new THREE.Mesh(sphereGeo, appleMat);
  apple14.name = 'apple14';
  apple14.position.set(1.1505, 2.6926, -0.2573);
  apple14.rotation.set(deg(-6.6011), deg(136.0549), deg(5.207));
  apple14.scale.set(1, 0.9, 1);
  root.add(apple14);
  const apple15 = new THREE.Mesh(sphereGeo, appleMat);
  apple15.name = 'apple15';
  apple15.position.set(-0.4398, 2.6317, 0.9424);
  apple15.rotation.set(deg(-10.7755), deg(327.2795), deg(-12.0819));
  apple15.scale.set(1, 0.9, 1);
  root.add(apple15);
  const apple16 = new THREE.Mesh(sphereGeo, appleDarkMat);
  apple16.name = 'apple16';
  apple16.position.set(0.0147, 2.5551, -1.1633);
  apple16.rotation.set(deg(14.7509), deg(341.5822), deg(5.3283));
  apple16.scale.set(1, 0.9, 1);
  root.add(apple16);
  const apple17 = new THREE.Mesh(sphereGeo, appleMat);
  apple17.name = 'apple17';
  apple17.position.set(0.6679, 2.5666, 0.5904);
  apple17.rotation.set(deg(13.3748), deg(163.8929), deg(-2.5907));
  apple17.scale.set(1, 0.9, 1);
  root.add(apple17);
  const apple18 = new THREE.Mesh(sphereGeo, appleMat);
  apple18.name = 'apple18';
  apple18.position.set(-0.9864, 2.4568, -0.075);
  apple18.rotation.set(deg(7.7835), deg(284.0324), deg(-5.914));
  apple18.scale.set(1, 0.9, 1);
  root.add(apple18);
  const fallen1 = new THREE.Group();
  fallen1.name = 'fallen1';
  fallen1.position.set(-0.851, 0.1005, 0.2737);
  fallen1.rotation.set(deg(15.6212), deg(251.7167), 0);
  root.add(fallen1);
  const fruit = new THREE.Mesh(sphereGeo, appleMat);
  fruit.name = 'fruit';
  fruit.scale.set(1, 0.9, 1);
  fallen1.add(fruit);
  const stem = new THREE.Mesh(cylinderGeo, stemMat);
  stem.name = 'stem';
  stem.position.set(0, 0.1102, 0);
  stem.rotation.set(deg(12), 0, 0);
  fallen1.add(stem);
  const fallen2 = new THREE.Group();
  fallen2.name = 'fallen2';
  fallen2.position.set(-0.7422, 0.1142, -0.6794);
  fallen2.rotation.set(deg(67.0706), deg(296.2589), 0);
  root.add(fallen2);
  const fruit2 = new THREE.Mesh(sphereGeo, appleDarkMat);
  fruit2.name = 'fruit';
  fruit2.scale.set(1, 0.9, 1);
  fallen2.add(fruit2);
  const stem2 = new THREE.Mesh(cylinderGeo, stemMat);
  stem2.name = 'stem';
  stem2.position.set(0, 0.1102, 0);
  stem2.rotation.set(deg(12), 0, 0);
  fallen2.add(stem2);
  const fallen3 = new THREE.Group();
  fallen3.name = 'fallen3';
  fallen3.position.set(0.5879, 0.1049, -0.4352);
  fallen3.rotation.set(deg(59.331), deg(223.0435), 0);
  root.add(fallen3);
  const fruit3 = new THREE.Mesh(sphereGeo, appleMat);
  fruit3.name = 'fruit';
  fruit3.scale.set(1, 0.9, 1);
  fallen3.add(fruit3);
  const stem3 = new THREE.Mesh(cylinderGeo, stemMat);
  stem3.name = 'stem';
  stem3.position.set(0, 0.1102, 0);
  stem3.rotation.set(deg(12), 0, 0);
  fallen3.add(stem3);

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

export default createAppleTree;
```

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