# Fern

> A lush low-poly fern: arching fronds with pairs of diamond leaflets radiate from a compact crown and droop gracefully toward the ground, with two curled fiddleheads unrolling in the middle. Adjust size, frond count, droop and color for shady forest floors, jungles, riverbanks and swamps.

![Fern preview](https://codels.download/m/fern.png)

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

## Facts

- Category: Nature › Plants & Flowers
- Size (W × H × D): 0.97 × 0.41 × 1.00 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 1,428 · Meshes: 159 · Materials: 4
- License: CC0-1.0 (Codels built-in)
- Tags: fern, plant, low-poly, stylized, cave, forest, jungle, river, swamp, adventure, rpg, survival, background, decoration, vegetation, foliage-material, instancing-friendly, mobile-friendly, parametric, color-green, size-small, poly-low
- Page: https://codels.download/models/fern

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `size` | number | 0.3 – 1.5 | 0.7 | 0.7 |
| `fronds` | int | 5 – 9 | 7 | 7 |
| `droop` | number | 0 – 1 | 0.5 | 0.5 |
| `color` | color | #rrggbb | #4f913c | #4f913c |

## Parts

- fern (group)
  - frond1 (group)
    - rachis1 (cylinder · frondDark)
    - rachis2 (cylinder · frondDark)
    - leaflet1L (octahedron · frondDark)
    - leaflet1R (octahedron · frondDark)
    - rachis3 (cylinder · frondDark)
    - leaflet2L (octahedron · frondDark)
    - leaflet2R (octahedron · frondDark)
    - rachis4 (cylinder · frondDark)
    - leaflet3L (octahedron · frondDark)
    - leaflet3R (octahedron · frondDark)
    - rachis5 (cylinder · frondDark)
    - leaflet4L (octahedron · frondDark)
    - leaflet4R (octahedron · frondDark)
    - rachis6 (cylinder · frondDark)
    - leaflet5L (octahedron · frondDark)
    - leaflet5R (octahedron · frondDark)
    - rachis7 (cylinder · frondDark)
    - leaflet6L (octahedron · frondDark)
    - leaflet6R (octahedron · frondDark)
    - rachis8 (cylinder · frondDark)
    - leaflet7L (octahedron · frondDark)
    - leaflet7R (octahedron · frondDark)
  - frond2 (group)
    - rachis1 (cylinder · frondDark)
    - rachis2 (cylinder · frondDark)
    - leaflet1L (octahedron · frond)
    - leaflet1R (octahedron · frond)
    - rachis3 (cylinder · frondDark)
    - leaflet2L (octahedron · frond)
    - leaflet2R (octahedron · frond)
    - rachis4 (cylinder · frondDark)
    - leaflet3L (octahedron · frond)
    - leaflet3R (octahedron · frond)
    - rachis5 (cylinder · frondDark)
    - leaflet4L (octahedron · frond)
    - leaflet4R (octahedron · frond)
    - rachis6 (cylinder · frondDark)
    - leaflet5L (octahedron · frond)

## How to use

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

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

## Code

```js
/**
 * Fern — Codels 3D model library (https://codels.download/models/fern)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,428 · Size (W × H × D): 0.97 × 0.41 × 1.00 m
 *
 * Usage:
 *   import { createFern } from './fern.js';
 *   
 *   const model = createFern();
 *   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;
}

export function createFern() {
  const root = new THREE.Group();
  root.name = 'Fern';

  // Materials
  const frondMat = new THREE.MeshStandardMaterial({ name: 'frond', color: 0x4f913c, roughness: 0.85, flatShading: true });
  const frondDarkMat = new THREE.MeshStandardMaterial({ name: 'frondDark', color: 0x477a32, roughness: 0.85, flatShading: true });
  const frondLightMat = new THREE.MeshStandardMaterial({ name: 'frondLight', color: 0x599c50, roughness: 0.85, flatShading: true });
  const crownMat = new THREE.MeshStandardMaterial({ name: 'crown', color: 0x6b5236, roughness: 0.95, flatShading: true });

  // Shared geometries
  const octahedronGeo = new THREE.OctahedronGeometry(1, 0);
  const torusGeo = new THREE.TorusGeometry(0.0315, 0.0091, 4, 8, 5.0265);

  // Parts
  const fern = new THREE.Group();
  fern.name = 'fern';
  fern.position.set(0, 0.0101, 0);
  root.add(fern);
  const frond1 = new THREE.Group();
  frond1.name = 'frond1';
  frond1.position.set(0, 0.021, 0);
  frond1.rotation.set(0, deg(1.478), 0);
  fern.add(frond1);
  const rachis1 = new THREE.Mesh(new THREE.CylinderGeometry(0.0075, 0.0081, 0.0895, 4, 1, true), frondDarkMat);
  rachis1.name = 'rachis1';
  rachis1.position.set(0.0114, 0.0405, 0);
  rachis1.rotation.set(0, 0, deg(-15.7367));
  frond1.add(rachis1);
  const rachis2 = new THREE.Mesh(new THREE.CylinderGeometry(0.0068, 0.0074, 0.0895, 4, 1, true), frondDarkMat);
  rachis2.name = 'rachis2';
  rachis2.position.set(0.0396, 0.1196, 0);
  rachis2.rotation.set(0, 0, deg(-23.5362));
  frond1.add(rachis2);
  const leaflet1L = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet1L.name = 'leaflet1L';
  leaflet1L.position.set(0.086, 0.1811, 0.0598);
  leaflet1L.rotation.set(deg(59.0401), deg(-20.4811), deg(63.4175));
  leaflet1L.scale.set(0.0706, 0.0054, 0.0282);
  frond1.add(leaflet1L);
  const leaflet1R = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet1R.name = 'leaflet1R';
  leaflet1R.position.set(0.086, 0.1811, -0.0598);
  leaflet1R.rotation.set(deg(-59.0401), deg(20.4811), deg(63.4175));
  leaflet1R.scale.set(0.0706, 0.0054, 0.0282);
  frond1.add(leaflet1R);
  const rachis3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0061, 0.0067, 0.0895, 4, 1, true), frondDarkMat);
  rachis3.name = 'rachis3';
  rachis3.position.set(0.0801, 0.1929, 0);
  rachis3.rotation.set(0, 0, deg(-34.2871));
  frond1.add(rachis3);
  const leaflet2L = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet2L.name = 'leaflet2L';
  leaflet2L.position.set(0.1434, 0.2479, 0.071);
  leaflet2L.rotation.set(deg(56.3492), deg(-29.578), deg(57.0825));
  leaflet2L.scale.set(0.0838, 0.0054, 0.0335);
  frond1.add(leaflet2L);
  const leaflet2R = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet2R.name = 'leaflet2R';
  leaflet2R.position.set(0.1434, 0.2479, -0.071);
  leaflet2R.rotation.set(deg(-56.3492), deg(29.578), deg(57.0825));
  leaflet2R.scale.set(0.0838, 0.0054, 0.0335);
  frond1.add(leaflet2R);
  const rachis4 = new THREE.Mesh(new THREE.CylinderGeometry(0.0054, 0.006, 0.0895, 4, 1, true), frondDarkMat);
  rachis4.name = 'rachis4';
  rachis4.position.set(0.1344, 0.2566, 0);
  rachis4.rotation.set(0, 0, deg(-46.5308));
  frond1.add(rachis4);
  const leaflet3L = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet3L.name = 'leaflet3L';
  leaflet3L.position.set(0.2112, 0.2978, 0.0764);
  leaflet3L.rotation.set(deg(51.3591), deg(-39.4874), deg(48.3241));
  leaflet3L.scale.set(0.0902, 0.0054, 0.0361);
  frond1.add(leaflet3L);
  const leaflet3R = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet3R.name = 'leaflet3R';
  leaflet3R.position.set(0.2112, 0.2978, -0.0764);
  leaflet3R.rotation.set(deg(-51.3591), deg(39.4874), deg(48.3241));
  leaflet3R.scale.set(0.0902, 0.0054, 0.0361);
  frond1.add(leaflet3R);
  const rachis5 = new THREE.Mesh(new THREE.CylinderGeometry(0.0047, 0.0053, 0.0895, 4, 1, true), frondDarkMat);
  rachis5.name = 'rachis5';
  rachis5.position.set(0.2013, 0.3067, 0);
  rachis5.rotation.set(0, 0, deg(-59.8573));
  frond1.add(rachis5);
  const leaflet4L = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet4L.name = 'leaflet4L';
  leaflet4L.position.set(0.2854, 0.3291, 0.0762);
  leaflet4L.rotation.set(deg(42.3964), deg(-49.2646), deg(35.5819));
  leaflet4L.scale.set(0.0899, 0.0054, 0.036);
  frond1.add(leaflet4L);
  const leaflet4R = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet4R.name = 'leaflet4R';
  leaflet4R.position.set(0.2854, 0.3291, -0.0762);
  leaflet4R.rotation.set(deg(-42.3964), deg(49.2646), deg(35.5819));
  leaflet4R.scale.set(0.0899, 0.0054, 0.036);
  frond1.add(leaflet4R);
  const rachis6 = new THREE.Mesh(new THREE.CylinderGeometry(0.004, 0.0046, 0.0895, 4, 1, true), frondDarkMat);
  rachis6.name = 'rachis6';
  rachis6.position.set(0.2781, 0.3394, 0);
  rachis6.rotation.set(0, 0, deg(-74.0515));
  frond1.add(rachis6);
  const leaflet5L = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet5L.name = 'leaflet5L';
  leaflet5L.position.set(0.3615, 0.3413, 0.0702);
  leaflet5L.rotation.set(deg(26.5461), deg(-57.404), deg(15.9396));
  leaflet5L.scale.set(0.0828, 0.0054, 0.0331);
  frond1.add(leaflet5L);
  const leaflet5R = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet5R.name = 'leaflet5R';
  leaflet5R.position.set(0.3615, 0.3413, -0.0702);
  leaflet5R.rotation.set(deg(-26.5461), deg(57.404), deg(15.9396));
  leaflet5R.scale.set(0.0828, 0.0054, 0.0331);
  frond1.add(leaflet5R);
  const rachis7 = new THREE.Mesh(new THREE.CylinderGeometry(0.0033, 0.0039, 0.0895, 4, 1, true), frondDarkMat);
  rachis7.name = 'rachis7';
  rachis7.position.set(0.3607, 0.3517, 0);
  rachis7.rotation.set(0, 0, deg(-88.9779));
  frond1.add(rachis7);
  const leaflet6L = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet6L.name = 'leaflet6L';
  leaflet6L.position.set(0.4352, 0.3355, 0.0585);
  leaflet6L.rotation.set(deg(1.8576), deg(-61.1726), deg(-12.6077));
  leaflet6L.scale.set(0.069, 0.0054, 0.0276);
  frond1.add(leaflet6L);
  const leaflet6R = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet6R.name = 'leaflet6R';
  leaflet6R.position.set(0.4352, 0.3355, -0.0585);
  leaflet6R.rotation.set(deg(-1.8576), deg(61.1726), deg(-12.6077));
  leaflet6R.scale.set(0.069, 0.0054, 0.0276);
  frond1.add(leaflet6R);
  const rachis8 = new THREE.Mesh(new THREE.CylinderGeometry(0.0026, 0.0032, 0.0895, 4, 1, true), frondDarkMat);
  rachis8.name = 'rachis8';
  rachis8.position.set(0.4435, 0.3419, 0);
  rachis8.rotation.set(0, 0, deg(-104.542));
  frond1.add(rachis8);
  const leaflet7L = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet7L.name = 'leaflet7L';
  leaflet7L.position.set(0.5028, 0.3139, 0.0406);
  leaflet7L.rotation.set(deg(-24.538), deg(-58.0105), deg(-43.0199));
  leaflet7L.scale.set(0.048, 0.0054, 0.0192);
  frond1.add(leaflet7L);
  const leaflet7R = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet7R.name = 'leaflet7R';
  leaflet7R.position.set(0.5028, 0.3139, -0.0406);
  leaflet7R.rotation.set(deg(24.538), deg(58.0105), deg(-43.0199));
  leaflet7R.scale.set(0.048, 0.0054, 0.0192);
  frond1.add(leaflet7R);
  const frond2 = new THREE.Group();
  frond2.name = 'frond2';
  frond2.position.set(0, 0.021, 0);
  frond2.rotation.set(0, deg(40.773), 0);
  fern.add(frond2);
  const rachis12 = new THREE.Mesh(new THREE.CylinderGeometry(0.0071, 0.0077, 0.0854, 4, 1, true), frondDarkMat);
  rachis12.name = 'rachis1';
  rachis12.position.set(0.0071, 0.0395, 0);
  rachis12.rotation.set(0, 0, deg(-10.1342));
  frond2.add(rachis12);
  const rachis22 = new THREE.Mesh(new THREE.CylinderGeometry(0.0065, 0.007, 0.0854, 4, 1, true), frondDarkMat);
  rachis22.name = 'rachis2';
  rachis22.position.set(0.0267, 0.1171, 0);
  rachis22.rotation.set(0, 0, deg(-18.2868));
  frond2.add(rachis22);
  const leaflet1L2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet1L2.name = 'leaflet1L';
  leaflet1L2.position.set(0.0654, 0.1796, 0.057);
  leaflet1L2.rotation.set(deg(59.9183), deg(-15.9581), deg(66.2234));
  leaflet1L2.scale.set(0.0673, 0.0051, 0.0269);
  frond2.add(leaflet1L2);
  const leaflet1R2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet1R2.name = 'leaflet1R';
  leaflet1R2.position.set(0.0654, 0.1796, -0.057);
  leaflet1R2.rotation.set(deg(-59.9183), deg(15.9581), deg(66.2234));
  leaflet1R2.scale.set(0.0673, 0.0051, 0.0269);
  frond2.add(leaflet1R2);
  const rachis32 = new THREE.Mesh(new THREE.CylinderGeometry(0.0058, 0.0064, 0.0854, 4, 1, true), frondDarkMat);
  rachis32.name = 'rachis3';
  rachis32.position.set(0.0591, 0.1901, 0);
  rachis32.rotation.set(0, 0, deg(-29.5246));
  frond2.add(rachis32);
  const leaflet2L2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet2L2.name = 'leaflet2L';
  leaflet2L2.position.set(0.1148, 0.2474, 0.0677);
  leaflet2L2.rotation.set(deg(57.7039), deg(-25.5817), deg(60.0062));
  leaflet2L2.scale.set(0.0798, 0.0051, 0.0319);
  frond2.add(leaflet2L2);
  const leaflet2R2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet2R2.name = 'leaflet2R';
  leaflet2R2.position.set(0.1148, 0.2474, -0.0677);
  leaflet2R2.rotation.set(deg(-57.7039), deg(25.5817), deg(60.0062));
  leaflet2R2.scale.set(0.0798, 0.0051, 0.0319);
  frond2.add(leaflet2R2);
  const rachis42 = new THREE.Mesh(new THREE.CylinderGeometry(0.0051, 0.0057, 0.0854, 4, 1, true), frondDarkMat);
  rachis42.name = 'rachis4';
  rachis42.position.set(0.1058, 0.2546, 0);
  rachis42.rotation.set(0, 0, deg(-42.3228));
  frond2.add(rachis42);
  const leaflet3L2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet3L2.name = 'leaflet3L';
  leaflet3L2.position.set(0.176, 0.2992, 0.0729);
  leaflet3L2.rotation.set(deg(53.3551), deg(-36.1543), deg(51.5772));
  leaflet3L2.scale.set(0.086, 0.0051, 0.0344);
  frond2.add(leaflet3L2);
  const leaflet3R2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet3R2.name = 'leaflet3R';
  leaflet3R2.position.set(0.176, 0.2992, -0.0729);
  leaflet3R2.rotation.set(deg(-53.3551), deg(36.1543), deg(51.5772));
  leaflet3R2.scale.set(0.086, 0.0051, 0.0344);
  frond2.add(leaflet3R2);
  const rachis52 = new THREE.Mesh(new THREE.CylinderGeometry(0.0045, 0.0051, 0.0854, 4, 1, true), frondDarkMat);
  rachis52.name = 'rachis5';
  rachis52.position.set(0.1662, 0.3066, 0);
  rachis52.rotation.set(0, 0, deg(-56.2528));
  frond2.add(rachis52);
  const leaflet4L2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet4L2.name = 'leaflet4L';
  leaflet4L2.position.set(0.2449, 0.3329, 0.0726);
  leaflet4L2.rotation.set(deg(45.2866), deg(-46.7667), deg(39.4686));
  leaflet4L2.scale.set(0.0857, 0.0051, 0.0343);
  frond2.add(leaflet4L2);
  const leaflet4R2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet4R2.name = 'leaflet4R';
  leaflet4R2.position.set(0.2449, 0.3329, -0.0726);
  leaflet4R2.rotation.set(deg(-45.2866), deg(46.7667), deg(39.4686));
  leaflet4R2.scale.set(0.0857, 0.0051, 0.0343);
  frond2.add(leaflet4R2);
  const rachis62 = new THREE.Mesh(new THREE.CylinderGeometry(0.0038, 0.0044, 0.0854, 4, 1, true), frondDarkMat);
  rachis62.name = 'rachis6';
  rachis62.position.set(0.2375, 0.3419, 0);
  rachis62.rotation.set(0, 0, deg(-71.0898));
  frond2.add(rachis62);
  const leaflet5L2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet5L2.name = 'leaflet5L';
  leaflet5L2.position.set(0.3168, 0.3478, 0.0669);
  leaflet5L2.rotation.set(deg(30.5086), deg(-55.9884), deg(20.6796));
  leaflet5L2.scale.set(0.079, 0.0051, 0.0316);
  frond2.add(leaflet5L2);
  const leaflet5R2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet5R2.name = 'leaflet5R';
  leaflet5R2.position.set(0.3168, 0.3478, -0.0669);
  leaflet5R2.rotation.set(deg(-30.5086), deg(55.9884), deg(20.6796));
  leaflet5R2.scale.set(0.079, 0.0051, 0.0316);
  frond2.add(leaflet5R2);
  const rachis72 = new THREE.Mesh(new THREE.CylinderGeometry(0.0032, 0.0037, 0.0854, 4, 1, true), frondDarkMat);
  rachis72.name = 'rachis7';
  rachis72.position.set(0.3155, 0.3572, 0);
  rachis72.rotation.set(0, 0, deg(-86.6921));
  frond2.add(rachis72);
  const leaflet6L2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet6L2.name = 'leaflet6L';
  leaflet6L2.position.set(0.3872, 0.3446, 0.0558);
  leaflet6L2.rotation.set(deg(5.9891), deg(-61.0161), deg(-7.8889));
  leaflet6L2.scale.set(0.0658, 0.0051, 0.0263);
  frond2.add(leaflet6L2);
  const leaflet6R2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet6R2.name = 'leaflet6R';
  leaflet6R2.position.set(0.3872, 0.3446, -0.0558);
  leaflet6R2.rotation.set(deg(-5.9891), deg(61.0161), deg(-7.8889));
  leaflet6R2.scale.set(0.0658, 0.0051, 0.0263);
  frond2.add(leaflet6R2);
  const rachis82 = new THREE.Mesh(new THREE.CylinderGeometry(0.0025, 0.0031, 0.0854, 4, 1, true), frondDarkMat);
  rachis82.name = 'rachis8';
  rachis82.position.set(0.3947, 0.3505, 0);
  rachis82.rotation.set(0, 0, deg(-102.961));
  frond2.add(rachis82);
  const leaflet7L2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet7L2.name = 'leaflet7L';
  leaflet7L2.position.set(0.4519, 0.3254, 0.0388);
  leaflet7L2.rotation.set(deg(-22.1855), deg(-58.6376), deg(-40.2558));
  leaflet7L2.scale.set(0.0457, 0.0051, 0.0183);
  frond2.add(leaflet7L2);
  const leaflet7R2 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet7R2.name = 'leaflet7R';
  leaflet7R2.position.set(0.4519, 0.3254, -0.0388);
  leaflet7R2.rotation.set(deg(22.1855), deg(58.6376), deg(-40.2558));
  leaflet7R2.scale.set(0.0457, 0.0051, 0.0183);
  frond2.add(leaflet7R2);
  const frond3 = new THREE.Group();
  frond3.name = 'frond3';
  frond3.position.set(0, 0.021, 0);
  frond3.rotation.set(0, deg(99.2879), 0);
  fern.add(frond3);
  const rachis13 = new THREE.Mesh(new THREE.CylinderGeometry(0.0066, 0.0071, 0.0788, 4, 1, true), frondDarkMat);
  rachis13.name = 'rachis1';
  rachis13.position.set(0.0115, 0.0352, 0);
  rachis13.rotation.set(0, 0, deg(-18.0069));
  frond3.add(rachis13);
  const rachis23 = new THREE.Mesh(new THREE.CylinderGeometry(0.006, 0.0065, 0.0788, 4, 1, true), frondDarkMat);
  rachis23.name = 'rachis2';
  rachis23.position.set(0.0392, 0.1037, 0);
  rachis23.rotation.set(0, 0, deg(-26.0983));
  frond3.add(rachis23);
  const leaflet1L3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet1L3.name = 'leaflet1L';
  leaflet1L3.position.set(0.0824, 0.1561, 0.0527);
  leaflet1L3.rotation.set(deg(58.5148), deg(-22.6722), deg(61.9894));
  leaflet1L3.scale.set(0.0622, 0.0047, 0.0249);
  frond3.add(leaflet1L3);
  const leaflet1R3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet1R3.name = 'leaflet1R';
  leaflet1R3.position.set(0.0824, 0.1561, -0.0527);
  leaflet1R3.rotation.set(deg(-58.5148), deg(22.6722), deg(61.9894));
  leaflet1R3.scale.set(0.0622, 0.0047, 0.0249);
  frond3.add(leaflet1R3);
  const rachis33 = new THREE.Mesh(new THREE.CylinderGeometry(0.0054, 0.0059, 0.0788, 4, 1, true), frondDarkMat);
  rachis33.name = 'rachis3';
  rachis33.position.set(0.0779, 0.1665, 0);
  rachis33.rotation.set(0, 0, deg(-37.2515));
  frond3.add(rachis33);
  const leaflet2L3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet2L3.name = 'leaflet2L';
  leaflet2L3.position.set(0.1361, 0.212, 0.0625);
  leaflet2L3.rotation.set(deg(55.3568), deg(-32.0316), deg(55.1453));
  leaflet2L3.scale.set(0.0738, 0.0047, 0.0295);
  frond3.add(leaflet2L3);
  const leaflet2R3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet2R3.name = 'leaflet2R';
  leaflet2R3.position.set(0.1361, 0.212, -0.0625);
  leaflet2R3.rotation.set(deg(-55.3568), deg(32.0316), deg(55.1453));
  leaflet2R3.scale.set(0.0738, 0.0047, 0.0295);
  frond3.add(leaflet2R3);
  const rachis43 = new THREE.Mesh(new THREE.CylinderGeometry(0.0048, 0.0053, 0.0788, 4, 1, true), frondDarkMat);
  rachis43.name = 'rachis4';
  rachis43.position.set(0.1287, 0.2198, 0);
  rachis43.rotation.set(0, 0, deg(-49.9533));
  frond3.add(rachis43);
  const leaflet3L3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet3L3.name = 'leaflet3L';
  leaflet3L3.position.set(0.1984, 0.252, 0.0673);
  leaflet3L3.rotation.set(deg(49.4756), deg(-42.1259), deg(45.4431));
  leaflet3L3.scale.set(0.0794, 0.0047, 0.0318);
  frond3.add(leaflet3L3);
  const leaflet3R3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet3R3.name = 'leaflet3R';
  leaflet3R3.position.set(0.1984, 0.252, -0.0673);
  leaflet3R3.rotation.set(deg(-49.4756), deg(42.1259), deg(45.4431));
  leaflet3R3.scale.set(0.0794, 0.0047, 0.0318);
  frond3.add(leaflet3R3);
  const rachis53 = new THREE.Mesh(new THREE.CylinderGeometry(0.0041, 0.0047, 0.0788, 4, 1, true), frondDarkMat);
  rachis53.name = 'rachis5';
  rachis53.position.set(0.1903, 0.2601, 0);
  rachis53.rotation.set(0, 0, deg(-63.7784));
  frond3.add(rachis53);
  const leaflet4L3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet4L3.name = 'leaflet4L';
  leaflet4L3.position.set(0.2656, 0.2747, 0.0671);
  leaflet4L3.rotation.set(deg(38.7767), deg(-51.8176), deg(30.8959));
  leaflet4L3.scale.set(0.0791, 0.0047, 0.0317);
  frond3.add(leaflet4L3);
  const leaflet4R3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet4R3.name = 'leaflet4R';
  leaflet4R3.position.set(0.2656, 0.2747, -0.0671);
  leaflet4R3.rotation.set(deg(-38.7767), deg(51.8176), deg(30.8959));
  leaflet4R3.scale.set(0.0791, 0.0047, 0.0317);
  frond3.add(leaflet4R3);
  const rachis63 = new THREE.Mesh(new THREE.CylinderGeometry(0.0035, 0.0041, 0.0788, 4, 1, true), frondDarkMat);
  rachis63.name = 'rachis6';
  rachis63.position.set(0.2599, 0.2838, 0);
  rachis63.rotation.set(0, 0, deg(-78.5038));
  frond3.add(rachis63);
  const leaflet5L3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet5L3.name = 'leaflet5L';
  leaflet5L3.position.set(0.3332, 0.2798, 0.0618);
  leaflet5L3.rotation.set(deg(19.919), deg(-59.1639), deg(8.1533));
  leaflet5L3.scale.set(0.0729, 0.0047, 0.0292);
  frond3.add(leaflet5L3);
  const leaflet5R3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet5R3.name = 'leaflet5R';
  leaflet5R3.position.set(0.3332, 0.2798, -0.0618);
  leaflet5R3.rotation.set(deg(-19.919), deg(59.1639), deg(8.1533));
  leaflet5R3.scale.set(0.0729, 0.0047, 0.0292);
  frond3.add(leaflet5R3);
  const rachis73 = new THREE.Mesh(new THREE.CylinderGeometry(0.0029, 0.0035, 0.0788, 4, 1, true), frondDarkMat);
  rachis73.name = 'rachis7';
  rachis73.position.set(0.3331, 0.2886, 0);
  rachis73.rotation.set(0, 0, deg(-93.9887));
  frond3.add(rachis73);
  const leaflet6L3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet6L3.name = 'leaflet6L';
  leaflet6L3.position.set(0.3973, 0.2687, 0.0515);
  leaflet6L3.rotation.set(deg(-7.208), deg(-60.9379), deg(-22.9608));
  leaflet6L3.scale.set(0.0608, 0.0047, 0.0243);
  frond3.add(leaflet6L3);
  const leaflet6R3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet6R3.name = 'leaflet6R';
  leaflet6R3.position.set(0.3973, 0.2687, -0.0515);
  leaflet6R3.rotation.set(deg(7.208), deg(60.9379), deg(-22.9608));
  leaflet6R3.scale.set(0.0608, 0.0047, 0.0243);
  frond3.add(leaflet6R3);
  const rachis83 = new THREE.Mesh(new THREE.CylinderGeometry(0.0023, 0.0028, 0.0788, 4, 1, true), frondDarkMat);
  rachis83.name = 'rachis8';
  rachis83.position.set(0.4049, 0.2733, 0);
  rachis83.rotation.set(0, 0, deg(-110.1352));
  frond3.add(rachis83);
  const leaflet7L3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet7L3.name = 'leaflet7L';
  leaflet7L3.position.set(0.4545, 0.2437, 0.0358);
  leaflet7L3.rotation.set(deg(-32.0418), deg(-55.3524), deg(-51.9918));
  leaflet7L3.scale.set(0.0422, 0.0047, 0.0169);
  frond3.add(leaflet7L3);
  const leaflet7R3 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet7R3.name = 'leaflet7R';
  leaflet7R3.position.set(0.4545, 0.2437, -0.0358);
  leaflet7R3.rotation.set(deg(32.0418), deg(55.3524), deg(-51.9918));
  leaflet7R3.scale.set(0.0422, 0.0047, 0.0169);
  frond3.add(leaflet7R3);
  const frond4 = new THREE.Group();
  frond4.name = 'frond4';
  frond4.position.set(0, 0.021, 0);
  frond4.rotation.set(0, deg(161.4676), 0);
  fern.add(frond4);
  const rachis14 = new THREE.Mesh(new THREE.CylinderGeometry(0.0063, 0.0068, 0.0753, 4, 1, true), frondDarkMat);
  rachis14.name = 'rachis1';
  rachis14.position.set(0.0073, 0.0346, 0);
  rachis14.rotation.set(0, 0, deg(-11.9194));
  frond4.add(rachis14);
  const rachis24 = new THREE.Mesh(new THREE.CylinderGeometry(0.0057, 0.0062, 0.0753, 4, 1, true), frondDarkMat);
  rachis24.name = 'rachis2';
  rachis24.position.set(0.0273, 0.1023, 0);
  rachis24.rotation.set(0, 0, deg(-20.9885));
  frond4.add(rachis24);
  const leaflet1L4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet1L4.name = 'leaflet1L';
  leaflet1L4.position.set(0.064, 0.1558, 0.0503);
  leaflet1L4.rotation.set(deg(59.4983), deg(-18.291), deg(64.7976));
  leaflet1L4.scale.set(0.0594, 0.0045, 0.0238);
  frond4.add(leaflet1L4);
  const leaflet1R4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet1R4.name = 'leaflet1R';
  leaflet1R4.position.set(0.064, 0.1558, -0.0503);
  leaflet1R4.rotation.set(deg(-59.4983), deg(18.291), deg(64.7976));
  leaflet1R4.scale.set(0.0594, 0.0045, 0.0238);
  frond4.add(leaflet1R4);
  const rachis34 = new THREE.Mesh(new THREE.CylinderGeometry(0.0051, 0.0056, 0.0753, 4, 1, true), frondDarkMat);
  rachis34.name = 'rachis3';
  rachis34.position.set(0.0595, 0.1649, 0);
  rachis34.rotation.set(0, 0, deg(-33.4895));
  frond4.add(rachis34);
  const leaflet2L4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet2L4.name = 'leaflet2L';
  leaflet2L4.position.set(0.1121, 0.2119, 0.0597);
  leaflet2L4.rotation.set(deg(56.5958), deg(-28.9131), deg(57.5874));
  leaflet2L4.scale.set(0.0705, 0.0045, 0.0282);
  frond4.add(leaflet2L4);
  const leaflet2R4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet2R4.name = 'leaflet2R';
  leaflet2R4.position.set(0.1121, 0.2119, -0.0597);
  leaflet2R4.rotation.set(deg(-56.5958), deg(28.9131), deg(57.5874));
  leaflet2R4.scale.set(0.0705, 0.0045, 0.0282);
  frond4.add(leaflet2R4);
  const rachis44 = new THREE.Mesh(new THREE.CylinderGeometry(0.0045, 0.005, 0.0753, 4, 1, true), frondDarkMat);
  rachis44.name = 'rachis4';
  rachis44.position.set(0.1052, 0.2183, 0);
  rachis44.rotation.set(0, 0, deg(-47.7263));
  frond4.add(rachis44);
  const leaflet3L4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet3L4.name = 'leaflet3L';
  leaflet3L4.position.set(0.1706, 0.2516, 0.0643);
  leaflet3L4.rotation.set(deg(50.7294), deg(-40.4171), deg(47.3436));
  leaflet3L4.scale.set(0.0759, 0.0045, 0.0304);
  frond4.add(leaflet3L4);
  const leaflet3R4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet3R4.name = 'leaflet3R';
  leaflet3R4.position.set(0.1706, 0.2516, -0.0643);
  leaflet3R4.rotation.set(deg(-50.7294), deg(40.4171), deg(47.3436));
  leaflet3R4.scale.set(0.0759, 0.0045, 0.0304);
  frond4.add(leaflet3R4);
  const rachis54 = new THREE.Mesh(new THREE.CylinderGeometry(0.004, 0.0045, 0.0753, 4, 1, true), frondDarkMat);
  rachis54.name = 'rachis5';
  rachis54.position.set(0.1631, 0.258, 0);
  rachis54.rotation.set(0, 0, deg(-63.2221));
  frond4.add(rachis54);
  const leaflet4L4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet4L4.name = 'leaflet4L';
  leaflet4L4.position.set(0.2348, 0.2727, 0.0641);
  leaflet4L4.rotation.set(deg(39.3226), deg(-51.4671), deg(31.5921));
  leaflet4L4.scale.set(0.0756, 0.0045, 0.0302);
  frond4.add(leaflet4L4);
  const leaflet4R4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet4R4.name = 'leaflet4R';
  leaflet4R4.position.set(0.2348, 0.2727, -0.0641);
  leaflet4R4.rotation.set(deg(-39.3226), deg(51.4671), deg(31.5921));
  leaflet4R4.scale.set(0.0756, 0.0045, 0.0302);
  frond4.add(leaflet4R4);
  const rachis64 = new THREE.Mesh(new THREE.CylinderGeometry(0.0034, 0.0039, 0.0753, 4, 1, true), frondDarkMat);
  rachis64.name = 'rachis6';
  rachis64.position.set(0.2295, 0.2803, 0);
  rachis64.rotation.set(0, 0, deg(-79.727));
  frond4.add(rachis64);
  const leaflet5L4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet5L4.name = 'leaflet5L';
  leaflet5L4.position.set(0.2995, 0.275, 0.0591);
  leaflet5L4.rotation.set(deg(17.9655), deg(-59.561), deg(5.8829));
  leaflet5L4.scale.set(0.0697, 0.0045, 0.0279);
  frond4.add(leaflet5L4);
  const leaflet5R4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet5R4.name = 'leaflet5R';
  leaflet5R4.position.set(0.2995, 0.275, -0.0591);
  leaflet5R4.rotation.set(deg(-17.9655), deg(59.561), deg(5.8829));
  leaflet5R4.scale.set(0.0697, 0.0045, 0.0279);
  frond4.add(leaflet5R4);
  const rachis74 = new THREE.Mesh(new THREE.CylinderGeometry(0.0028, 0.0033, 0.0753, 4, 1, true), frondDarkMat);
  rachis74.name = 'rachis7';
  rachis74.position.set(0.2995, 0.2822, 0);
  rachis74.rotation.set(0, 0, deg(-97.0831));
  frond4.add(rachis74);
  const leaflet6L4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet6L4.name = 'leaflet6L';
  leaflet6L4.position.set(0.3596, 0.2599, 0.0492);
  leaflet6L4.rotation.set(deg(-12.6367), deg(-60.4039), deg(-29.1861));
  leaflet6L4.scale.set(0.0581, 0.0045, 0.0232);
  frond4.add(leaflet6L4);
  const leaflet6R4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet6R4.name = 'leaflet6R';
  leaflet6R4.position.set(0.3596, 0.2599, -0.0492);
  leaflet6R4.rotation.set(deg(12.6367), deg(60.4039), deg(-29.1861));
  leaflet6R4.scale.set(0.0581, 0.0045, 0.0232);
  frond4.add(leaflet6R4);
  const rachis84 = new THREE.Mesh(new THREE.CylinderGeometry(0.0022, 0.0027, 0.0753, 4, 1, true), frondDarkMat);
  rachis84.name = 'rachis8';
  rachis84.position.set(0.3666, 0.2628, 0);
  rachis84.rotation.set(0, 0, deg(-115.1808));
  frond4.add(rachis84);
  const leaflet7L4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet7L4.name = 'leaflet7L';
  leaflet7L4.position.set(0.4113, 0.2304, 0.0342);
  leaflet7L4.rotation.set(deg(-37.7253), deg(-52.4619), deg(-59.02));
  leaflet7L4.scale.set(0.0404, 0.0045, 0.0161);
  frond4.add(leaflet7L4);
  const leaflet7R4 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet7R4.name = 'leaflet7R';
  leaflet7R4.position.set(0.4113, 0.2304, -0.0342);
  leaflet7R4.rotation.set(deg(37.7253), deg(52.4619), deg(-59.02));
  leaflet7R4.scale.set(0.0404, 0.0045, 0.0161);
  frond4.add(leaflet7R4);
  const frond5 = new THREE.Group();
  frond5.name = 'frond5';
  frond5.position.set(0, 0.021, 0);
  frond5.rotation.set(0, deg(218.4842), 0);
  fern.add(frond5);
  const rachis15 = new THREE.Mesh(new THREE.CylinderGeometry(0.0072, 0.0078, 0.0863, 4, 1, true), frondDarkMat);
  rachis15.name = 'rachis1';
  rachis15.position.set(0.012, 0.0387, 0);
  rachis15.rotation.set(0, 0, deg(-17.2422));
  frond5.add(rachis15);
  const rachis25 = new THREE.Mesh(new THREE.CylinderGeometry(0.0065, 0.0071, 0.0863, 4, 1, true), frondDarkMat);
  rachis25.name = 'rachis2';
  rachis25.position.set(0.0416, 0.114, 0);
  rachis25.rotation.set(0, 0, deg(-25.6826));
  frond5.add(rachis25);
  const leaflet1L5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet1L5.name = 'leaflet1L';
  leaflet1L5.position.set(0.0885, 0.1716, 0.0576);
  leaflet1L5.rotation.set(deg(58.6046), deg(-22.3176), deg(62.2241));
  leaflet1L5.scale.set(0.068, 0.0052, 0.0272);
  frond5.add(leaflet1L5);
  const leaflet1R5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet1R5.name = 'leaflet1R';
  leaflet1R5.position.set(0.0885, 0.1716, -0.0576);
  leaflet1R5.rotation.set(deg(-58.6046), deg(22.3176), deg(62.2241));
  leaflet1R5.scale.set(0.068, 0.0052, 0.0272);
  frond5.add(leaflet1R5);
  const rachis35 = new THREE.Mesh(new THREE.CylinderGeometry(0.0059, 0.0064, 0.0863, 4, 1, true), frondDarkMat);
  rachis35.name = 'rachis3';
  rachis35.position.set(0.0837, 0.1827, 0);
  rachis35.rotation.set(0, 0, deg(-37.3171));
  frond5.add(rachis35);
  const leaflet2L5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet2L5.name = 'leaflet2L';
  leaflet2L5.position.set(0.1474, 0.2324, 0.0684);
  leaflet2L5.rotation.set(deg(55.3335), deg(-32.0855), deg(55.1013));
  leaflet2L5.scale.set(0.0807, 0.0052, 0.0323);
  frond5.add(leaflet2L5);
  const leaflet2R5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet2R5.name = 'leaflet2R';
  leaflet2R5.position.set(0.1474, 0.2324, -0.0684);
  leaflet2R5.rotation.set(deg(-55.3335), deg(32.0855), deg(55.1013));
  leaflet2R5.scale.set(0.0807, 0.0052, 0.0323);
  frond5.add(leaflet2R5);
  const rachis45 = new THREE.Mesh(new THREE.CylinderGeometry(0.0052, 0.0058, 0.0863, 4, 1, true), frondDarkMat);
  rachis45.name = 'rachis4';
  rachis45.position.set(0.1396, 0.2407, 0);
  rachis45.rotation.set(0, 0, deg(-50.567));
  frond5.add(rachis45);
  const leaflet3L5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet3L5.name = 'leaflet3L';
  leaflet3L5.position.set(0.2162, 0.2751, 0.0736);
  leaflet3L5.rotation.set(deg(49.1106), deg(-42.591), deg(44.9015));
  leaflet3L5.scale.set(0.0869, 0.0052, 0.0348);
  frond5.add(leaflet3L5);
  const leaflet3R5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet3R5.name = 'leaflet3R';
  leaflet3R5.position.set(0.2162, 0.2751, -0.0736);
  leaflet3R5.rotation.set(deg(-49.1106), deg(42.591), deg(44.9015));
  leaflet3R5.scale.set(0.0869, 0.0052, 0.0348);
  frond5.add(leaflet3R5);
  const rachis55 = new THREE.Mesh(new THREE.CylinderGeometry(0.0045, 0.0051, 0.0863, 4, 1, true), frondDarkMat);
  rachis55.name = 'rachis5';
  rachis55.position.set(0.2077, 0.2836, 0);
  rachis55.rotation.set(0, 0, deg(-64.9886));
  frond5.add(rachis55);
  const leaflet4L5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet4L5.name = 'leaflet4L';
  leaflet4L5.position.set(0.2903, 0.2978, 0.0734);
  leaflet4L5.rotation.set(deg(37.5503), deg(-52.5654), deg(29.3438));
  leaflet4L5.scale.set(0.0866, 0.0052, 0.0346);
  frond5.add(leaflet4L5);
  const leaflet4R5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet4R5.name = 'leaflet4R';
  leaflet4R5.position.set(0.2903, 0.2978, -0.0734);
  leaflet4R5.rotation.set(deg(-37.5503), deg(52.5654), deg(29.3438));
  leaflet4R5.scale.set(0.0866, 0.0052, 0.0346);
  frond5.add(leaflet4R5);
  const rachis65 = new THREE.Mesh(new THREE.CylinderGeometry(0.0039, 0.0044, 0.0863, 4, 1, true), frondDarkMat);
  rachis65.name = 'rachis6';
  rachis65.position.set(0.2843, 0.3075, 0);
  rachis65.rotation.set(0, 0, deg(-80.3494));
  frond5.add(rachis65);
  const leaflet5L5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet5L5.name = 'leaflet5L';
  leaflet5L5.position.set(0.3644, 0.3005, 0.0676);
  leaflet5L5.rotation.set(deg(16.9512), deg(-59.7478), deg(4.7077));
  leaflet5L5.scale.set(0.0798, 0.0052, 0.0319);
  frond5.add(leaflet5L5);
  const leaflet5R5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet5R5.name = 'leaflet5R';
  leaflet5R5.position.set(0.3644, 0.3005, -0.0676);
  leaflet5R5.rotation.set(deg(-16.9512), deg(59.7478), deg(4.7077));
  leaflet5R5.scale.set(0.0798, 0.0052, 0.0319);
  frond5.add(leaflet5R5);
  const rachis75 = new THREE.Mesh(new THREE.CylinderGeometry(0.0032, 0.0038, 0.0863, 4, 1, true), frondDarkMat);
  rachis75.name = 'rachis7';
  rachis75.position.set(0.3646, 0.3097, 0);
  rachis75.rotation.set(0, 0, deg(-96.5024));
  frond5.add(rachis75);
  const leaflet6L5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet6L5.name = 'leaflet6L';
  leaflet6L5.position.set(0.4337, 0.2848, 0.0564);
  leaflet6L5.rotation.set(deg(-11.6346), deg(-60.526), deg(-28.0343));
  leaflet6L5.scale.set(0.0665, 0.0052, 0.0266);
  frond5.add(leaflet6L5);
  const leaflet6R5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet6R5.name = 'leaflet6R';
  leaflet6R5.position.set(0.4337, 0.2848, -0.0564);
  leaflet6R5.rotation.set(deg(11.6346), deg(60.526), deg(-28.0343));
  leaflet6R5.scale.set(0.0665, 0.0052, 0.0266);
  frond5.add(leaflet6R5);
  const rachis85 = new THREE.Mesh(new THREE.CylinderGeometry(0.0025, 0.0031, 0.0863, 4, 1, true), frondDarkMat);
  rachis85.name = 'rachis8';
  rachis85.position.set(0.4421, 0.2891, 0);
  rachis85.rotation.set(0, 0, deg(-113.3456));
  frond5.add(rachis85);
  const leaflet7L5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet7L5.name = 'leaflet7L';
  leaflet7L5.position.set(0.4944, 0.2537, 0.0392);
  leaflet7L5.rotation.set(deg(-35.7728), deg(-53.5602), deg(-56.5758));
  leaflet7L5.scale.set(0.0462, 0.0052, 0.0185);
  frond5.add(leaflet7L5);
  const leaflet7R5 = new THREE.Mesh(octahedronGeo, frondMat);
  leaflet7R5.name = 'leaflet7R';
  leaflet7R5.position.set(0.4944, 0.2537, -0.0392);
  leaflet7R5.rotation.set(deg(35.7728), deg(53.5602), deg(-56.5758));
  leaflet7R5.scale.set(0.0462, 0.0052, 0.0185);
  frond5.add(leaflet7R5);
  const frond6 = new THREE.Group();
  frond6.name = 'frond6';
  frond6.position.set(0, 0.021, 0);
  frond6.rotation.set(0, deg(262.5674), 0);
  fern.add(frond6);
  const rachis16 = new THREE.Mesh(new THREE.CylinderGeometry(0.007, 0.0075, 0.0834, 4, 1, true), frondDarkMat);
  rachis16.name = 'rachis1';
  rachis16.position.set(0.0078, 0.0384, 0);
  rachis16.rotation.set(0, 0, deg(-11.5042));
  frond6.add(rachis16);
  const rachis26 = new THREE.Mesh(new THREE.CylinderGeometry(0.0063, 0.0069, 0.0834, 4, 1, true), frondDarkMat);
  rachis26.name = 'rachis2';
  rachis26.position.set(0.0294, 0.1134, 0);
  rachis26.rotation.set(0, 0, deg(-20.6006));
  frond6.add(rachis26);
  const leaflet1L6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet1L6.name = 'leaflet1L';
  leaflet1L6.position.set(0.0696, 0.1729, 0.0557);
  leaflet1L6.rotation.set(deg(59.5627), deg(-17.9567), deg(65.0045));
  leaflet1L6.scale.set(0.0657, 0.005, 0.0263);
  frond6.add(leaflet1L6);
  const leaflet1R6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet1R6.name = 'leaflet1R';
  leaflet1R6.position.set(0.0696, 0.1729, -0.0557);
  leaflet1R6.rotation.set(deg(-59.5627), deg(17.9567), deg(65.0045));
  leaflet1R6.scale.set(0.0657, 0.005, 0.0263);
  frond6.add(leaflet1R6);
  const rachis36 = new THREE.Mesh(new THREE.CylinderGeometry(0.0057, 0.0062, 0.0834, 4, 1, true), frondDarkMat);
  rachis36.name = 'rachis3';
  rachis36.position.set(0.0646, 0.1829, 0);
  rachis36.rotation.set(0, 0, deg(-33.1393));
  frond6.add(rachis36);
  const leaflet2L6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet2L6.name = 'leaflet2L';
  leaflet2L6.position.set(0.1225, 0.2353, 0.0661);
  leaflet2L6.rotation.set(deg(56.7015), deg(-28.6205), deg(57.807));
  leaflet2L6.scale.set(0.078, 0.005, 0.0312);
  frond6.add(leaflet2L6);
  const leaflet2R6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet2R6.name = 'leaflet2R';
  leaflet2R6.position.set(0.1225, 0.2353, -0.0661);
  leaflet2R6.rotation.set(deg(-56.7015), deg(28.6205), deg(57.807));
  leaflet2R6.scale.set(0.078, 0.005, 0.0312);
  frond6.add(leaflet2R6);
  const rachis46 = new THREE.Mesh(new THREE.CylinderGeometry(0.005, 0.0056, 0.0834, 4, 1, true), frondDarkMat);
  rachis46.name = 'rachis4';
  rachis46.position.set(0.1149, 0.2422, 0);
  rachis46.rotation.set(0, 0, deg(-47.4189));
  frond6.add(rachis46);
  const leaflet3L6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet3L6.name = 'leaflet3L';
  leaflet3L6.position.set(0.187, 0.2795, 0.0712);
  leaflet3L6.rotation.set(deg(50.8941), deg(-40.1788), deg(47.5983));
  leaflet3L6.scale.set(0.084, 0.005, 0.0336);
  frond6.add(leaflet3L6);
  const leaflet3R6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet3R6.name = 'leaflet3R';
  leaflet3R6.position.set(0.187, 0.2795, -0.0712);
  leaflet3R6.rotation.set(deg(-50.8941), deg(40.1788), deg(47.5983));
  leaflet3R6.scale.set(0.084, 0.005, 0.0336);
  frond6.add(leaflet3R6);
  const rachis56 = new THREE.Mesh(new THREE.CylinderGeometry(0.0044, 0.0049, 0.0834, 4, 1, true), frondDarkMat);
  rachis56.name = 'rachis5';
  rachis56.position.set(0.1786, 0.2865, 0);
  rachis56.rotation.set(0, 0, deg(-62.9614));
  frond6.add(rachis56);
  const leaflet4L6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet4L6.name = 'leaflet4L';
  leaflet4L6.position.set(0.2579, 0.3031, 0.0709);
  leaflet4L6.rotation.set(deg(39.5747), deg(-51.3014), deg(31.9148));
  leaflet4L6.scale.set(0.0837, 0.005, 0.0335);
  frond6.add(leaflet4L6);
  const leaflet4R6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet4R6.name = 'leaflet4R';
  leaflet4R6.position.set(0.2579, 0.3031, -0.0709);
  leaflet4R6.rotation.set(deg(-39.5747), deg(51.3014), deg(31.9148));
  leaflet4R6.scale.set(0.0837, 0.005, 0.0335);
  frond6.add(leaflet4R6);
  const rachis66 = new THREE.Mesh(new THREE.CylinderGeometry(0.0037, 0.0043, 0.0834, 4, 1, true), frondDarkMat);
  rachis66.name = 'rachis6';
  rachis66.position.set(0.252, 0.3115, 0);
  rachis66.rotation.set(0, 0, deg(-79.5159));
  frond6.add(rachis66);
  const leaflet5L6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet5L6.name = 'leaflet5L';
  leaflet5L6.position.set(0.3294, 0.3059, 0.0654);
  leaflet5L6.rotation.set(deg(18.3064), deg(-59.4953), deg(6.2785));
  leaflet5L6.scale.set(0.0771, 0.005, 0.0308);
  frond6.add(leaflet5L6);
  const leaflet5R6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet5R6.name = 'leaflet5R';
  leaflet5R6.position.set(0.3294, 0.3059, -0.0654);
  leaflet5R6.rotation.set(deg(-18.3064), deg(59.4953), deg(6.2785));
  leaflet5R6.scale.set(0.0771, 0.005, 0.0308);
  frond6.add(leaflet5R6);
  const rachis76 = new THREE.Mesh(new THREE.CylinderGeometry(0.0031, 0.0037, 0.0834, 4, 1, true), frondDarkMat);
  rachis76.name = 'rachis7';
  rachis76.position.set(0.3294, 0.3139, 0);
  rachis76.rotation.set(0, 0, deg(-96.9243));
  frond6.add(rachis76);
  const leaflet6L6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet6L6.name = 'leaflet6L';
  leaflet6L6.position.set(0.3961, 0.2893, 0.0545);
  leaflet6L6.rotation.set(deg(-12.3634), deg(-60.4383), deg(-28.8719));
  leaflet6L6.scale.set(0.0643, 0.005, 0.0257);
  frond6.add(leaflet6L6);
  const leaflet6R6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet6R6.name = 'leaflet6R';
  leaflet6R6.position.set(0.3961, 0.2893, -0.0545);
  leaflet6R6.rotation.set(deg(12.3634), deg(60.4383), deg(-28.8719));
  leaflet6R6.scale.set(0.0643, 0.005, 0.0257);
  frond6.add(leaflet6R6);
  const rachis86 = new THREE.Mesh(new THREE.CylinderGeometry(0.0024, 0.003, 0.0834, 4, 1, true), frondDarkMat);
  rachis86.name = 'rachis8';
  rachis86.position.set(0.4038, 0.2925, 0);
  rachis86.rotation.set(0, 0, deg(-115.0765));
  frond6.add(rachis86);
  const leaflet7L6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet7L6.name = 'leaflet7L';
  leaflet7L6.position.set(0.4533, 0.2568, 0.0378);
  leaflet7L6.rotation.set(deg(-37.6177), deg(-52.5257), deg(-58.8843));
  leaflet7L6.scale.set(0.0447, 0.005, 0.0179);
  frond6.add(leaflet7L6);
  const leaflet7R6 = new THREE.Mesh(octahedronGeo, frondLightMat);
  leaflet7R6.name = 'leaflet7R';
  leaflet7R6.position.set(0.4533, 0.2568, -0.0378);
  leaflet7R6.rotation.set(deg(37.6177), deg(52.5257), deg(-58.8843));
  leaflet7R6.scale.set(0.0447, 0.005, 0.0179);
  frond6.add(leaflet7R6);
  const frond7 = new THREE.Group();
  frond7.name = 'frond7';
  frond7.position.set(0, 0.021, 0);
  frond7.rotation.set(0, deg(296.2032), 0);
  fern.add(frond7);
  const rachis17 = new THREE.Mesh(new THREE.CylinderGeometry(0.008, 0.0086, 0.0956, 4, 1, true), frondDarkMat);
  rachis17.name = 'rachis1';
  rachis17.position.set(0.0096, 0.0439, 0);
  rachis17.rotation.set(0, 0, deg(-12.3298));
  frond7.add(rachis17);
  const rachis27 = new THREE.Mesh(new THREE.CylinderGeometry(0.0072, 0.0079, 0.0956, 4, 1, true), frondDarkMat);
  rachis27.name = 'rachis2';
  rachis27.position.set(0.0352, 0.1297, 0);
  rachis27.rotation.set(0, 0, deg(-20.9398));
  frond7.add(rachis27);
  const leaflet1L7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet1L7.name = 'leaflet1L';
  leaflet1L7.position.set(0.0817, 0.1976, 0.0638);
  leaflet1L7.rotation.set(deg(59.5065), deg(-18.249), deg(64.8236));
  leaflet1L7.scale.set(0.0753, 0.0057, 0.0301);
  frond7.add(leaflet1L7);
  const leaflet1R7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet1R7.name = 'leaflet1R';
  leaflet1R7.position.set(0.0817, 0.1976, -0.0638);
  leaflet1R7.rotation.set(deg(-59.5065), deg(18.249), deg(64.8236));
  leaflet1R7.scale.set(0.0753, 0.0057, 0.0301);
  frond7.add(leaflet1R7);
  const rachis37 = new THREE.Mesh(new THREE.CylinderGeometry(0.0065, 0.0071, 0.0956, 4, 1, true), frondDarkMat);
  rachis37.name = 'rachis3';
  rachis37.position.set(0.0756, 0.2094, 0);
  rachis37.rotation.set(0, 0, deg(-32.8078));
  frond7.add(rachis37);
  const leaflet2L7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet2L7.name = 'leaflet2L';
  leaflet2L7.position.set(0.1416, 0.2698, 0.0757);
  leaflet2L7.rotation.set(deg(56.8002), deg(-28.3433), deg(58.0138));
  leaflet2L7.scale.set(0.0894, 0.0057, 0.0358);
  frond7.add(leaflet2L7);
  const leaflet2R7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet2R7.name = 'leaflet2R';
  leaflet2R7.position.set(0.1416, 0.2698, -0.0757);
  leaflet2R7.rotation.set(deg(-56.8002), deg(28.3433), deg(58.0138));
  leaflet2R7.scale.set(0.0894, 0.0057, 0.0358);
  frond7.add(leaflet2R7);
  const rachis47 = new THREE.Mesh(new THREE.CylinderGeometry(0.0058, 0.0064, 0.0956, 4, 1, true), frondDarkMat);
  rachis47.name = 'rachis4';
  rachis47.position.set(0.1324, 0.2781, 0);
  rachis47.rotation.set(0, 0, deg(-46.3237));
  frond7.add(rachis47);
  const leaflet3L7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet3L7.name = 'leaflet3L';
  leaflet3L7.position.set(0.2142, 0.3224, 0.0816);
  leaflet3L7.rotation.set(deg(51.4652), deg(-39.3255), deg(48.4913));
  leaflet3L7.scale.set(0.0962, 0.0057, 0.0385);
  frond7.add(leaflet3L7);
  const leaflet3R7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet3R7.name = 'leaflet3R';
  leaflet3R7.position.set(0.2142, 0.3224, -0.0816);
  leaflet3R7.rotation.set(deg(-51.4652), deg(39.3255), deg(48.4913));
  leaflet3R7.scale.set(0.0962, 0.0057, 0.0385);
  frond7.add(leaflet3R7);
  const rachis57 = new THREE.Mesh(new THREE.CylinderGeometry(0.005, 0.0057, 0.0956, 4, 1, true), frondDarkMat);
  rachis57.name = 'rachis5';
  rachis57.position.set(0.2042, 0.3309, 0);
  rachis57.rotation.set(0, 0, deg(-61.0349));
  frond7.add(rachis57);
  const leaflet4L7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet4L7.name = 'leaflet4L';
  leaflet4L7.position.set(0.2944, 0.3529, 0.0813);
  leaflet4L7.rotation.set(deg(41.364), deg(-50.0508), deg(34.2275));
  leaflet4L7.scale.set(0.0959, 0.0057, 0.0384);
  frond7.add(leaflet4L7);
  const leaflet4R7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet4R7.name = 'leaflet4R';
  leaflet4R7.position.set(0.2944, 0.3529, -0.0813);
  leaflet4R7.rotation.set(deg(-41.364), deg(50.0508), deg(34.2275));
  leaflet4R7.scale.set(0.0959, 0.0057, 0.0384);
  frond7.add(leaflet4R7);
  const rachis67 = new THREE.Mesh(new THREE.CylinderGeometry(0.0043, 0.0049, 0.0956, 4, 1, true), frondDarkMat);
  rachis67.name = 'rachis6';
  rachis67.position.set(0.2872, 0.3629, 0);
  rachis67.rotation.set(0, 0, deg(-76.704));
  frond7.add(rachis67);
  const leaflet5L7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet5L7.name = 'leaflet5L';
  leaflet5L7.position.set(0.3761, 0.3609, 0.0749);
  leaflet5L7.rotation.set(deg(22.6922), deg(-58.5097), deg(11.3938));
  leaflet5L7.scale.set(0.0884, 0.0057, 0.0354);
  frond7.add(leaflet5L7);
  const leaflet5R7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet5R7.name = 'leaflet5R';
  leaflet5R7.position.set(0.3761, 0.3609, -0.0749);
  leaflet5R7.rotation.set(deg(-22.6922), deg(58.5097), deg(11.3938));
  leaflet5R7.scale.set(0.0884, 0.0057, 0.0354);
  frond7.add(leaflet5R7);
  const rachis77 = new THREE.Mesh(new THREE.CylinderGeometry(0.0035, 0.0042, 0.0956, 4, 1, true), frondDarkMat);
  rachis77.name = 'rachis7';
  rachis77.position.set(0.3757, 0.3708, 0);
  rachis77.rotation.set(0, 0, deg(-93.1814));
  frond7.add(rachis77);
  const leaflet6L7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet6L7.name = 'leaflet6L';
  leaflet6L7.position.set(0.4538, 0.3477, 0.0624);
  leaflet6L7.rotation.set(deg(-5.7618), deg(-61.0291), deg(-21.3071));
  leaflet6L7.scale.set(0.0737, 0.0057, 0.0295);
  frond7.add(leaflet6L7);
  const leaflet6R7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet6R7.name = 'leaflet6R';
  leaflet6R7.position.set(0.4538, 0.3477, -0.0624);
  leaflet6R7.rotation.set(deg(5.7618), deg(61.0291), deg(-21.3071));
  leaflet6R7.scale.set(0.0737, 0.0057, 0.0295);
  frond7.add(leaflet6R7);
  const rachis87 = new THREE.Mesh(new THREE.CylinderGeometry(0.0028, 0.0034, 0.0956, 4, 1, true), frondDarkMat);
  rachis87.name = 'rachis8';
  rachis87.position.set(0.4626, 0.3527, 0);
  rachis87.rotation.set(0, 0, deg(-110.3627));
  frond7.add(rachis87);
  const leaflet7L7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet7L7.name = 'leaflet7L';
  leaflet7L7.position.set(0.5226, 0.3165, 0.0434);
  leaflet7L7.rotation.set(deg(-32.3198), deg(-55.2312), deg(-52.33));
  leaflet7L7.scale.set(0.0512, 0.0057, 0.0205);
  frond7.add(leaflet7L7);
  const leaflet7R7 = new THREE.Mesh(octahedronGeo, frondDarkMat);
  leaflet7R7.name = 'leaflet7R';
  leaflet7R7.position.set(0.5226, 0.3165, -0.0434);
  leaflet7R7.rotation.set(deg(32.3198), deg(55.2312), deg(-52.33));
  leaflet7R7.scale.set(0.0512, 0.0057, 0.0205);
  frond7.add(leaflet7R7);
  const crown = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.042, 0), 0.0056, 3), crownMat);
  crown.name = 'crown';
  crown.position.set(0, 0.021, 0);
  crown.scale.set(1, 0.7, 1);
  fern.add(crown);
  const fiddleStem1 = new THREE.Mesh(new THREE.CylinderGeometry(0.0077, 0.0091, 0.21, 4), frondDarkMat);
  fiddleStem1.name = 'fiddleStem1';
  fiddleStem1.position.set(0.0175, 0.119, 0);
  fern.add(fiddleStem1);
  const fiddlehead1 = new THREE.Mesh(torusGeo, frondLightMat);
  fiddlehead1.name = 'fiddlehead1';
  fiddlehead1.position.set(0.049, 0.224, 0);
  fern.add(fiddlehead1);
  const fiddleStem2 = new THREE.Mesh(new THREE.CylinderGeometry(0.0077, 0.0091, 0.154, 4), frondDarkMat);
  fiddleStem2.name = 'fiddleStem2';
  fiddleStem2.position.set(-0.0175, 0.091, 0);
  fern.add(fiddleStem2);
  const fiddlehead2 = new THREE.Mesh(torusGeo, frondLightMat);
  fiddlehead2.name = 'fiddlehead2';
  fiddlehead2.position.set(-0.049, 0.168, 0);
  fiddlehead2.rotation.set(0, deg(180), 0);
  fern.add(fiddlehead2);

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

export default createFern;
```

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