삼각형 1.1천개14.7 × 7.29 × 15.7 m
코드에서 사용하기
에디터에서 리믹스asteroid-field.js · 261줄
독립형 ES 모듈이에요 — three에만 의존해요. 팩토리 함수를 호출하고 그룹을 씬에 추가하세요.
/**
* Asteroid Field — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the model (it floats — pickups, planets)
* Triangles: 1,080 · Size (W × H × D): 14.71 × 7.29 × 15.74 m
*
* Usage:
* import { createAsteroidField } from './asteroid-field.js';
*
* const model = createAsteroidField();
* 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 createAsteroidField() {
const root = new THREE.Group();
root.name = 'AsteroidField';
// Materials
const aMat = new THREE.MeshStandardMaterial({ name: 'a', color: 0x5f564d, roughness: 0.92, flatShading: true });
const bMat = new THREE.MeshStandardMaterial({ name: 'b', color: 0x4b453f, roughness: 0.95, flatShading: true });
const cMat = new THREE.MeshStandardMaterial({ name: 'c', color: 0x706559, roughness: 0.92, flatShading: true });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x3d3732, roughness: 0.95, flatShading: true });
// Parts
const field = new THREE.Group();
field.name = 'field';
root.add(field);
const asteroid1 = new THREE.Group();
asteroid1.name = 'asteroid1';
asteroid1.position.set(0.0116, -0.4738, -2.6333);
asteroid1.rotation.set(deg(145.1426), deg(216.9104), deg(116.4156));
asteroid1.scale.setScalar(1.7982);
field.add(asteroid1);
const body = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.16, 91), bMat);
body.name = 'body';
body.scale.set(0.9728, 0.6241, 0.7184);
asteroid1.add(body);
const bulge1 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.3975, 0), 0.0596, 119), darkMat);
bulge1.name = 'bulge1';
bulge1.position.set(0.2495, -0.1583, -0.4477);
bulge1.rotation.set(deg(72.3743), deg(77.9906), 0);
asteroid1.add(bulge1);
const bulge2 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.4193, 0), 0.0629, 120), bMat);
bulge2.name = 'bulge2';
bulge2.position.set(0.4146, 0.2435, 0.3086);
bulge2.rotation.set(deg(56.7559), deg(81.3505), 0);
asteroid1.add(bulge2);
const asteroid2 = new THREE.Group();
asteroid2.name = 'asteroid2';
asteroid2.position.set(-0.6001, 1.8399, 1.4329);
asteroid2.rotation.set(deg(174.1107), deg(272.4175), deg(166.6608));
asteroid2.scale.setScalar(1.5744);
field.add(asteroid2);
const body2 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.16, 92), cMat);
body2.name = 'body';
body2.scale.set(1.1601, 0.7332, 0.7468);
asteroid2.add(body2);
const bulge12 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.3753, 0), 0.0563, 122), darkMat);
bulge12.name = 'bulge1';
bulge12.position.set(0.5703, 0.2225, -0.3209);
bulge12.rotation.set(deg(5.1557), deg(16.994), 0);
asteroid2.add(bulge12);
const bulge22 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.4238, 0), 0.0636, 123), cMat);
bulge22.name = 'bulge2';
bulge22.position.set(0.1783, 0.3858, 0.3486);
bulge22.rotation.set(deg(80.9849), deg(88.8971), 0);
asteroid2.add(bulge22);
const asteroid3 = new THREE.Group();
asteroid3.name = 'asteroid3';
asteroid3.position.set(-3.0423, -1.5014, 4.8374);
asteroid3.rotation.set(deg(10.8577), deg(248.3237), deg(116.9973));
asteroid3.scale.setScalar(1.4495);
field.add(asteroid3);
const body3 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.16, 93), aMat);
body3.name = 'body';
body3.scale.set(1.2353, 0.7346, 0.91);
asteroid3.add(body3);
const bulge13 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.4437, 0), 0.0666, 125), darkMat);
bulge13.name = 'bulge1';
bulge13.position.set(-0.5342, 0.4103, -0.1268);
bulge13.rotation.set(deg(40.3818), deg(9.7662), 0);
asteroid3.add(bulge13);
const bulge23 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.416, 0), 0.0624, 126), aMat);
bulge23.name = 'bulge2';
bulge23.position.set(0.2724, -0.2392, 0.5488);
bulge23.rotation.set(deg(76.2923), deg(9.2411), 0);
asteroid3.add(bulge23);
const asteroid4 = new THREE.Group();
asteroid4.name = 'asteroid4';
asteroid4.position.set(2.6248, -2.4443, -4.6295);
asteroid4.rotation.set(deg(126.911), deg(286.966), deg(178.3325));
asteroid4.scale.setScalar(1.2307);
field.add(asteroid4);
const body4 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.16, 94), bMat);
body4.name = 'body';
body4.scale.set(1.2521, 0.5914, 0.998);
asteroid4.add(body4);
const asteroid5 = new THREE.Group();
asteroid5.name = 'asteroid5';
asteroid5.position.set(-3.2591, 2.7709, 0.4343);
asteroid5.rotation.set(deg(109.3185), deg(343.0207), deg(173.0595));
asteroid5.scale.setScalar(0.9041);
field.add(asteroid5);
const body5 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.16, 95), cMat);
body5.name = 'body';
body5.scale.set(1.0031, 0.5874, 0.8754);
asteroid5.add(body5);
const asteroid6 = new THREE.Group();
asteroid6.name = 'asteroid6';
asteroid6.position.set(-3.1083, 1.2854, -5.6789);
asteroid6.rotation.set(deg(12.9399), deg(274.3123), deg(168.7918));
asteroid6.scale.setScalar(0.9526);
field.add(asteroid6);
const body6 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.16, 96), aMat);
body6.name = 'body';
body6.scale.set(1.1254, 0.6653, 0.7768);
asteroid6.add(body6);
const asteroid7 = new THREE.Group();
asteroid7.name = 'asteroid7';
asteroid7.position.set(1.0088, 0.947, -6.3657);
asteroid7.rotation.set(deg(51.0326), deg(236.0673), deg(159.8164));
asteroid7.scale.setScalar(0.8082);
field.add(asteroid7);
const body7 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.16, 97), bMat);
body7.name = 'body';
body7.scale.set(1.1772, 0.8463, 0.9262);
asteroid7.add(body7);
const asteroid8 = new THREE.Group();
asteroid8.name = 'asteroid8';
asteroid8.position.set(6.9121, -0.1321, -1.8939);
asteroid8.rotation.set(deg(20.5544), deg(132.7213), deg(95.5927));
asteroid8.scale.setScalar(0.5339);
field.add(asteroid8);
const body8 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.16, 98), cMat);
body8.name = 'body';
body8.scale.set(1.0391, 0.6947, 0.71);
asteroid8.add(body8);
const asteroid9 = new THREE.Group();
asteroid9.name = 'asteroid9';
asteroid9.position.set(-6.8684, 2.2237, -5.2057);
asteroid9.rotation.set(deg(93.0306), deg(36.4539), deg(25.8796));
asteroid9.scale.setScalar(0.4869);
field.add(asteroid9);
const body9 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1, 0), 0.16, 99), aMat);
body9.name = 'body';
body9.scale.set(0.9292, 0.5878, 0.8381);
asteroid9.add(body9);
const asteroid10 = new THREE.Group();
asteroid10.name = 'asteroid10';
asteroid10.position.set(-5.6179, -1.5987, -4.318);
asteroid10.rotation.set(deg(22.6544), deg(76.2792), deg(136.1208));
asteroid10.scale.setScalar(0.3918);
field.add(asteroid10);
const body10 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1, 0), 0.16, 100), bMat);
body10.name = 'body';
body10.scale.set(1.0192, 0.6217, 0.7342);
asteroid10.add(body10);
const asteroid11 = new THREE.Group();
asteroid11.name = 'asteroid11';
asteroid11.position.set(-7.0534, -1.7494, 3.6717);
asteroid11.rotation.set(deg(4.1328), deg(9.4287), deg(47.3407));
asteroid11.scale.setScalar(0.3927);
field.add(asteroid11);
const body11 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1, 0), 0.16, 101), cMat);
body11.name = 'body';
body11.scale.set(1.2292, 0.6503, 0.8636);
asteroid11.add(body11);
const asteroid12 = new THREE.Group();
asteroid12.name = 'asteroid12';
asteroid12.position.set(3.6384, -2.9736, 6.7699);
asteroid12.rotation.set(deg(77.0752), deg(121.3613), deg(110.6957));
asteroid12.scale.setScalar(0.4039);
field.add(asteroid12);
const body12 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1, 0), 0.16, 102), aMat);
body12.name = 'body';
body12.scale.set(1.2357, 0.6183, 0.761);
asteroid12.add(body12);
const gravel1 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1532, 0), 0.0306, 287), aMat);
gravel1.name = 'gravel1';
gravel1.position.set(1.6952, -2.6248, -8.314);
gravel1.rotation.set(deg(26.553), deg(12.8744), 0);
field.add(gravel1);
const gravel2 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1642, 0), 0.0328, 288), darkMat);
gravel2.name = 'gravel2';
gravel2.position.set(4.3175, 2.2421, -0.1485);
gravel2.rotation.set(deg(71.3263), deg(84.4855), 0);
field.add(gravel2);
const gravel3 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1676, 0), 0.0335, 289), cMat);
gravel3.name = 'gravel3';
gravel3.position.set(-4.7698, -0.8502, -5.8089);
gravel3.rotation.set(deg(6.3393), deg(75.6595), 0);
field.add(gravel3);
const gravel4 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.142, 0), 0.0284, 290), darkMat);
gravel4.name = 'gravel4';
gravel4.position.set(6.99, -1.0406, 0.962);
gravel4.rotation.set(deg(53.5314), deg(60.3496), 0);
field.add(gravel4);
const gravel5 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1191, 0), 0.0238, 291), bMat);
gravel5.name = 'gravel5';
gravel5.position.set(5.3283, 1.658, 2.6573);
gravel5.rotation.set(deg(38.392), deg(76.3117), 0);
field.add(gravel5);
const gravel6 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1105, 0), 0.0221, 292), darkMat);
gravel6.name = 'gravel6';
gravel6.position.set(0.9125, -2.7235, 6.4395);
gravel6.rotation.set(deg(23.6519), deg(24.2344), 0);
field.add(gravel6);
const gravel7 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1049, 0), 0.021, 293), aMat);
gravel7.name = 'gravel7';
gravel7.position.set(1.0978, -1.3455, -0.5791);
gravel7.rotation.set(deg(82.3345), deg(19.7941), 0);
field.add(gravel7);
const gravel8 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1302, 0), 0.026, 294), darkMat);
gravel8.name = 'gravel8';
gravel8.position.set(-4.2232, -1.505, -7.2816);
gravel8.rotation.set(deg(67.6852), deg(0.7139), 0);
field.add(gravel8);
const gravel9 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1202, 0), 0.024, 295), cMat);
gravel9.name = 'gravel9';
gravel9.position.set(3.0953, -1.4832, -2.4491);
gravel9.rotation.set(deg(83.0631), deg(66.3593), 0);
field.add(gravel9);
const gravel10 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1519, 0), 0.0304, 296), darkMat);
gravel10.name = 'gravel10';
gravel10.position.set(0.45, -1.9604, 6.5557);
gravel10.rotation.set(deg(67.0739), deg(66.4162), 0);
field.add(gravel10);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createAsteroidField;
평점 및 댓글
댓글 0개
아직 댓글이 없어요. 이 모델을 어떻게 사용했는지, 어떤 점이 더 나아질 수 있을지 공유해 주세요.
관련 모델
같은 카테고리 또는 비슷한 태그









