1482 三角面0.85 × 0.79 × 0.88 m
在代码中使用
在编辑器中改编mushroom-monster.js · 300 行
自包含的 ES 模块,仅依赖 three。调用工厂函数,然后把返回的 group 添加到场景中。
/**
* Mushroom Monster — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,482 · Size (W × H × D): 0.85 × 0.79 × 0.88 m
*
* Usage:
* import { createMushroomMonster } from './mushroom-monster.js';
*
* const model = createMushroomMonster();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Revolve a 2D profile [[radius, y], ...] around the Y axis.
function lathe(points, segments, phiStart = 0, phiLength = Math.PI * 2) {
return new THREE.LatheGeometry(points.map(([x, y]) => new THREE.Vector2(x, y)), segments, phiStart, phiLength);
}
// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}
export function createMushroomMonster() {
const root = new THREE.Group();
root.name = 'MushroomMonster';
// Materials
const capMat = new THREE.MeshStandardMaterial({ name: 'cap', color: 0xd9443a, roughness: 0.55, flatShading: true });
const spotMat = new THREE.MeshStandardMaterial({ name: 'spot', color: 0xfbf6ec, roughness: 0.6, flatShading: true });
const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0xf3e3c6, roughness: 0.8, flatShading: true });
const gillMat = new THREE.MeshStandardMaterial({ name: 'gill', color: 0xc7baa2, roughness: 0.85, flatShading: true });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x21171a, roughness: 0.35, flatShading: true });
const bootMat = new THREE.MeshStandardMaterial({ name: 'boot', color: 0x6b4430, roughness: 0.8, flatShading: true });
// Shared geometries
const cylinderGeo = new THREE.CylinderGeometry(0.045, 0.05, 0.08, 7);
const sphereGeo = new THREE.SphereGeometry(0.07, 8, 5);
const sphereGeo2 = new THREE.SphereGeometry(0.052, 8, 6);
const sphereGeo3 = new THREE.SphereGeometry(0.024, 6, 4);
const boxGeo = new THREE.BoxGeometry(0.008, 0.008, 0.004);
const boxGeo2 = new THREE.BoxGeometry(0.085, 0.022, 0.02);
const capsuleGeo = new THREE.CapsuleGeometry(0.04, 0.07, 2, 6);
const boxGeo3 = new THREE.BoxGeometry(0.006, 0.008, 0.15);
const sphereGeo4 = new THREE.SphereGeometry(0.07, 8, 3);
const sphereGeo5 = new THREE.SphereGeometry(0.045, 8, 3);
// Parts
const legL = new THREE.Group();
legL.name = 'legL';
legL.position.set(0.09, 0.14, 0);
root.add(legL);
const legLStub = new THREE.Mesh(cylinderGeo, stemMat);
legLStub.name = 'legLStub';
legLStub.position.set(0, -0.04, 0);
legL.add(legLStub);
const bootL = new THREE.Mesh(sphereGeo, bootMat);
bootL.name = 'bootL';
bootL.position.set(0, -0.098, 0.025);
bootL.scale.set(0.95, 0.6, 1.3);
legL.add(bootL);
const legR = new THREE.Group();
legR.name = 'legR';
legR.position.set(-0.09, 0.14, 0);
root.add(legR);
const legRStub = new THREE.Mesh(cylinderGeo, stemMat);
legRStub.name = 'legRStub';
legRStub.position.set(0, -0.04, 0);
legR.add(legRStub);
const bootR = new THREE.Mesh(sphereGeo, bootMat);
bootR.name = 'bootR';
bootR.position.set(0, -0.098, 0.025);
bootR.scale.set(0.95, 0.6, 1.3);
legR.add(bootR);
const body = new THREE.Group();
body.name = 'body';
root.add(body);
const stemBody = new THREE.Mesh(lathe([[0, 0], [0.17, 0], [0.21, 0.06], [0.225, 0.16], [0.205, 0.27], [0.165, 0.35], [0, 0.37]], 12), stemMat);
stemBody.name = 'stemBody';
stemBody.position.set(0, 0.1, 0);
body.add(stemBody);
const eyeL = new THREE.Mesh(sphereGeo2, spotMat);
eyeL.name = 'eyeL';
eyeL.position.set(0.075, 0.3, 0.1924);
eyeL.rotation.set(0, deg(18), 0);
eyeL.scale.set(0.9, 0.85, 0.45);
body.add(eyeL);
const pupilL = new THREE.Mesh(sphereGeo3, darkMat);
pupilL.name = 'pupilL';
pupilL.position.set(0.063, 0.292, 0.2124);
pupilL.scale.set(1, 1.1, 0.5);
body.add(pupilL);
const eyeShineL = new THREE.Mesh(boxGeo, spotMat);
eyeShineL.name = 'eyeShineL';
eyeShineL.position.set(0.069, 0.308, 0.2244);
body.add(eyeShineL);
const browL = new THREE.Mesh(boxGeo2, darkMat);
browL.name = 'browL';
browL.position.set(0.08, 0.358, 0.1951);
browL.rotation.set(0, deg(18), deg(24));
body.add(browL);
const eyeR = new THREE.Mesh(sphereGeo2, spotMat);
eyeR.name = 'eyeR';
eyeR.position.set(-0.075, 0.3, 0.1924);
eyeR.rotation.set(0, deg(-18), 0);
eyeR.scale.set(0.9, 0.85, 0.45);
body.add(eyeR);
const pupilR = new THREE.Mesh(sphereGeo3, darkMat);
pupilR.name = 'pupilR';
pupilR.position.set(-0.063, 0.292, 0.2124);
pupilR.scale.set(1, 1.1, 0.5);
body.add(pupilR);
const eyeShineR = new THREE.Mesh(boxGeo, spotMat);
eyeShineR.name = 'eyeShineR';
eyeShineR.position.set(-0.069, 0.308, 0.2244);
body.add(eyeShineR);
const browR = new THREE.Mesh(boxGeo2, darkMat);
browR.name = 'browR';
browR.position.set(-0.08, 0.358, 0.1951);
browR.rotation.set(0, deg(-18), deg(-24));
body.add(browR);
const frown = new THREE.Mesh(tube([[-0.06, 0.19, 0.2055], [-0.025, 0.214, 0.2195], [0.025, 0.214, 0.2195], [0.06, 0.19, 0.2055]], 0.009, 10, 4), darkMat);
frown.name = 'frown';
body.add(frown);
const tooth = new THREE.Mesh(new THREE.ConeGeometry(0.014, 0.03, 4), spotMat);
tooth.name = 'tooth';
tooth.position.set(0.022, 0.202, 0.2215);
tooth.rotation.set(deg(180), 0, 0);
body.add(tooth);
const armL = new THREE.Group();
armL.name = 'armL';
armL.position.set(0.205, 0.3, 0.01);
armL.rotation.set(deg(-20), 0, deg(35));
root.add(armL);
const armLNub = new THREE.Mesh(capsuleGeo, stemMat);
armLNub.name = 'armLNub';
armLNub.position.set(0, -0.06, 0);
armL.add(armLNub);
const armR = new THREE.Group();
armR.name = 'armR';
armR.position.set(-0.205, 0.3, 0.01);
armR.rotation.set(deg(-20), 0, deg(-35));
root.add(armR);
const armRNub = new THREE.Mesh(capsuleGeo, stemMat);
armRNub.name = 'armRNub';
armRNub.position.set(0, -0.06, 0);
armR.add(armRNub);
const cap = new THREE.Group();
cap.name = 'cap';
cap.position.set(0, 0.44, -0.01);
cap.rotation.set(deg(-6), 0, deg(7));
root.add(cap);
const capDome = new THREE.Mesh(lathe([[0, 0], [0.4, 0.015], [0.44, 0.06], [0.43, 0.13], [0.37, 0.22], [0.27, 0.3], [0.14, 0.345], [0, 0.36]], 14), capMat);
capDome.name = 'capDome';
capDome.position.set(0, -0.03, 0);
cap.add(capDome);
const gills = new THREE.Mesh(new THREE.CircleGeometry(0.395, 14), gillMat);
gills.name = 'gills';
gills.position.set(0, -0.032, 0);
gills.rotation.set(deg(90), 0, 0);
cap.add(gills);
const gillLine = new THREE.Mesh(boxGeo3, stemMat);
gillLine.name = 'gillLine';
gillLine.position.set(0, -0.036, 0.26);
cap.add(gillLine);
const gillLine2 = new THREE.Mesh(boxGeo3, stemMat);
gillLine2.name = 'gillLine';
gillLine2.position.set(0.1128, -0.036, 0.2343);
gillLine2.rotation.set(0, deg(25.7143), 0);
cap.add(gillLine2);
const gillLine3 = new THREE.Mesh(boxGeo3, stemMat);
gillLine3.name = 'gillLine';
gillLine3.position.set(0.2033, -0.036, 0.1621);
gillLine3.rotation.set(0, deg(51.4286), 0);
cap.add(gillLine3);
const gillLine4 = new THREE.Mesh(boxGeo3, stemMat);
gillLine4.name = 'gillLine';
gillLine4.position.set(0.2535, -0.036, 0.0579);
gillLine4.rotation.set(0, deg(77.1429), 0);
cap.add(gillLine4);
const gillLine5 = new THREE.Mesh(boxGeo3, stemMat);
gillLine5.name = 'gillLine';
gillLine5.position.set(0.2535, -0.036, -0.0579);
gillLine5.rotation.set(0, deg(102.8571), 0);
cap.add(gillLine5);
const gillLine6 = new THREE.Mesh(boxGeo3, stemMat);
gillLine6.name = 'gillLine';
gillLine6.position.set(0.2033, -0.036, -0.1621);
gillLine6.rotation.set(0, deg(128.5714), 0);
cap.add(gillLine6);
const gillLine7 = new THREE.Mesh(boxGeo3, stemMat);
gillLine7.name = 'gillLine';
gillLine7.position.set(0.1128, -0.036, -0.2343);
gillLine7.rotation.set(0, deg(154.2857), 0);
cap.add(gillLine7);
const gillLine8 = new THREE.Mesh(boxGeo3, stemMat);
gillLine8.name = 'gillLine';
gillLine8.position.set(0, -0.036, -0.26);
gillLine8.rotation.set(0, deg(180), 0);
cap.add(gillLine8);
const gillLine9 = new THREE.Mesh(boxGeo3, stemMat);
gillLine9.name = 'gillLine';
gillLine9.position.set(-0.1128, -0.036, -0.2343);
gillLine9.rotation.set(0, deg(205.7143), 0);
cap.add(gillLine9);
const gillLine10 = new THREE.Mesh(boxGeo3, stemMat);
gillLine10.name = 'gillLine';
gillLine10.position.set(-0.2033, -0.036, -0.1621);
gillLine10.rotation.set(0, deg(231.4286), 0);
cap.add(gillLine10);
const gillLine11 = new THREE.Mesh(boxGeo3, stemMat);
gillLine11.name = 'gillLine';
gillLine11.position.set(-0.2535, -0.036, -0.0579);
gillLine11.rotation.set(0, deg(257.1429), 0);
cap.add(gillLine11);
const gillLine12 = new THREE.Mesh(boxGeo3, stemMat);
gillLine12.name = 'gillLine';
gillLine12.position.set(-0.2535, -0.036, 0.0579);
gillLine12.rotation.set(0, deg(282.8571), 0);
cap.add(gillLine12);
const gillLine13 = new THREE.Mesh(boxGeo3, stemMat);
gillLine13.name = 'gillLine';
gillLine13.position.set(-0.2033, -0.036, 0.1621);
gillLine13.rotation.set(0, deg(308.5714), 0);
cap.add(gillLine13);
const gillLine14 = new THREE.Mesh(boxGeo3, stemMat);
gillLine14.name = 'gillLine';
gillLine14.position.set(-0.1128, -0.036, 0.2343);
gillLine14.rotation.set(0, deg(334.2857), 0);
cap.add(gillLine14);
const capSpot1 = new THREE.Mesh(new THREE.SphereGeometry(0.09, 8, 3), spotMat);
capSpot1.name = 'capSpot1';
capSpot1.position.set(-0.0001, 0.324, -0.0006);
capSpot1.rotation.set(deg(6.1137), deg(-0.0744), deg(-1.3929));
capSpot1.scale.set(1, 0.3, 1);
cap.add(capSpot1);
const capSpot2 = new THREE.Mesh(sphereGeo4, spotMat);
capSpot2.name = 'capSpot2';
capSpot2.position.set(0.2182, 0.272, 0.0991);
capSpot2.rotation.set(deg(8.3495), deg(-1.291), deg(-17.5497));
capSpot2.scale.set(1, 0.3, 1);
cap.add(capSpot2);
const capSpot3 = new THREE.Mesh(new THREE.SphereGeometry(0.065, 8, 3), spotMat);
capSpot3.name = 'capSpot3';
capSpot3.position.set(-0.1982, 0.2723, 0.1391);
capSpot3.rotation.set(deg(8.3495), deg(1.291), deg(17.5497));
capSpot3.scale.set(1, 0.3, 1);
cap.add(capSpot3);
const capSpot4 = new THREE.Mesh(sphereGeo4, spotMat);
capSpot4.name = 'capSpot4';
capSpot4.position.set(0.0592, 0.2464, 0.2763);
capSpot4.rotation.set(deg(38.2571), deg(-2.8221), deg(-8.1246));
capSpot4.scale.set(1, 0.3, 1);
cap.add(capSpot4);
const capSpot5 = new THREE.Mesh(new THREE.SphereGeometry(0.06, 8, 3), spotMat);
capSpot5.name = 'capSpot5';
capSpot5.position.set(-0.1187, 0.2757, -0.1984);
capSpot5.rotation.set(deg(-15.1708), deg(-1.61), deg(12.046));
capSpot5.scale.set(1, 0.3, 1);
cap.add(capSpot5);
const capSpot6 = new THREE.Mesh(new THREE.SphereGeometry(0.055, 8, 3), spotMat);
capSpot6.name = 'capSpot6';
capSpot6.position.set(0.1987, 0.2663, -0.1684);
capSpot6.rotation.set(deg(-15.1708), deg(1.61), deg(-12.046));
capSpot6.scale.set(1, 0.3, 1);
cap.add(capSpot6);
const capSpot7 = new THREE.Mesh(sphereGeo5, spotMat);
capSpot7.name = 'capSpot7';
capSpot7.position.set(0.3262, 0.2106, -0.02);
capSpot7.rotation.set(0, 0, deg(-39.3714));
capSpot7.scale.set(1, 0.3, 1);
cap.add(capSpot7);
const capSpot8 = new THREE.Mesh(new THREE.SphereGeometry(0.05, 8, 3), spotMat);
capSpot8.name = 'capSpot8';
capSpot8.position.set(-0.3262, 0.2106, -0.04);
capSpot8.rotation.set(0, 0, deg(39.3714));
capSpot8.scale.set(1, 0.3, 1);
cap.add(capSpot8);
const capSpot9 = new THREE.Mesh(sphereGeo5, spotMat);
capSpot9.name = 'capSpot9';
capSpot9.position.set(-0.0789, 0.1743, 0.3551);
capSpot9.rotation.set(deg(55.2304), deg(5.6653), deg(10.8064));
capSpot9.scale.set(1, 0.3, 1);
cap.add(capSpot9);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createMushroomMonster;
评分与评论
0 条评论
暂无评论。分享一下你是如何使用这个模型的,或者有哪些可以改进的地方。
相关模型
同一分类或相似标签









