1024 Tris4,48 × 4,55 × 4,10 m
Im Code verwenden
Im Editor remixenoak-tree.js · 160 Zeilen
Eigenständiges ES-Modul — hängt nur von three ab. Ruf die Factory auf und füge die Gruppe deiner Szene hinzu.
/**
* Oak Tree — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,024 · Size (W × H × D): 4.48 × 4.55 × 4.10 m
*
* Usage:
* import { createOakTree } from './oak-tree.js';
*
* const model = createOakTree();
* 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 createOakTree() {
const root = new THREE.Group();
root.name = 'OakTree';
// Materials
const barkMat = new THREE.MeshStandardMaterial({ name: 'bark', color: 0x6a4a30, roughness: 0.95, flatShading: true });
const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x4f8a3c, roughness: 0.85, flatShading: true });
const leafLightMat = new THREE.MeshStandardMaterial({ name: 'leafLight', color: 0x579b4b, roughness: 0.85, flatShading: true });
const leafDarkMat = new THREE.MeshStandardMaterial({ name: 'leafDark', color: 0x446c2f, roughness: 0.9, flatShading: true });
// Parts
const trunk = new THREE.Mesh(lathe([[0, 0], [0.484, 0], [0.3691, 0.22], [0.3086, 0.66], [0.2602, 1.386], [0.2178, 2.5245], [0, 2.5245]], 7), barkMat);
trunk.name = 'trunk';
root.add(trunk);
const root1 = new THREE.Mesh(new THREE.CylinderGeometry(0.0484, 0.1664, 0.5334, 5), barkMat);
root1.name = 'root1';
root1.position.set(0.2672, 0.1376, 0.2593);
root1.rotation.set(deg(61.756), deg(-41.8357), deg(-65.1734));
root.add(root1);
const root2 = new THREE.Mesh(new THREE.CylinderGeometry(0.0484, 0.1664, 0.506, 5), barkMat);
root2.name = 'root2';
root2.position.set(-0.2242, 0.1376, 0.2788);
root2.rotation.set(deg(76.239), deg(41.3475), deg(51.3666));
root.add(root2);
const root3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0484, 0.1664, 0.5461, 5), barkMat);
root3.name = 'root3';
root3.position.set(-0.3168, 0.1376, -0.2081);
root3.rotation.set(deg(-40.8562), deg(-37.5094), deg(84.7073));
root.add(root3);
const root4 = new THREE.Mesh(new THREE.CylinderGeometry(0.0484, 0.1664, 0.5178, 5), barkMat);
root4.name = 'root4';
root4.position.set(0.2847, 0.1376, -0.2268);
root4.rotation.set(deg(-50.7354), deg(40.943), deg(-76.4303));
root.add(root4);
const branch1 = new THREE.Mesh(new THREE.CylinderGeometry(0.0545, 0.1513, 1.839, 5), barkMat);
branch1.name = 'branch1';
branch1.position.set(0.5375, 2.3984, -0.1326);
branch1.rotation.set(deg(-8.2997), deg(2.686), deg(-35.8133));
root.add(branch1);
const branch2 = new THREE.Mesh(new THREE.CylinderGeometry(0.0545, 0.1513, 1.8104, 5), barkMat);
branch2.name = 'branch2';
branch2.position.set(-0.441, 2.3781, 0.3346);
branch2.rotation.set(deg(21.8085), deg(5.7699), deg(29.319));
root.add(branch2);
const branch3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0545, 0.1513, 1.67, 5), barkMat);
branch3.name = 'branch3';
branch3.position.set(-0.3419, 2.2665, -0.4354);
branch3.rotation.set(deg(-31.6931), deg(-7.0126), deg(24.3624));
root.add(branch3);
const canopyCore = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1.2705, 1), 0.1089, 3), leafMat);
canopyCore.name = 'canopyCore';
canopyCore.position.set(0, 3.2505, 0);
canopyCore.scale.set(1.22, 0.8, 1.22);
root.add(canopyCore);
const leaves1 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.8709, 1), 0.0871, 93), leafDarkMat);
leaves1.name = 'leaves1';
leaves1.position.set(1.4456, 2.8664, -0.1705);
leaves1.rotation.set(deg(17.3941), deg(42.9491), 0);
leaves1.scale.set(1, 0.85, 1);
root.add(leaves1);
const leaves2 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.8034, 1), 0.0803, 94), leafDarkMat);
leaves2.name = 'leaves2';
leaves2.position.set(-1.0134, 2.9916, 0.6871);
leaves2.rotation.set(deg(56.4261), deg(217.7235), 0);
leaves2.scale.set(1, 0.85, 1);
root.add(leaves2);
const leaves3 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.7707, 1), 0.0771, 95), leafDarkMat);
leaves3.name = 'leaves3';
leaves3.position.set(-0.2478, 3.0586, -1.4004);
leaves3.rotation.set(deg(45.2744), deg(63.4196), 0);
leaves3.scale.set(1, 0.85, 1);
root.add(leaves3);
const leaves4 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.6626, 1), 0.0663, 96), leafMat);
leaves4.name = 'leaves4';
leaves4.position.set(0.8877, 3.2109, 1.025);
leaves4.rotation.set(deg(0.3043), deg(46.7638), 0);
leaves4.scale.set(1, 0.85, 1);
root.add(leaves4);
const leaves5 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.7747, 1), 0.0775, 97), leafMat);
leaves5.name = 'leaves5';
leaves5.position.set(-1.4184, 3.2607, -0.3301);
leaves5.rotation.set(deg(30.9687), deg(172.3031), 0);
leaves5.scale.set(1, 0.85, 1);
root.add(leaves5);
const leaves6 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.7791, 1), 0.0779, 98), leafLightMat);
leaves6.name = 'leaves6';
leaves6.position.set(1.0184, 3.3453, -0.586);
leaves6.rotation.set(deg(44.6369), deg(153.1454), 0);
leaves6.scale.set(1, 0.85, 1);
root.add(leaves6);
const leaves7 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.7113, 1), 0.0711, 99), leafLightMat);
leaves7.name = 'leaves7';
leaves7.position.set(-0.1581, 3.5786, 1.297);
leaves7.rotation.set(deg(16.0568), deg(101.0846), 0);
leaves7.scale.set(1, 0.85, 1);
root.add(leaves7);
const leaves8 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.6814, 1), 0.0681, 100), leafLightMat);
leaves8.name = 'leaves8';
leaves8.position.set(-0.3694, 3.5426, -0.9875);
leaves8.rotation.set(deg(20.2814), deg(90.0089), 0);
leaves8.scale.set(1, 0.85, 1);
root.add(leaves8);
const leaves9 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.8242, 1), 0.0824, 101), leafLightMat);
leaves9.name = 'leaves9';
leaves9.position.set(0.9016, 3.7622, 0.2995);
leaves9.rotation.set(deg(33.7375), deg(214.1656), 0);
leaves9.scale.set(1, 0.85, 1);
root.add(leaves9);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createOakTree;
Bewertungen & Kommentare
—
Noch keine Bewertungen — gib die erste ab.
5
0
4
0
3
0
2
0
1
0
Melde dich an, um zu bewerten und zu kommentieren.
0 Kommentare
Noch keine Kommentare. Erzähl, wie du dieses Modell genutzt hast oder was besser sein könnte.
Ähnliche Modelle
Gleiche Kategorie oder ähnliche Tags









