358 tris0.57 × 1.31 × 0.64 m
Use it in code
Remix in the editorreeds.js · 193 lines
Self-contained ES module — only depends on three. Call the factory and add the group to your scene.
/**
* Reeds — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 358 · Size (W × H × D): 0.56 × 1.31 × 0.64 m
*
* Usage:
* import { createReeds } from './reeds.js';
*
* const model = createReeds();
* 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 createReeds() {
const root = new THREE.Group();
root.name = 'Reeds';
// Materials
const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x5f8f3c, roughness: 0.85, flatShading: true });
const leafDarkMat = new THREE.MeshStandardMaterial({ name: 'leafDark', color: 0x517230, roughness: 0.9, flatShading: true });
const leafLightMat = new THREE.MeshStandardMaterial({ name: 'leafLight', color: 0x679e51, roughness: 0.85, flatShading: true });
const headMat = new THREE.MeshStandardMaterial({ name: 'head', color: 0x6b4528, roughness: 0.9, flatShading: true });
const mudMat = new THREE.MeshStandardMaterial({ name: 'mud', color: 0x4f3d2c, roughness: 0.95, flatShading: true });
// Parts
const reeds = new THREE.Group();
reeds.name = 'reeds';
reeds.position.set(0, 0.0135, 0);
root.add(reeds);
const mud = new THREE.Mesh(jitter(new THREE.SphereGeometry(0.1989, 8, 2, 0, Math.PI * 2, 0, Math.PI / 2), 0.0127, 5), mudMat);
mud.name = 'mud';
mud.scale.set(1, 0.35, 1);
reeds.add(mud);
const cylinder3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0106, 0.0132, 0.8552, 4), leafDarkMat);
cylinder3.position.set(0.0661, 0.4261, 0.0116);
cylinder3.rotation.set(deg(0.8881), deg(-0.037), deg(-4.7656));
reeds.add(cylinder3);
const capsule4 = new THREE.Mesh(new THREE.CapsuleGeometry(0.0343, 0.1754, 1, 6), headMat);
capsule4.position.set(0.1034, 0.874, 0.0186);
capsule4.rotation.set(deg(0.8881), deg(-0.037), deg(-4.7656));
reeds.add(capsule4);
const cylinder5 = new THREE.Mesh(new THREE.CylinderGeometry(0.0026, 0.0059, 0.1316, 3), leafDarkMat);
cylinder5.position.set(0.1189, 1.0597, 0.0215);
cylinder5.rotation.set(deg(0.8881), deg(-0.037), deg(-4.7656));
reeds.add(cylinder5);
const cylinder6 = new THREE.Mesh(new THREE.CylinderGeometry(0.0106, 0.0132, 0.8738, 4), leafDarkMat);
cylinder6.position.set(-0.0561, 0.4348, -0.0785);
cylinder6.rotation.set(deg(-4.469), deg(-0.1336), deg(3.4234));
reeds.add(cylinder6);
const capsule7 = new THREE.Mesh(new THREE.CapsuleGeometry(0.0343, 0.1792, 1, 6), headMat);
capsule7.position.set(-0.0835, 0.8919, -0.1143);
capsule7.rotation.set(deg(-4.469), deg(-0.1336), deg(3.4234));
reeds.add(capsule7);
const cylinder8 = new THREE.Mesh(new THREE.CylinderGeometry(0.0026, 0.0059, 0.1344, 3), leafDarkMat);
cylinder8.position.set(-0.0949, 1.0814, -0.1291);
cylinder8.rotation.set(deg(-4.469), deg(-0.1336), deg(3.4234));
reeds.add(cylinder8);
const cylinder9 = new THREE.Mesh(new THREE.CylinderGeometry(0.0106, 0.0132, 0.9866, 4), leafDarkMat);
cylinder9.position.set(-0.039, 0.4911, 0.1087);
cylinder9.rotation.set(deg(4.9799), deg(0.0906), deg(2.0842));
reeds.add(cylinder9);
const capsule10 = new THREE.Mesh(new THREE.CapsuleGeometry(0.0343, 0.2024, 1, 6), headMat);
capsule10.position.set(-0.0579, 1.0074, 0.1537);
capsule10.rotation.set(deg(4.9799), deg(0.0906), deg(2.0842));
reeds.add(capsule10);
const cylinder11 = new THREE.Mesh(new THREE.CylinderGeometry(0.0026, 0.0059, 0.1518, 3), leafDarkMat);
cylinder11.position.set(-0.0657, 1.2214, 0.1724);
cylinder11.rotation.set(deg(4.9799), deg(0.0906), deg(2.0842));
reeds.add(cylinder11);
const cylinder12 = new THREE.Mesh(new THREE.CylinderGeometry(0.0106, 0.0132, 0.8944, 4), leafDarkMat);
cylinder12.position.set(0.1334, 0.4433, -0.0449);
cylinder12.rotation.set(deg(-2.3193), deg(0.1459), deg(-7.197));
reeds.add(cylinder12);
const capsule13 = new THREE.Mesh(new THREE.CapsuleGeometry(0.0343, 0.1835, 1, 6), headMat);
capsule13.position.set(0.1923, 0.9094, -0.0639);
capsule13.rotation.set(deg(-2.3193), deg(0.1459), deg(-7.197));
reeds.add(capsule13);
const cylinder14 = new THREE.Mesh(new THREE.CylinderGeometry(0.0026, 0.0059, 0.1376, 3), leafDarkMat);
cylinder14.position.set(0.2167, 1.1026, -0.0718);
cylinder14.rotation.set(deg(-2.3193), deg(0.1459), deg(-7.197));
reeds.add(cylinder14);
const leaf1 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.7819, 3), leafMat);
leaf1.name = 'leaf1';
leaf1.position.set(0.0834, 0.3863, 0.0177);
leaf1.rotation.set(deg(1.8488), deg(-0.0474), deg(-8.6753));
leaf1.scale.set(1, 1, 0.3);
reeds.add(leaf1);
const leaf2 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.6737, 3), leafDarkMat);
leaf2.name = 'leaf2';
leaf2.position.set(-0.0736, 0.3279, 0.095);
leaf2.rotation.set(deg(179.3215), deg(-53.935), deg(166.2592));
leaf2.scale.set(1, 1, 0.3);
reeds.add(leaf2);
const leaf3 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.9698, 3), leafLightMat);
leaf3.name = 'leaf3';
leaf3.position.set(0.023, 0.4697, -0.175);
leaf3.rotation.set(deg(159.0556), deg(74.3323), deg(-173.0954));
leaf3.scale.set(1, 1, 0.3);
reeds.add(leaf3);
const leaf4 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.9459, 3), leafMat);
leaf4.name = 'leaf4';
leaf4.position.set(0.0826, 0.4624, 0.143);
leaf4.rotation.set(deg(6.2069), deg(-35.4548), deg(-7.3945));
leaf4.scale.set(1, 1, 0.3);
reeds.add(leaf4);
const leaf5 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.6226, 3), leafDarkMat);
leaf5.name = 'leaf5';
leaf5.position.set(-0.1497, 0.3014, -0.0295);
leaf5.rotation.set(deg(-171.2666), deg(38.4849), deg(161.7665));
leaf5.scale.set(1, 1, 0.3);
reeds.add(leaf5);
const leaf6 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.6867, 3), leafLightMat);
leaf6.name = 'leaf6';
leaf6.position.set(0.1087, 0.3384, -0.0891);
leaf6.rotation.set(deg(-3.966), deg(16.3781), deg(-7.7948));
leaf6.scale.set(1, 1, 0.3);
reeds.add(leaf6);
const leaf7 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.8051, 3), leafMat);
leaf7.name = 'leaf7';
leaf7.position.set(-0.0695, 0.3971, 0.1394);
leaf7.rotation.set(deg(169.8161), deg(-77.1077), deg(160.9359));
leaf7.scale.set(1, 1, 0.3);
reeds.add(leaf7);
const leaf8 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.9051, 3), leafDarkMat);
leaf8.name = 'leaf8';
leaf8.position.set(-0.1499, 0.4207, -0.2166);
leaf8.rotation.set(deg(-142.169), deg(75.4748), deg(123.258));
leaf8.scale.set(1, 1, 0.3);
reeds.add(leaf8);
const leaf9 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.6763, 3), leafLightMat);
leaf9.name = 'leaf9';
leaf9.position.set(0.1584, 0.325, 0.1159);
leaf9.rotation.set(deg(7.5504), deg(-9.0021), deg(-13.0398));
leaf9.scale.set(1, 1, 0.3);
reeds.add(leaf9);
const leaf10 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.6601, 3), leafMat);
leaf10.name = 'leaf10';
leaf10.position.set(-0.2082, 0.2958, 0.1477);
leaf10.rotation.set(deg(-178.2923), deg(-32.419), deg(154.6094));
leaf10.scale.set(1, 1, 0.3);
reeds.add(leaf10);
const leaf11 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 1.0204, 3), leafDarkMat);
leaf11.name = 'leaf11';
leaf11.position.set(0.142, 0.4886, -0.2193);
leaf11.rotation.set(deg(-9.2408), deg(28.4183), deg(-10.2419));
leaf11.scale.set(1, 1, 0.3);
reeds.add(leaf11);
const leaf12 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.7156, 3), leafLightMat);
leaf12.name = 'leaf12';
leaf12.position.set(0.0198, 0.3473, 0.2049);
leaf12.rotation.set(deg(-159.8922), deg(-77.9397), deg(-173.6231));
leaf12.scale.set(1, 1, 0.3);
reeds.add(leaf12);
const leaf13 = new THREE.Mesh(new THREE.ConeGeometry(0.035, 0.7603, 3), leafMat);
leaf13.name = 'leaf13';
leaf13.position.set(-0.1953, 0.3721, -0.0536);
leaf13.rotation.set(deg(-179.8544), deg(16.0136), deg(168.1689));
leaf13.scale.set(1, 1, 0.3);
reeds.add(leaf13);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createReeds;
Ratings & comments
0 comments
No comments yet. Share how you used this model or what could be better.
Related models
Same category or similar tags









