삼각형 368개0.14 × 0.13 × 0.23 m
코드에서 사용하기
에디터에서 리믹스bread.js · 86줄
독립형 ES 모듈이에요 — three에만 의존해요. 팩토리 함수를 호출하고 그룹을 씬에 추가하세요.
/**
* Bread — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 368 · Size (W × H × D): 0.14 × 0.13 × 0.23 m
*
* Usage:
* import { createBread } from './bread.js';
*
* const model = createBread();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Extrude a 2D outline along Z (centered). bevel = [thickness, size, segments].
function extrude(outline, depth, holes = [], bevel = null) {
const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
const options = bevel
? { depth, bevelEnabled: true, bevelThickness: bevel[0], bevelSize: bevel[1], bevelSegments: bevel[2] }
: { depth, bevelEnabled: false };
return new THREE.ExtrudeGeometry(shape, options).translate(0, 0, -depth / 2);
}
export function createBread() {
const root = new THREE.Group();
root.name = 'Bread';
// Materials
const crustMat = new THREE.MeshStandardMaterial({ name: 'crust', color: 0xc98339, roughness: 0.75, flatShading: true });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x9d662c, roughness: 0.8, flatShading: true });
const crumbMat = new THREE.MeshStandardMaterial({ name: 'crumb', color: 0xf0d2a5, roughness: 0.9, flatShading: true });
// Shared geometries
const sphereGeo = new THREE.SphereGeometry(1, 8, 4);
// Parts
const loaf = new THREE.Group();
loaf.name = 'loaf';
root.add(loaf);
const loafBody = new THREE.Mesh(extrude([[-0.05, 0], [0.05, 0], [0.053, 0.05], [0.06, 0.064], [0.061, 0.078], [0.052, 0.094], [0.034, 0.104], [0.012, 0.108], [-0.012, 0.108], [-0.034, 0.104], [-0.052, 0.094], [-0.061, 0.078], [-0.06, 0.064], [-0.053, 0.05]], 0.2, [], [0.014, 0.008, 2]), crustMat);
loafBody.name = 'loafBody';
loafBody.position.set(0, 0.008, 0);
loaf.add(loafBody);
const tinLine = new THREE.Mesh(new THREE.BoxGeometry(0.124, 0.006, 0.226), darkMat);
tinLine.name = 'tinLine';
tinLine.position.set(0, 0.062, 0);
loaf.add(tinLine);
const score1 = new THREE.Mesh(sphereGeo, crumbMat);
score1.name = 'score1';
score1.position.set(0, 0.121, -0.075);
score1.rotation.set(0, deg(28), 0);
score1.scale.set(0.036, 0.006, 0.008);
loaf.add(score1);
const score2 = new THREE.Mesh(sphereGeo, crumbMat);
score2.name = 'score2';
score2.position.set(0, 0.121, -0.025);
score2.rotation.set(0, deg(28), 0);
score2.scale.set(0.036, 0.006, 0.008);
loaf.add(score2);
const score3 = new THREE.Mesh(sphereGeo, crumbMat);
score3.name = 'score3';
score3.position.set(0, 0.121, 0.025);
score3.rotation.set(0, deg(28), 0);
score3.scale.set(0.036, 0.006, 0.008);
loaf.add(score3);
const score4 = new THREE.Mesh(sphereGeo, crumbMat);
score4.name = 'score4';
score4.position.set(0, 0.121, 0.075);
score4.rotation.set(0, deg(28), 0);
score4.scale.set(0.036, 0.006, 0.008);
loaf.add(score4);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createBread;
평점 및 댓글
댓글 0개
아직 댓글이 없어요. 이 모델을 어떻게 사용했는지, 어떤 점이 더 나아질 수 있을지 공유해 주세요.
관련 모델
같은 카테고리 또는 비슷한 태그









