368 tris0,14 × 0,13 × 0,23 m
Utiliser dans le code
Remixer dans l’éditeurbread.js · 86 lignes
Module ES autonome — ne dépend que de three. Appelez la fonction factory et ajoutez le groupe à votre scène.
/**
* 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;
Notes et commentaires
0 commentaire
Aucun commentaire pour l’instant. Dites comment vous avez utilisé ce modèle ou ce qui pourrait être amélioré.
Modèles similaires
Même catégorie ou étiquettes proches









