Codels
204 ポリゴン1.16 × 3.19 × 0.63 m
自己完結型の ES モジュールで、依存先は three のみです。ファクトリー関数を呼び出し、返された group をシーンに追加してください。
/**
 * Standing Stone — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 204 · Size (W × H × D): 1.16 × 3.19 × 0.63 m
 *
 * Usage:
 *   import { createStandingStone } from './standing-stone.js';
 *   
 *   const model = createStandingStone();
 *   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 createStandingStone() {
  const root = new THREE.Group();
  root.name = 'StandingStone';

  // Materials
  const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0x77756f, roughness: 0.95, flatShading: true });
  const runeMat = new THREE.MeshStandardMaterial({ name: 'rune', color: 0x4fd4ff, roughness: 0.4, emissive: 0x4fd4ff, emissiveIntensity: 1.4, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.2831, 0.0389, 0.03);
  const boxGeo2 = new THREE.BoxGeometry(0.4277, 0.0389, 0.03);
  const boxGeo3 = new THREE.BoxGeometry(0.2458, 0.0389, 0.03);
  const boxGeo4 = new THREE.BoxGeometry(0.2591, 0.0389, 0.03);

  // Parts
  const menhir = new THREE.Group();
  menhir.name = 'menhir';
  menhir.position.set(0, 0.0733, 0);
  menhir.rotation.set(0, 0, deg(-2.7367));
  root.add(menhir);
  const slab = new THREE.Mesh(jitter(new THREE.CylinderGeometry(0.3456, 0.5616, 3, 6, 4), 0.0648, 548), stoneMat);
  slab.name = 'slab';
  slab.position.set(0, 1.5, 0);
  slab.rotation.set(0, deg(90), 0);
  slab.scale.set(0.6, 1, 1);
  menhir.add(slab);
  const crown = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.2916, 0), 0.027, 708), stoneMat);
  crown.name = 'crown';
  crown.position.set(0.0329, 2.9784, 0);
  crown.rotation.set(0, deg(90), 0);
  crown.scale.set(0.58, 0.5, 1);
  menhir.add(crown);
  const rune1s1 = new THREE.Mesh(boxGeo, runeMat);
  rune1s1.name = 'rune1s1';
  rune1s1.position.set(0.0007, 2.1458, 0.229);
  rune1s1.rotation.set(deg(2.7309), deg(6.4925), deg(-142.9201));
  menhir.add(rune1s1);
  const rune1s2 = new THREE.Mesh(new THREE.BoxGeometry(0.2545, 0.0389, 0.03), runeMat);
  rune1s2.name = 'rune1s2';
  rune1s2.position.set(0.0007, 2.0253, 0.2232);
  rune1s2.rotation.set(deg(2.7309), deg(6.4925), deg(-25.7959));
  menhir.add(rune1s2);
  const rune1s3 = new THREE.Mesh(boxGeo, runeMat);
  rune1s3.name = 'rune1s3';
  rune1s3.position.set(-0.0003, 1.9054, 0.2188);
  rune1s3.rotation.set(deg(-2.7774), deg(-2.4116), deg(-142.8236));
  menhir.add(rune1s3);
  const rune2s1 = new THREE.Mesh(boxGeo2, runeMat);
  rune2s1.name = 'rune2s1';
  rune2s1.position.set(-0.078, 1.4813, 0.2349);
  rune2s1.rotation.set(deg(-0.603), deg(-2.4371), deg(89.9872));
  menhir.add(rune2s1);
  const rune2s2 = new THREE.Mesh(boxGeo3, runeMat);
  rune2s2.name = 'rune2s2';
  rune2s2.position.set(0.0153, 1.6118, 0.2337);
  rune2s2.rotation.set(deg(-2.7774), deg(-2.4116), deg(25.5437));
  menhir.add(rune2s2);
  const rune2s3 = new THREE.Mesh(boxGeo3, runeMat);
  rune2s3.name = 'rune2s3';
  rune2s3.position.set(0.0153, 1.5066, 0.2386);
  rune2s3.rotation.set(deg(-0.603), deg(-2.4371), deg(25.5894));
  menhir.add(rune2s3);
  const rune3s1 = new THREE.Mesh(boxGeo2, runeMat);
  rune3s1.name = 'rune3s1';
  rune3s1.position.set(-0.0001, 0.9369, 0.2399);
  rune3s1.rotation.set(deg(0.5273), deg(-0.7508), deg(90.0035));
  menhir.add(rune3s1);
  const rune3s2 = new THREE.Mesh(boxGeo4, runeMat);
  rune3s2.name = 'rune3s2';
  rune3s2.position.set(-0.074, 1.0186, 0.2397);
  rune3s2.rotation.set(deg(0.5273), deg(-0.7508), deg(132.141));
  menhir.add(rune3s2);
  const rune3s3 = new THREE.Mesh(boxGeo4, runeMat);
  rune3s3.name = 'rune3s3';
  rune3s3.position.set(0.0738, 1.0186, 0.2416);
  rune3s3.rotation.set(deg(0.5273), deg(-0.7508), deg(47.8659));
  menhir.add(rune3s3);

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

export default createStandingStone;

評価とコメント

—
まだ評価はありません。最初の評価をしてみましょう。
5
0
4
0
3
0
2
0
1
0

評価やコメントをするにはログインしてください。

0 件のコメント

まだコメントはありません。このモデルの使い方や改善できる点を共有しましょう。

関連モデル

同じカテゴリまたは似たタグ