Codels
1,2 mil tris0,76 × 1,48 × 0,77 m

Úsalo en código

Hacer remix en el editor
Módulo ES autónomo — solo depende de three. Llama a la función factory y añade el grupo a tu escena.
/**
 * Brazier — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,168 · Size (W × H × D): 0.76 × 1.48 × 0.77 m
 *
 * Usage:
 *   import { createBrazier } from './brazier.js';
 *   
 *   const model = createBrazier();
 *   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;
}

// 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 createBrazier() {
  const root = new THREE.Group();
  root.name = 'Brazier';

  // Materials
  const ironMat = new THREE.MeshStandardMaterial({ name: 'iron', color: 0x4a4645, roughness: 0.55, metalness: 0.5, flatShading: true });
  const ironDarkMat = new THREE.MeshStandardMaterial({ name: 'ironDark', color: 0x292726, roughness: 0.8, metalness: 0.3, flatShading: true });
  const coalMat = new THREE.MeshStandardMaterial({ name: 'coal', color: 0x2a1d18, roughness: 1, flatShading: true });
  const emberMat = new THREE.MeshStandardMaterial({ name: 'ember', color: 0xff6a1a, roughness: 1, emissive: 0xff4a00, emissiveIntensity: 1.2, flatShading: true });
  const redMat = new THREE.MeshStandardMaterial({ name: 'red', color: 0xe8401c, roughness: 1, emissive: 0xd42c08, emissiveIntensity: 1.1, flatShading: true });
  const orangeMat = new THREE.MeshStandardMaterial({ name: 'orange', color: 0xff7a1a, roughness: 1, emissive: 0xf05a00, emissiveIntensity: 1.25, flatShading: true });
  const yellowMat = new THREE.MeshStandardMaterial({ name: 'yellow', color: 0xffd760, roughness: 1, emissive: 0xffb830, emissiveIntensity: 1.4, flatShading: true });

  // Shared geometries
  const coneGeo = new THREE.ConeGeometry(0.022, 0.08, 4);
  const sphereGeo = new THREE.SphereGeometry(0.04, 6, 4);
  const boxGeo = new THREE.BoxGeometry(0.022, 0.5934, 0.03);

  // Parts
  const bowl = new THREE.Mesh(lathe([[0, 0], [0.12, 0], [0.22, 0.06], [0.29, 0.14], [0.32, 0.2], [0.345, 0.222], [0.335, 0.237], [0.305, 0.215], [0.27, 0.15], [0.19, 0.085], [0, 0.075]], 12), ironMat);
  bowl.name = 'bowl';
  bowl.position.set(0, 0.665, 0);
  root.add(bowl);
  const bowlBand = new THREE.Mesh(lathe([[0.287, 0.128], [0.3, 0.13], [0.312, 0.152], [0.299, 0.152]], 12), ironDarkMat);
  bowlBand.name = 'bowlBand';
  bowlBand.position.set(0, 0.665, 0);
  root.add(bowlBand);
  const rimSpike = new THREE.Mesh(coneGeo, ironMat);
  rimSpike.name = 'rimSpike';
  rimSpike.position.set(0.3095, 0.925, 0.1282);
  rimSpike.rotation.set(deg(7.2642), deg(-1.1373), deg(-17.7741));
  root.add(rimSpike);
  const rimSpike2 = new THREE.Mesh(coneGeo, ironMat);
  rimSpike2.name = 'rimSpike';
  rimSpike2.position.set(0.1282, 0.925, 0.3095);
  rimSpike2.rotation.set(deg(17.7741), deg(-1.1373), deg(-7.2642));
  root.add(rimSpike2);
  const rimSpike3 = new THREE.Mesh(coneGeo, ironMat);
  rimSpike3.name = 'rimSpike';
  rimSpike3.position.set(-0.1282, 0.925, 0.3095);
  rimSpike3.rotation.set(deg(17.7741), deg(1.1373), deg(7.2642));
  root.add(rimSpike3);
  const rimSpike4 = new THREE.Mesh(coneGeo, ironMat);
  rimSpike4.name = 'rimSpike';
  rimSpike4.position.set(-0.3095, 0.925, 0.1282);
  rimSpike4.rotation.set(deg(7.2642), deg(1.1373), deg(17.7741));
  root.add(rimSpike4);
  const rimSpike5 = new THREE.Mesh(coneGeo, ironMat);
  rimSpike5.name = 'rimSpike';
  rimSpike5.position.set(-0.3095, 0.925, -0.1282);
  rimSpike5.rotation.set(deg(-7.2642), deg(-1.1373), deg(17.7741));
  root.add(rimSpike5);
  const rimSpike6 = new THREE.Mesh(coneGeo, ironMat);
  rimSpike6.name = 'rimSpike';
  rimSpike6.position.set(-0.1282, 0.925, -0.3095);
  rimSpike6.rotation.set(deg(-17.7741), deg(-1.1373), deg(7.2642));
  root.add(rimSpike6);
  const rimSpike7 = new THREE.Mesh(coneGeo, ironMat);
  rimSpike7.name = 'rimSpike';
  rimSpike7.position.set(0.1282, 0.925, -0.3095);
  rimSpike7.rotation.set(deg(-17.7741), deg(1.1373), deg(-7.2642));
  root.add(rimSpike7);
  const rimSpike8 = new THREE.Mesh(coneGeo, ironMat);
  rimSpike8.name = 'rimSpike';
  rimSpike8.position.set(0.3095, 0.925, -0.1282);
  rimSpike8.rotation.set(deg(-7.2642), deg(1.1373), deg(-17.7741));
  root.add(rimSpike8);
  const leg = new THREE.Mesh(tube([[0, 0.03, 0.37], [0, 0.2328, 0.35], [0, 0.4788, 0.28], [0, 0.725, 0.2]], 0.022, 10, 5), ironMat);
  leg.name = 'leg';
  root.add(leg);
  const foot = new THREE.Mesh(sphereGeo, ironMat);
  foot.name = 'foot';
  foot.position.set(0, 0.026, 0.38);
  foot.scale.set(1.25, 0.65, 1.25);
  root.add(foot);
  const leg2 = new THREE.Mesh(tube([[-0.3204, 0.03, -0.185], [-0.3031, 0.2328, -0.175], [-0.2425, 0.4788, -0.14], [-0.1732, 0.725, -0.1]], 0.022, 10, 5), ironMat);
  leg2.name = 'leg';
  root.add(leg2);
  const foot2 = new THREE.Mesh(sphereGeo, ironMat);
  foot2.name = 'foot';
  foot2.position.set(-0.3291, 0.026, -0.19);
  foot2.scale.set(1.25, 0.65, 1.25);
  root.add(foot2);
  const leg3 = new THREE.Mesh(tube([[0.3204, 0.03, -0.185], [0.3031, 0.2328, -0.175], [0.2425, 0.4788, -0.14], [0.1732, 0.725, -0.1]], 0.022, 10, 5), ironMat);
  leg3.name = 'leg';
  root.add(leg3);
  const foot3 = new THREE.Mesh(sphereGeo, ironMat);
  foot3.name = 'foot';
  foot3.position.set(0.3291, 0.026, -0.19);
  foot3.scale.set(1.25, 0.65, 1.25);
  root.add(foot3);
  const brace = new THREE.Mesh(boxGeo, ironDarkMat);
  brace.name = 'brace';
  brace.position.set(-0.1434, 0.2993, 0.0828);
  brace.rotation.set(deg(-90), 0, deg(30));
  root.add(brace);
  const brace2 = new THREE.Mesh(boxGeo, ironDarkMat);
  brace2.name = 'brace';
  brace2.position.set(0, 0.2993, -0.1655);
  brace2.rotation.set(deg(-90), 0, deg(-90));
  root.add(brace2);
  const brace3 = new THREE.Mesh(boxGeo, ironDarkMat);
  brace3.name = 'brace';
  brace3.position.set(0.1434, 0.2993, 0.0828);
  brace3.rotation.set(deg(-90), 0, deg(150));
  root.add(brace3);
  const coalBed = new THREE.Mesh(jitter(new THREE.SphereGeometry(0.27, 8, 3, 0, Math.PI * 2, 0, Math.PI / 2), 0.012, 4), coalMat);
  coalBed.name = 'coalBed';
  coalBed.position.set(0, 0.815, 0);
  coalBed.scale.set(1, 0.36, 1);
  root.add(coalBed);
  const coal = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.0406, 0), 0.0061, 0), coalMat);
  coal.name = 'coal';
  coal.position.set(0.1465, 0.9064, 0.0156);
  coal.rotation.set(deg(14.8925), deg(7.9007), 0);
  root.add(coal);
  const ember = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.0409, 0), 0.0061, 1), emberMat);
  ember.name = 'ember';
  ember.position.set(0.1278, 0.9046, 0.0884);
  ember.rotation.set(deg(23.1084), deg(61.5041), 0);
  root.add(ember);
  const ember2 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.0347, 0), 0.0052, 2), emberMat);
  ember2.name = 'ember';
  ember2.position.set(0.0748, 0.9025, 0.1385);
  ember2.rotation.set(deg(17.8695), deg(56.7548), 0);
  root.add(ember2);
  const coal2 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.0397, 0), 0.006, 3), coalMat);
  coal2.name = 'coal';
  coal2.position.set(0.0127, 0.904, 0.1559);
  coal2.rotation.set(deg(62.2034), deg(60.2945), 0);
  root.add(coal2);
  const ember3 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.0413, 0), 0.0062, 4), emberMat);
  ember3.name = 'ember';
  ember3.position.set(-0.0472, 0.8961, 0.1787);
  ember3.rotation.set(deg(36.5282), deg(5.7446), 0);
  root.add(ember3);
  const ember4 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.0364, 0), 0.0055, 5), emberMat);
  ember4.name = 'ember';
  ember4.position.set(-0.0836, 0.8856, 0.1914);
  ember4.rotation.set(deg(38.1989), deg(57.1465), 0);
  root.add(ember4);
  const coal3 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.0346, 0), 0.0052, 6), coalMat);
  coal3.name = 'coal';
  coal3.position.set(-0.1243, 0.9078, 0.0505);
  coal3.rotation.set(deg(72.2731), deg(9.4593), 0);
  root.add(coal3);
  const ember5 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.0322, 0), 0.0048, 7), emberMat);
  ember5.name = 'ember';
  ember5.position.set(-0.1529, 0.9015, -0.043);
  ember5.rotation.set(deg(64.6398), deg(17.726), 0);
  root.add(ember5);
  const ember6 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.0317, 0), 0.0048, 8), emberMat);
  ember6.name = 'ember';
  ember6.position.set(-0.1812, 0.8899, -0.0731);
  ember6.rotation.set(deg(68.7352), deg(22.308), 0);
  root.add(ember6);
  const coal4 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.0371, 0), 0.0056, 9), coalMat);
  coal4.name = 'coal';
  coal4.position.set(-0.0485, 0.9138, -0.0918);
  coal4.rotation.set(deg(16.7985), deg(20.3714), 0);
  root.add(coal4);
  const ember7 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.044, 0), 0.0066, 10), emberMat);
  ember7.name = 'ember';
  ember7.position.set(-0.0032, 0.9192, -0.0748);
  ember7.rotation.set(deg(11.2841), deg(42.8681), 0);
  root.add(ember7);
  const ember8 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.0467, 0), 0.007, 11), emberMat);
  ember8.name = 'ember';
  ember8.position.set(0.0354, 0.9197, -0.0684);
  ember8.rotation.set(deg(7.4681), deg(69.8295), 0);
  root.add(ember8);
  const coal5 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.0315, 0), 0.0047, 12), coalMat);
  coal5.name = 'coal';
  coal5.position.set(0.0418, 0.9181, -0.0303);
  coal5.rotation.set(deg(61.2706), deg(12.8874), 0);
  root.add(coal5);
  const ember9 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.0432, 0), 0.0065, 13), emberMat);
  ember9.name = 'ember';
  ember9.position.set(0.0777, 0.9172, -0.0467);
  ember9.rotation.set(deg(49.8613), deg(60.0203), 0);
  root.add(ember9);
  const flames = new THREE.Group();
  flames.name = 'flames';
  flames.position.set(0, 0.865, 0);
  root.add(flames);
  const flameMain = new THREE.Mesh(jitter(new THREE.ConeGeometry(0.13, 0.5, 6), 0.014, 3), orangeMat);
  flameMain.name = 'flameMain';
  flameMain.position.set(0, 0.25, -0.01);
  flameMain.rotation.set(0, deg(15), deg(3));
  flames.add(flameMain);
  const flameBackL = new THREE.Mesh(jitter(new THREE.ConeGeometry(0.1, 0.4, 6), 0.01, 4), redMat);
  flameBackL.name = 'flameBackL';
  flameBackL.position.set(-0.09, 0.2, -0.07);
  flameBackL.rotation.set(deg(-8), 0, deg(14));
  flames.add(flameBackL);
  const flameBackR = new THREE.Mesh(jitter(new THREE.ConeGeometry(0.09, 0.34, 6), 0.01, 5), redMat);
  flameBackR.name = 'flameBackR';
  flameBackR.position.set(0.1, 0.17, -0.05);
  flameBackR.rotation.set(deg(-6), 0, deg(-16));
  flames.add(flameBackR);
  const flameSideL = new THREE.Mesh(jitter(new THREE.ConeGeometry(0.08, 0.28, 6), 0.008, 7), orangeMat);
  flameSideL.name = 'flameSideL';
  flameSideL.position.set(-0.13, 0.14, 0.05);
  flameSideL.rotation.set(deg(10), 0, deg(22));
  flames.add(flameSideL);
  const flameSideR = new THREE.Mesh(new THREE.ConeGeometry(0.075, 0.25, 6), redMat);
  flameSideR.name = 'flameSideR';
  flameSideR.position.set(0.13, 0.125, 0.04);
  flameSideR.rotation.set(deg(8), 0, deg(-24));
  flames.add(flameSideR);
  const flameFront = new THREE.Mesh(jitter(new THREE.ConeGeometry(0.085, 0.3, 6), 0.008, 6), yellowMat);
  flameFront.name = 'flameFront';
  flameFront.position.set(0.01, 0.15, 0.09);
  flameFront.rotation.set(deg(14), 0, deg(-4));
  flames.add(flameFront);
  const flameFrontR = new THREE.Mesh(new THREE.ConeGeometry(0.05, 0.17, 5), yellowMat);
  flameFrontR.name = 'flameFrontR';
  flameFrontR.position.set(0.09, 0.085, 0.1);
  flameFrontR.rotation.set(deg(18), 0, deg(-20));
  flames.add(flameFrontR);
  const flameFrontL = new THREE.Mesh(new THREE.ConeGeometry(0.045, 0.15, 5), orangeMat);
  flameFrontL.name = 'flameFrontL';
  flameFrontL.position.set(-0.08, 0.075, 0.11);
  flameFrontL.rotation.set(deg(20), 0, deg(18));
  flames.add(flameFrontL);
  const spark = new THREE.Mesh(new THREE.TetrahedronGeometry(0.0129, 0), orangeMat);
  spark.name = 'spark';
  spark.position.set(0.0775, 0.5071, -0.1058);
  spark.rotation.set(deg(59.3976), deg(46.2127), 0);
  flames.add(spark);
  const spark2 = new THREE.Mesh(new THREE.TetrahedronGeometry(0.0118, 0), yellowMat);
  spark2.name = 'spark';
  spark2.position.set(-0.1475, 0.6091, -0.1076);
  spark2.rotation.set(deg(49.6722), deg(10.2049), 0);
  flames.add(spark2);
  const spark3 = new THREE.Mesh(new THREE.TetrahedronGeometry(0.0099, 0), orangeMat);
  spark3.name = 'spark';
  spark3.position.set(-0.0062, 0.5313, -0.0856);
  spark3.rotation.set(deg(42.6723), deg(71.0909), 0);
  flames.add(spark3);
  const spark4 = new THREE.Mesh(new THREE.TetrahedronGeometry(0.0081, 0), yellowMat);
  spark4.name = 'spark';
  spark4.position.set(0.0858, 0.6057, -0.0217);
  spark4.rotation.set(deg(81.4709), deg(27.8737), 0);
  flames.add(spark4);
  const spark5 = new THREE.Mesh(new THREE.TetrahedronGeometry(0.0097, 0), orangeMat);
  spark5.name = 'spark';
  spark5.position.set(0.0178, 0.4829, -0.092);
  spark5.rotation.set(deg(54.2315), deg(71.3583), 0);
  flames.add(spark5);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createBrazier;

Valoraciones y comentarios

—
Aún no hay valoraciones — sé el primero.
5
0
4
0
3
0
2
0
1
0

Inicia sesión para valorar y comentar.

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