816 tris0,62 × 0,48 × 0,63 m
Úsalo en código
Hacer remix en el editorslime.js · 106 líneas
Módulo ES autónomo — solo depende de three. Llama a la función factory y añade el grupo a tu escena.
/**
* Slime — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 816 · Size (W × H × D): 0.62 × 0.48 × 0.63 m
*
* Usage:
* import { createSlime } from './slime.js';
*
* const model = createSlime();
* 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);
}
// 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 createSlime() {
const root = new THREE.Group();
root.name = 'Slime';
// Materials
const slimeMat = new THREE.MeshStandardMaterial({ name: 'slime', color: 0x4fb6f0, roughness: 0.12 });
const eyeMat = new THREE.MeshStandardMaterial({ name: 'eye', color: 0x16131b, roughness: 0.1 });
const shineMat = new THREE.MeshStandardMaterial({ name: 'shine', color: 0xffffff, roughness: 0.2, emissive: 0xffffff, emissiveIntensity: 0.35 });
const mouthMat = new THREE.MeshStandardMaterial({ name: 'mouth', color: 0x3b1424, roughness: 0.5, flatShading: true });
const tongueMat = new THREE.MeshStandardMaterial({ name: 'tongue', color: 0xf2768f, roughness: 0.5, flatShading: true });
// Shared geometries
const sphereGeo = new THREE.SphereGeometry(0.047, 10, 8);
const sphereGeo2 = new THREE.SphereGeometry(0.013, 6, 4);
// Parts
const slime = new THREE.Group();
slime.name = 'slime';
root.add(slime);
const body = new THREE.Group();
body.name = 'body';
slime.add(body);
const jelly = new THREE.Mesh(lathe([[0, 0], [0.2, 0.0047], [0.285, 0.0413], [0.315, 0.118], [0.295, 0.2124], [0.225, 0.3009], [0.12, 0.3658], [0.045, 0.4248], [0.012, 0.472], [0, 0.4779]], 18), slimeMat);
jelly.name = 'jelly';
body.add(jelly);
const highlight = new THREE.Mesh(new THREE.SphereGeometry(0.04, 8, 6), shineMat);
highlight.name = 'highlight';
highlight.position.set(-0.13, 0.3, 0.1595);
highlight.rotation.set(0, deg(-30), deg(25));
highlight.scale.set(1.3, 0.7, 0.5);
body.add(highlight);
const face = new THREE.Group();
face.name = 'face';
slime.add(face);
const eyeL = new THREE.Mesh(sphereGeo, eyeMat);
eyeL.name = 'eyeL';
eyeL.position.set(0.085, 0.2, 0.2732);
eyeL.rotation.set(0, deg(16), 0);
eyeL.scale.set(0.8, 1.2, 0.55);
face.add(eyeL);
const eyeShineL = new THREE.Mesh(sphereGeo2, shineMat);
eyeShineL.name = 'eyeShineL';
eyeShineL.position.set(0.083, 0.22, 0.2932);
face.add(eyeShineL);
const eyeR = new THREE.Mesh(sphereGeo, eyeMat);
eyeR.name = 'eyeR';
eyeR.position.set(-0.085, 0.2, 0.2732);
eyeR.rotation.set(0, deg(-16), 0);
eyeR.scale.set(0.8, 1.2, 0.55);
face.add(eyeR);
const eyeShineR = new THREE.Mesh(sphereGeo2, shineMat);
eyeShineR.name = 'eyeShineR';
eyeShineR.position.set(-0.099, 0.22, 0.2932);
face.add(eyeShineR);
const mouth = new THREE.Mesh(extrude([[-0.045, 0], [0.045, 0], [0.038, -0.022], [0.02, -0.036], [0, -0.04], [-0.02, -0.036], [-0.038, -0.022]], 0.04), mouthMat);
mouth.name = 'mouth';
mouth.position.set(0, 0.125, 0.2955);
face.add(mouth);
const tongue = new THREE.Mesh(new THREE.SphereGeometry(0.022, 6, 4), tongueMat);
tongue.name = 'tongue';
tongue.position.set(0, 0.095, 0.3075);
tongue.scale.set(1.1, 0.5, 0.6);
face.add(tongue);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createSlime;
Valoraciones y comentarios
0 comentarios
Aún no hay comentarios. Cuenta cómo usaste este modelo o qué se podría mejorar.
Modelos relacionados
Misma categoría o etiquetas similares









