# Bookshelf

> A low-poly wooden bookcase with a crown top and kick plinth, filled with rows of colorful books in random heights and widths, including leaning books and small flat stacks. Set the number of shelves, width and how full it is. Ideal for libraries, studies, wizard towers and cozy interiors.

![Bookshelf preview](https://codels.download/m/bookshelf.png)

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

## Facts

- Category: Props › Furniture
- Size (W × H × D): 0.94 × 1.51 × 0.35 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 1,044 · Meshes: 87 · Materials: 9
- License: CC0-1.0 (Codels built-in)
- Tags: book, bookshelf, library, shelf, low-poly, stylized, fantasy, medieval, modern, office, interior, adventure, rpg, decoration, furniture, prop, paper, wood, tall, mobile-friendly, parametric, color-brown, multicolor, size-medium, poly-low
- Page: https://codels.download/models/bookshelf

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `shelves` | int | 2 – 6 | 4 | 4 |
| `fill` | number | 0 – 1 | 0.8 | 0.8 |
| `width` | number | 0.6 – 1.4 | 0.9 | 0.9 |
| `wood` | color | #rrggbb | #8a5a33 | #8a5a33 |

## Parts

- side (box · wood)
- side (box · wood)
- back (box · woodDark)
- plinth (box · woodDark)
- crown (box · wood)
- crownTrim (box · woodDark)
- shelf1 (box · wood)
- book (box · blue)
- spineBand (box · gilt)
- book (box · mustard)
- book (box · red)
- book (box · teal)
- book (box · green)
- book (box · teal)
- spineBand (box · gilt)
- bookLeaning (box · green)
- book (box · green)
- book (box · teal)
- spineBand (box · gilt)
- book (box · green)
- book (box · mustard)
- book (box · cream)
- spineBand (box · gilt)
- book (box · blue)
- book (box · cream)
- bookLeaning (box · teal)
- shelf2 (box · wood)
- book (box · teal)
- book (box · teal)
- book (box · mustard)
- book (box · green)
- book (box · green)
- bookLeaning (box · mustard)
- book (box · green)
- spineBand (box · gilt)
- book (box · teal)
- book (box · green)
- book (box · teal)
- book (box · blue)
- book (box · green)

## How to use

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

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

## Code

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

const deg = THREE.MathUtils.degToRad;

export function createBookshelf() {
  const root = new THREE.Group();
  root.name = 'Bookshelf';

  // Materials
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x8a5a33, roughness: 0.85, flatShading: true });
  const woodDarkMat = new THREE.MeshStandardMaterial({ name: 'woodDark', color: 0x4c321c, roughness: 0.95, flatShading: true });
  const redMat = new THREE.MeshStandardMaterial({ name: 'red', color: 0x9e3d38, roughness: 0.8, flatShading: true });
  const blueMat = new THREE.MeshStandardMaterial({ name: 'blue', color: 0x3b5878, roughness: 0.8, flatShading: true });
  const greenMat = new THREE.MeshStandardMaterial({ name: 'green', color: 0x4b6f44, roughness: 0.8, flatShading: true });
  const mustardMat = new THREE.MeshStandardMaterial({ name: 'mustard', color: 0xc49242, roughness: 0.8, flatShading: true });
  const creamMat = new THREE.MeshStandardMaterial({ name: 'cream', color: 0xd9cbab, roughness: 0.85, flatShading: true });
  const tealMat = new THREE.MeshStandardMaterial({ name: 'teal', color: 0x2e6163, roughness: 0.8, flatShading: true });
  const giltMat = new THREE.MeshStandardMaterial({ name: 'gilt', color: 0xe2c26a, roughness: 0.4, metalness: 0.3, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.03, 1.48, 0.32);
  const boxGeo2 = new THREE.BoxGeometry(0.84, 0.025, 0.293);

  // Parts
  const side = new THREE.Mesh(boxGeo, woodMat);
  side.name = 'side';
  side.position.set(-0.435, 0.74, 0);
  root.add(side);
  const side2 = new THREE.Mesh(boxGeo, woodMat);
  side2.name = 'side';
  side2.position.set(0.435, 0.74, 0);
  root.add(side2);
  const back = new THREE.Mesh(new THREE.BoxGeometry(0.84, 1.46, 0.012), woodDarkMat);
  back.name = 'back';
  back.position.set(0, 0.75, -0.154);
  root.add(back);
  const plinth = new THREE.Mesh(new THREE.BoxGeometry(0.84, 0.055, 0.278), woodDarkMat);
  plinth.name = 'plinth';
  plinth.position.set(0, 0.0275, -0.009);
  root.add(plinth);
  const crown = new THREE.Mesh(new THREE.BoxGeometry(0.94, 0.035, 0.35), woodMat);
  crown.name = 'crown';
  crown.position.set(0, 1.4975, 0.005);
  root.add(crown);
  const crownTrim = new THREE.Mesh(new THREE.BoxGeometry(0.91, 0.02, 0.33), woodDarkMat);
  crownTrim.name = 'crownTrim';
  crownTrim.position.set(0, 1.468, 0.002);
  root.add(crownTrim);
  const shelf1 = new THREE.Mesh(boxGeo2, woodMat);
  shelf1.name = 'shelf1';
  shelf1.position.set(0, 0.0675, -0.0015);
  root.add(shelf1);
  const book = new THREE.Mesh(new THREE.BoxGeometry(0.0515, 0.2831, 0.1719), blueMat);
  book.name = 'book';
  book.position.set(-0.3883, 0.2216, 0.0513);
  root.add(book);
  const spineBand = new THREE.Mesh(new THREE.BoxGeometry(0.0535, 0.012, 0.004), giltMat);
  spineBand.name = 'spineBand';
  spineBand.position.set(-0.3883, 0.3065, 0.1382);
  root.add(spineBand);
  const book2 = new THREE.Mesh(new THREE.BoxGeometry(0.032, 0.2406, 0.2181), mustardMat);
  book2.name = 'book';
  book2.position.set(-0.3445, 0.2003, 0.0206);
  root.add(book2);
  const book3 = new THREE.Mesh(new THREE.BoxGeometry(0.0293, 0.2054, 0.2238), redMat);
  book3.name = 'book';
  book3.position.set(-0.3119, 0.1827, 0.0163);
  root.add(book3);
  const book4 = new THREE.Mesh(new THREE.BoxGeometry(0.0519, 0.2608, 0.2145), tealMat);
  book4.name = 'book';
  book4.position.set(-0.2693, 0.2104, 0.0298);
  root.add(book4);
  const book5 = new THREE.Mesh(new THREE.BoxGeometry(0.0509, 0.2045, 0.2263), greenMat);
  book5.name = 'book';
  book5.position.set(-0.2159, 0.1823, 0.0194);
  root.add(book5);
  const book6 = new THREE.Mesh(new THREE.BoxGeometry(0.0503, 0.216, 0.1968), tealMat);
  book6.name = 'book';
  book6.position.set(-0.1633, 0.188, 0.0193);
  root.add(book6);
  const spineBand2 = new THREE.Mesh(new THREE.BoxGeometry(0.0523, 0.012, 0.004), giltMat);
  spineBand2.name = 'spineBand';
  spineBand2.position.set(-0.1633, 0.2528, 0.1187);
  root.add(spineBand2);
  const bookLeaning = new THREE.Mesh(new THREE.BoxGeometry(0.0329, 0.1907, 0.1915), greenMat);
  bookLeaning.name = 'bookLeaning';
  bookLeaning.position.set(-0.0878, 0.1752, 0.0383);
  bookLeaning.rotation.set(0, 0, deg(20.1543));
  root.add(bookLeaning);
  const book7 = new THREE.Mesh(new THREE.BoxGeometry(0.031, 0.2041, 0.1931), greenMat);
  book7.name = 'book';
  book7.position.set(0.034, 0.1821, 0.0319);
  root.add(book7);
  const book8 = new THREE.Mesh(new THREE.BoxGeometry(0.0512, 0.2027, 0.1897), tealMat);
  book8.name = 'book';
  book8.position.set(0.0771, 0.1814, 0.0242);
  root.add(book8);
  const spineBand3 = new THREE.Mesh(new THREE.BoxGeometry(0.0532, 0.012, 0.004), giltMat);
  spineBand3.name = 'spineBand';
  spineBand3.position.set(0.0771, 0.2421, 0.1201);
  root.add(spineBand3);
  const book9 = new THREE.Mesh(new THREE.BoxGeometry(0.033, 0.2683, 0.2204), greenMat);
  book9.name = 'book';
  book9.position.set(0.1211, 0.2142, 0.0171);
  root.add(book9);
  const book10 = new THREE.Mesh(new THREE.BoxGeometry(0.0307, 0.2083, 0.1768), mustardMat);
  book10.name = 'book';
  book10.position.set(0.155, 0.1842, 0.0491);
  root.add(book10);
  const book11 = new THREE.Mesh(new THREE.BoxGeometry(0.0453, 0.2288, 0.1702), creamMat);
  book11.name = 'book';
  book11.position.set(0.195, 0.1944, 0.0419);
  root.add(book11);
  const spineBand4 = new THREE.Mesh(new THREE.BoxGeometry(0.0473, 0.012, 0.004), giltMat);
  spineBand4.name = 'spineBand';
  spineBand4.position.set(0.195, 0.2631, 0.128);
  root.add(spineBand4);
  const book12 = new THREE.Mesh(new THREE.BoxGeometry(0.0409, 0.2839, 0.1967), blueMat);
  book12.name = 'book';
  book12.position.set(0.2401, 0.222, 0.0393);
  root.add(book12);
  const book13 = new THREE.Mesh(new THREE.BoxGeometry(0.0256, 0.2016, 0.1893), creamMat);
  book13.name = 'book';
  book13.position.set(0.2753, 0.1808, 0.0314);
  root.add(book13);
  const bookLeaning2 = new THREE.Mesh(new THREE.BoxGeometry(0.0257, 0.1778, 0.2099), tealMat);
  bookLeaning2.name = 'bookLeaning';
  bookLeaning2.position.set(0.3336, 0.1677, 0.0143);
  bookLeaning2.rotation.set(0, 0, deg(20.7318));
  root.add(bookLeaning2);
  const shelf2 = new THREE.Mesh(boxGeo2, woodMat);
  shelf2.name = 'shelf2';
  shelf2.position.set(0, 0.4125, -0.0015);
  root.add(shelf2);
  const book14 = new THREE.Mesh(new THREE.BoxGeometry(0.0458, 0.2217, 0.2236), tealMat);
  book14.name = 'book';
  book14.position.set(-0.3911, 0.5359, 0.0221);
  root.add(book14);
  const book15 = new THREE.Mesh(new THREE.BoxGeometry(0.0305, 0.2093, 0.2236), tealMat);
  book15.name = 'book';
  book15.position.set(-0.351, 0.5297, 0.0095);
  root.add(book15);
  const book16 = new THREE.Mesh(new THREE.BoxGeometry(0.0299, 0.2388, 0.1923), mustardMat);
  book16.name = 'book';
  book16.position.set(-0.3188, 0.5444, 0.0403);
  root.add(book16);
  const book17 = new THREE.Mesh(new THREE.BoxGeometry(0.0491, 0.2661, 0.226), greenMat);
  book17.name = 'book';
  book17.position.set(-0.2772, 0.5581, 0.0136);
  root.add(book17);
  const book18 = new THREE.Mesh(new THREE.BoxGeometry(0.0244, 0.2238, 0.2066), greenMat);
  book18.name = 'book';
  book18.position.set(-0.2385, 0.5369, 0.026);
  root.add(book18);
  const bookLeaning3 = new THREE.Mesh(new THREE.BoxGeometry(0.0278, 0.1801, 0.1809), mustardMat);
  bookLeaning3.name = 'bookLeaning';
  bookLeaning3.position.set(-0.1805, 0.5144, 0.0378);
  bookLeaning3.rotation.set(0, 0, deg(19.9778));
  root.add(bookLeaning3);
  const book19 = new THREE.Mesh(new THREE.BoxGeometry(0.0505, 0.2787, 0.2111), greenMat);
  book19.name = 'book';
  book19.position.set(-0.0643, 0.5644, 0.0151);
  root.add(book19);
  const spineBand5 = new THREE.Mesh(new THREE.BoxGeometry(0.0525, 0.012, 0.004), giltMat);
  spineBand5.name = 'spineBand';
  spineBand5.position.set(-0.0643, 0.648, 0.1216);
  root.add(spineBand5);
  const book20 = new THREE.Mesh(new THREE.BoxGeometry(0.0243, 0.269, 0.2074), tealMat);
  book20.name = 'book';
  book20.position.set(-0.0249, 0.5595, 0.0147);
  root.add(book20);
  const book21 = new THREE.Mesh(new THREE.BoxGeometry(0.0257, 0.2744, 0.2104), greenMat);
  book21.name = 'book';
  book21.position.set(0.0021, 0.5622, 0.0239);
  root.add(book21);
  const book22 = new THREE.Mesh(new THREE.BoxGeometry(0.0496, 0.2827, 0.1971), tealMat);
  book22.name = 'book';
  book22.position.set(0.0417, 0.5664, 0.0253);
  root.add(book22);
  const book23 = new THREE.Mesh(new THREE.BoxGeometry(0.043, 0.2817, 0.1776), blueMat);
  book23.name = 'book';
  book23.position.set(0.09, 0.5659, 0.0346);
  root.add(book23);
  const book24 = new THREE.Mesh(new THREE.BoxGeometry(0.041, 0.2559, 0.1772), greenMat);
  book24.name = 'book';
  book24.position.set(0.134, 0.553, 0.0347);
  root.add(book24);
  const spineBand6 = new THREE.Mesh(new THREE.BoxGeometry(0.043, 0.012, 0.004), giltMat);
  spineBand6.name = 'spineBand';
  spineBand6.position.set(0.134, 0.6298, 0.1243);
  root.add(spineBand6);
  const bookLeaning4 = new THREE.Mesh(new THREE.BoxGeometry(0.0324, 0.2339, 0.1876), tealMat);
  bookLeaning4.name = 'bookLeaning';
  bookLeaning4.position.set(0.2159, 0.5393, 0.0402);
  bookLeaning4.rotation.set(0, 0, deg(22.3458));
  root.add(bookLeaning4);
  const book25 = new THREE.Mesh(new THREE.BoxGeometry(0.0366, 0.2465, 0.1835), blueMat);
  book25.name = 'book';
  book25.position.set(0.3515, 0.5483, 0.0361);
  root.add(book25);
  const book26 = new THREE.Mesh(new THREE.BoxGeometry(0.0422, 0.2454, 0.2171), blueMat);
  book26.name = 'book';
  book26.position.set(0.3929, 0.5477, 0.0085);
  root.add(book26);
  const spineBand7 = new THREE.Mesh(new THREE.BoxGeometry(0.0442, 0.012, 0.004), giltMat);
  spineBand7.name = 'spineBand';
  spineBand7.position.set(0.3929, 0.6213, 0.118);
  root.add(spineBand7);
  const shelf3 = new THREE.Mesh(boxGeo2, woodMat);
  shelf3.name = 'shelf3';
  shelf3.position.set(0, 0.7575, -0.0015);
  root.add(shelf3);
  const book27 = new THREE.Mesh(new THREE.BoxGeometry(0.0409, 0.2472, 0.2237), blueMat);
  book27.name = 'book';
  book27.position.set(-0.239, 0.8936, 0.0193);
  root.add(book27);
  const book28 = new THREE.Mesh(new THREE.BoxGeometry(0.0344, 0.2671, 0.2289), creamMat);
  book28.name = 'book';
  book28.position.set(-0.1994, 0.9036, 0.011);
  root.add(book28);
  const book29 = new THREE.Mesh(new THREE.BoxGeometry(0.035, 0.2556, 0.2292), tealMat);
  book29.name = 'book';
  book29.position.set(-0.1627, 0.8978, 0.0105);
  root.add(book29);
  const book30 = new THREE.Mesh(new THREE.BoxGeometry(0.0382, 0.2061, 0.1959), redMat);
  book30.name = 'book';
  book30.position.set(-0.1241, 0.8731, 0.0413);
  root.add(book30);
  const book31 = new THREE.Mesh(new THREE.BoxGeometry(0.0317, 0.2811, 0.2207), greenMat);
  book31.name = 'book';
  book31.position.set(-0.0871, 0.9106, 0.0274);
  root.add(book31);
  const book32 = new THREE.Mesh(new THREE.BoxGeometry(0.0455, 0.2047, 0.2139), blueMat);
  book32.name = 'book';
  book32.position.set(-0.0465, 0.8724, 0.0087);
  root.add(book32);
  const book33 = new THREE.Mesh(new THREE.BoxGeometry(0.0339, 0.2706, 0.1739), blueMat);
  book33.name = 'book';
  book33.position.set(-0.0049, 0.9053, 0.0356);
  root.add(book33);
  const book34 = new THREE.Mesh(new THREE.BoxGeometry(0.0372, 0.245, 0.1935), blueMat);
  book34.name = 'book';
  book34.position.set(0.0327, 0.8925, 0.0422);
  root.add(book34);
  const book35 = new THREE.Mesh(new THREE.BoxGeometry(0.0467, 0.2168, 0.2055), blueMat);
  book35.name = 'book';
  book35.position.set(0.0766, 0.8784, 0.0323);
  root.add(book35);
  const spineBand8 = new THREE.Mesh(new THREE.BoxGeometry(0.0487, 0.012, 0.004), giltMat);
  spineBand8.name = 'spineBand';
  spineBand8.position.set(0.0766, 0.9435, 0.1361);
  root.add(spineBand8);
  const book36 = new THREE.Mesh(new THREE.BoxGeometry(0.0301, 0.2493, 0.1942), greenMat);
  book36.name = 'book';
  book36.position.set(0.117, 0.8947, 0.018);
  root.add(book36);
  const book37 = new THREE.Mesh(new THREE.BoxGeometry(0.0348, 0.2027, 0.1738), mustardMat);
  book37.name = 'book';
  book37.position.set(0.1514, 0.8714, 0.0478);
  root.add(book37);
  const book38 = new THREE.Mesh(new THREE.BoxGeometry(0.0448, 0.2584, 0.1756), tealMat);
  book38.name = 'book';
  book38.position.set(0.1932, 0.8992, 0.0502);
  root.add(book38);
  const spineBand9 = new THREE.Mesh(new THREE.BoxGeometry(0.0468, 0.012, 0.004), giltMat);
  spineBand9.name = 'spineBand';
  spineBand9.position.set(0.1932, 0.9768, 0.139);
  root.add(spineBand9);
  const book39 = new THREE.Mesh(new THREE.BoxGeometry(0.046, 0.2289, 0.1846), greenMat);
  book39.name = 'book';
  book39.position.set(0.2406, 0.8845, 0.03);
  root.add(book39);
  const book40 = new THREE.Mesh(new THREE.BoxGeometry(0.0299, 0.2351, 0.2285), tealMat);
  book40.name = 'book';
  book40.position.set(0.2806, 0.8876, 0.0173);
  root.add(book40);
  const book41 = new THREE.Mesh(new THREE.BoxGeometry(0.0497, 0.2559, 0.1721), mustardMat);
  book41.name = 'book';
  book41.position.set(0.3224, 0.898, 0.0507);
  root.add(book41);
  const spineBand10 = new THREE.Mesh(new THREE.BoxGeometry(0.0517, 0.012, 0.004), giltMat);
  spineBand10.name = 'spineBand';
  spineBand10.position.set(0.3224, 0.9747, 0.1377);
  root.add(spineBand10);
  const book42 = new THREE.Mesh(new THREE.BoxGeometry(0.0319, 0.2748, 0.2192), greenMat);
  book42.name = 'book';
  book42.position.set(0.3652, 0.9074, 0.0284);
  root.add(book42);
  const book43 = new THREE.Mesh(new THREE.BoxGeometry(0.0309, 0.2543, 0.1703), mustardMat);
  book43.name = 'book';
  book43.position.set(0.3986, 0.8972, 0.0407);
  root.add(book43);
  const shelf4 = new THREE.Mesh(boxGeo2, woodMat);
  shelf4.name = 'shelf4';
  shelf4.position.set(0, 1.1025, -0.0015);
  root.add(shelf4);
  const book44 = new THREE.Mesh(new THREE.BoxGeometry(0.0389, 0.2281, 0.2224), blueMat);
  book44.name = 'book';
  book44.position.set(-0.3946, 1.2291, 0.0182);
  root.add(book44);
  const book45 = new THREE.Mesh(new THREE.BoxGeometry(0.0324, 0.2064, 0.2179), tealMat);
  book45.name = 'book';
  book45.position.set(-0.357, 1.2182, 0.0177);
  root.add(book45);
  const book46 = new THREE.Mesh(new THREE.BoxGeometry(0.0382, 0.2212, 0.2195), creamMat);
  book46.name = 'book';
  book46.position.set(-0.3197, 1.2256, 0.0156);
  root.add(book46);
  const book47 = new THREE.Mesh(new THREE.BoxGeometry(0.0296, 0.2225, 0.1851), greenMat);
  book47.name = 'book';
  book47.position.set(-0.2838, 1.2263, 0.0371);
  root.add(book47);
  const book48 = new THREE.Mesh(new THREE.BoxGeometry(0.0372, 0.2599, 0.1771), tealMat);
  book48.name = 'book';
  book48.position.set(-0.2484, 1.245, 0.0295);
  root.add(book48);
  const book49 = new THREE.Mesh(new THREE.BoxGeometry(0.0491, 0.2477, 0.1941), redMat);
  book49.name = 'book';
  book49.position.set(-0.2033, 1.2389, 0.0196);
  root.add(book49);
  const spineBand11 = new THREE.Mesh(new THREE.BoxGeometry(0.0511, 0.012, 0.004), giltMat);
  spineBand11.name = 'spineBand';
  spineBand11.position.set(-0.2033, 1.3132, 0.1177);
  root.add(spineBand11);
  const book50 = new THREE.Mesh(new THREE.BoxGeometry(0.0492, 0.2343, 0.1743), creamMat);
  book50.name = 'book';
  book50.position.set(-0.1522, 1.2322, 0.0414);
  root.add(book50);
  const book51 = new THREE.Mesh(new THREE.BoxGeometry(0.0349, 0.2383, 0.2296), blueMat);
  book51.name = 'book';
  book51.position.set(-0.1081, 1.2342, 0.006);
  root.add(book51);
  const book52 = new THREE.Mesh(new THREE.BoxGeometry(0.0314, 0.2149, 0.1748), greenMat);
  book52.name = 'book';
  book52.position.set(-0.0729, 1.2225, 0.0421);
  root.add(book52);
  const book53 = new THREE.Mesh(new THREE.BoxGeometry(0.028, 0.266, 0.2042), creamMat);
  book53.name = 'book';
  book53.position.set(-0.0412, 1.248, 0.0354);
  root.add(book53);
  const book54 = new THREE.Mesh(new THREE.BoxGeometry(0.0362, 0.2833, 0.1832), redMat);
  book54.name = 'book';
  book54.position.set(-0.0071, 1.2567, 0.0392);
  root.add(book54);
  const book55 = new THREE.Mesh(new THREE.BoxGeometry(0.0448, 0.2444, 0.2063), blueMat);
  book55.name = 'book';
  book55.position.set(0.0355, 1.2372, 0.024);
  root.add(book55);
  const book56 = new THREE.Mesh(new THREE.BoxGeometry(0.0252, 0.2056, 0.1909), redMat);
  book56.name = 'book';
  book56.position.set(0.0725, 1.2178, 0.0259);
  root.add(book56);
  const book57 = new THREE.Mesh(new THREE.BoxGeometry(0.0487, 0.2194, 0.1759), blueMat);
  book57.name = 'book';
  book57.position.set(0.1114, 1.2247, 0.0394);
  root.add(book57);
  const book58 = new THREE.Mesh(new THREE.BoxGeometry(0.0357, 0.2736, 0.2046), redMat);
  book58.name = 'book';
  book58.position.set(0.1556, 1.2518, 0.0173);
  root.add(book58);
  const book59 = new THREE.Mesh(new THREE.BoxGeometry(0.0359, 0.2281, 0.2292), creamMat);
  book59.name = 'book';
  book59.position.set(0.1934, 1.2291, 0.0194);
  root.add(book59);
  const bookLeaning5 = new THREE.Mesh(new THREE.BoxGeometry(0.0317, 0.1992, 0.1713), mustardMat);
  bookLeaning5.name = 'bookLeaning';
  bookLeaning5.position.set(0.2561, 1.2151, 0.0504);
  bookLeaning5.rotation.set(0, 0, deg(16.0143));
  root.add(bookLeaning5);
  const book60 = new THREE.Mesh(new THREE.BoxGeometry(0.0255, 0.2441, 0.17), tealMat);
  book60.name = 'book';
  book60.position.set(0.3799, 1.2371, 0.031);
  root.add(book60);
  const topBoard = new THREE.Mesh(new THREE.BoxGeometry(0.84, 0.045, 0.293), woodMat);
  topBoard.name = 'topBoard';
  topBoard.position.set(0, 1.4575, -0.0015);
  root.add(topBoard);

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

export default createBookshelf;
```

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