Codels
1 тыс. треуг.2,23 × 0,72 × 0,87 m

Использовать в коде

Ремикс в редакторе
Самодостаточный ES-модуль — зависит только от three. Вызовите фабрику и добавьте группу в сцену.
/**
 * Fallen Log — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,036 · Size (W × H × D): 2.23 × 0.72 × 0.87 m
 *
 * Usage:
 *   import { createFallenLog } from './fallen-log.js';
 *   
 *   const model = createFallenLog();
 *   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 createFallenLog() {
  const root = new THREE.Group();
  root.name = 'FallenLog';

  // Materials
  const barkMat = new THREE.MeshStandardMaterial({ name: 'bark', color: 0x5f4631, roughness: 0.95, flatShading: true });
  const cutMat = new THREE.MeshStandardMaterial({ name: 'cut', color: 0xd3a262, roughness: 0.85, flatShading: true });
  const ringMat = new THREE.MeshStandardMaterial({ name: 'ring', color: 0x9c6a3a, roughness: 0.9, flatShading: true });
  const mossMat = new THREE.MeshStandardMaterial({ name: 'moss', color: 0x5b8a35, roughness: 1, flatShading: true });
  const capMat = new THREE.MeshStandardMaterial({ name: 'cap', color: 0xd8662f, roughness: 0.7, flatShading: true });
  const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0xefe2c4, roughness: 0.8, flatShading: true });

  // Parts
  const log = new THREE.Group();
  log.name = 'log';
  log.position.set(0, 0.2757, 0);
  root.add(log);
  const trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.2576, 0.28, 2.2, 9), barkMat);
  trunk.name = 'trunk';
  trunk.rotation.set(0, 0, deg(90));
  log.add(trunk);
  const cutLeft = new THREE.Mesh(new THREE.CylinderGeometry(0.2215, 0.2215, 0.02, 9), cutMat);
  cutLeft.name = 'cutLeft';
  cutLeft.position.set(-1.103, 0, 0);
  cutLeft.rotation.set(0, 0, deg(90));
  log.add(cutLeft);
  const ringL1 = new THREE.Mesh(new THREE.RingGeometry(0.038, 0.0492, 16), ringMat);
  ringL1.name = 'ringL1';
  ringL1.position.set(-1.1145, 0, 0);
  ringL1.rotation.set(0, deg(-90), 0);
  log.add(ringL1);
  const ringL2 = new THREE.Mesh(new THREE.RingGeometry(0.0996, 0.1108, 16), ringMat);
  ringL2.name = 'ringL2';
  ringL2.position.set(-1.1145, 0, 0);
  ringL2.rotation.set(0, deg(-90), 0);
  log.add(ringL2);
  const ringL3 = new THREE.Mesh(new THREE.RingGeometry(0.1611, 0.1723, 16), ringMat);
  ringL3.name = 'ringL3';
  ringL3.position.set(-1.1145, 0, 0);
  ringL3.rotation.set(0, deg(-90), 0);
  log.add(ringL3);
  const cutRight = new THREE.Mesh(new THREE.CylinderGeometry(0.2408, 0.2408, 0.02, 9), cutMat);
  cutRight.name = 'cutRight';
  cutRight.position.set(1.103, 0, 0);
  cutRight.rotation.set(0, 0, deg(90));
  log.add(cutRight);
  const ringR1 = new THREE.Mesh(new THREE.RingGeometry(0.0423, 0.0535, 16), ringMat);
  ringR1.name = 'ringR1';
  ringR1.position.set(1.1145, 0, 0);
  ringR1.rotation.set(0, deg(90), 0);
  log.add(ringR1);
  const ringR2 = new THREE.Mesh(new THREE.RingGeometry(0.1092, 0.1204, 16), ringMat);
  ringR2.name = 'ringR2';
  ringR2.position.set(1.1145, 0, 0);
  ringR2.rotation.set(0, deg(90), 0);
  log.add(ringR2);
  const ringR3 = new THREE.Mesh(new THREE.RingGeometry(0.1761, 0.1873, 16), ringMat);
  ringR3.name = 'ringR3';
  ringR3.position.set(1.1145, 0, 0);
  ringR3.rotation.set(0, deg(90), 0);
  log.add(ringR3);
  const stub1 = new THREE.Mesh(new THREE.CylinderGeometry(0.056, 0.084, 0.3676, 6), barkMat);
  stub1.name = 'stub1';
  stub1.position.set(-0.4215, 0.175, 0.3031);
  stub1.rotation.set(deg(59.3595), deg(4.5633), deg(7.9981));
  log.add(stub1);
  const stub2 = new THREE.Mesh(new THREE.CylinderGeometry(0.056, 0.084, 0.3674, 6), barkMat);
  stub2.name = 'stub2';
  stub2.position.set(0.6189, 0.2681, -0.225);
  stub2.rotation.set(deg(-39.6136), deg(2.8174), deg(-7.812));
  log.add(stub2);
  const moss1 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1, 1), 0.12, 40), mossMat);
  moss1.name = 'moss1';
  moss1.position.set(-0.484, 0.224, 0.0243);
  moss1.rotation.set(deg(10), 0, 0);
  moss1.scale.set(0.374, 0.0896, 0.2016);
  log.add(moss1);
  const moss2 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1, 1), 0.12, 41), mossMat);
  moss2.name = 'moss2';
  moss2.position.set(0.132, 0.224, -0.0362);
  moss2.rotation.set(deg(-15), 0, 0);
  moss2.scale.set(0.242, 0.0896, 0.2016);
  log.add(moss2);
  const moss3 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1, 1), 0.12, 42), mossMat);
  moss3.name = 'moss3';
  moss3.position.set(-0.924, 0.224, 0.0592);
  moss3.rotation.set(deg(25), 0, 0);
  moss3.scale.set(0.132, 0.0896, 0.2016);
  log.add(moss3);
  const mushroom1 = new THREE.Group();
  mushroom1.name = 'mushroom1';
  mushroom1.position.set(0.66, 0.1674, 0.1995);
  mushroom1.rotation.set(deg(16.1649), 0, 0);
  log.add(mushroom1);
  const stem = new THREE.Mesh(new THREE.CylinderGeometry(0.0304, 0.038, 0.133, 6), stemMat);
  stem.name = 'stem';
  stem.position.set(0, 0.0665, 0);
  mushroom1.add(stem);
  const cap = new THREE.Mesh(new THREE.SphereGeometry(0.0855, 8, 3, 0, Math.PI * 2, 0, Math.PI / 2), capMat);
  cap.name = 'cap';
  cap.position.set(0, 0.1178, 0);
  cap.scale.set(1, 0.75, 1);
  mushroom1.add(cap);
  const mushroom2 = new THREE.Group();
  mushroom2.name = 'mushroom2';
  mushroom2.position.set(0.814, 0.11, 0.236);
  mushroom2.rotation.set(deg(20.511), 0, 0);
  log.add(mushroom2);
  const stem2 = new THREE.Mesh(new THREE.CylinderGeometry(0.0228, 0.0285, 0.0998, 6), stemMat);
  stem2.name = 'stem';
  stem2.position.set(0, 0.0499, 0);
  mushroom2.add(stem2);
  const cap2 = new THREE.Mesh(new THREE.SphereGeometry(0.0641, 8, 3, 0, Math.PI * 2, 0, Math.PI / 2), capMat);
  cap2.name = 'cap';
  cap2.position.set(0, 0.0884, 0);
  cap2.scale.set(1, 0.75, 1);
  mushroom2.add(cap2);
  const mushroom3 = new THREE.Group();
  mushroom3.name = 'mushroom3';
  mushroom3.position.set(0.528, 0.0891, 0.2447);
  mushroom3.rotation.set(deg(21.8622), 0, 0);
  log.add(mushroom3);
  const stem3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0182, 0.0228, 0.0798, 6), stemMat);
  stem3.name = 'stem';
  stem3.position.set(0, 0.0399, 0);
  mushroom3.add(stem3);
  const cap3 = new THREE.Mesh(new THREE.SphereGeometry(0.0513, 8, 3, 0, Math.PI * 2, 0, Math.PI / 2), capMat);
  cap3.name = 'cap';
  cap3.position.set(0, 0.0707, 0);
  cap3.scale.set(1, 0.75, 1);
  mushroom3.add(cap3);
  const mushroom4 = new THREE.Group();
  mushroom4.name = 'mushroom4';
  mushroom4.position.set(-0.66, 0.1995, 0.1674);
  mushroom4.rotation.set(deg(13.0825), 0, 0);
  log.add(mushroom4);
  const stem4 = new THREE.Mesh(new THREE.CylinderGeometry(0.0213, 0.0266, 0.0931, 6), stemMat);
  stem4.name = 'stem';
  stem4.position.set(0, 0.0466, 0);
  mushroom4.add(stem4);
  const cap4 = new THREE.Mesh(new THREE.SphereGeometry(0.0598, 8, 3, 0, Math.PI * 2, 0, Math.PI / 2), capMat);
  cap4.name = 'cap';
  cap4.position.set(0, 0.0825, 0);
  cap4.scale.set(1, 0.75, 1);
  mushroom4.add(cap4);

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

export default createFallenLog;

Оценки и комментарии

—
Оценок пока нет — будьте первым.
5
0
4
0
3
0
2
0
1
0

Войдите, чтобы ставить оценки и оставлять комментарии.

0 комментариев

Комментариев пока нет. Расскажите, как вы использовали эту модель или что можно улучшить.

Похожие модели

Та же категория или похожие теги