Codels
삼각형 1.2천개0.98 × 1.21 × 0.94 m

코드에서 사용하기

에디터에서 리믹스
독립형 ES 모듈이에요 — three에만 의존해요. 팩토리 함수를 호출하고 그룹을 씬에 추가하세요.
/**
 * Iron Chandelier — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,204 · Size (W × H × D): 0.98 × 1.21 × 0.94 m
 *
 * Usage:
 *   import { createChandelier } from './chandelier.js';
 *   
 *   const model = createChandelier();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

export function createChandelier() {
  const root = new THREE.Group();
  root.name = 'Chandelier';

  // Materials
  const ironMat = new THREE.MeshStandardMaterial({ name: 'iron', color: 0x5a534c, roughness: 0.55, metalness: 0.5, flatShading: true });
  const waxMat = new THREE.MeshStandardMaterial({ name: 'wax', color: 0xeee2c2, roughness: 0.55, flatShading: true });
  const flameOutMat = new THREE.MeshStandardMaterial({ name: 'flameOut', color: 0xff9a2a, roughness: 1, emissive: 0xff7a10, emissiveIntensity: 1.3, flatShading: true });
  const flameInMat = new THREE.MeshStandardMaterial({ name: 'flameIn', color: 0xfff1a8, roughness: 1, emissive: 0xffd860, emissiveIntensity: 1.5, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.45, 0.018, 0.022);
  const cylinderGeo = new THREE.CylinderGeometry(0.048, 0.022, 0.04, 6);
  const coneGeo = new THREE.ConeGeometry(0.016, 0.06, 4);
  const sphereGeo = new THREE.SphereGeometry(0.016, 5, 4);
  const coneGeo2 = new THREE.ConeGeometry(0.014, 0.06, 5);
  const boxGeo2 = new THREE.BoxGeometry(0.02, 0.1492, 0.006);

  // Parts
  const finialTip = new THREE.Mesh(new THREE.ConeGeometry(0.032, 0.13, 6), ironMat);
  finialTip.name = 'finialTip';
  finialTip.position.set(0, 0.065, 0);
  finialTip.rotation.set(deg(180), 0, 0);
  root.add(finialTip);
  const finialKnob = new THREE.Mesh(new THREE.SphereGeometry(0.04, 6, 4), ironMat);
  finialKnob.name = 'finialKnob';
  finialKnob.position.set(0, 0.14, 0);
  root.add(finialKnob);
  const hub = new THREE.Mesh(new THREE.CylinderGeometry(0.045, 0.045, 0.09, 6), ironMat);
  hub.name = 'hub';
  hub.position.set(0, 0.2, 0);
  root.add(hub);
  const ring = new THREE.Mesh(new THREE.TorusGeometry(0.45, 0.02, 4, 16), ironMat);
  ring.name = 'ring';
  ring.position.set(0, 0.2, 0);
  ring.rotation.set(deg(90), 0, 0);
  root.add(ring);
  const spoke = new THREE.Mesh(boxGeo, ironMat);
  spoke.name = 'spoke';
  spoke.position.set(0, 0.2, 0.225);
  spoke.rotation.set(0, deg(-90), 0);
  root.add(spoke);
  const spoke2 = new THREE.Mesh(boxGeo, ironMat);
  spoke2.name = 'spoke';
  spoke2.position.set(-0.1949, 0.2, -0.1125);
  spoke2.rotation.set(0, deg(-210), 0);
  root.add(spoke2);
  const spoke3 = new THREE.Mesh(boxGeo, ironMat);
  spoke3.name = 'spoke';
  spoke3.position.set(0.1949, 0.2, -0.1125);
  spoke3.rotation.set(0, deg(-330), 0);
  root.add(spoke3);
  const cup = new THREE.Mesh(cylinderGeo, ironMat);
  cup.name = 'cup';
  cup.position.set(-0.225, 0.232, 0.3897);
  root.add(cup);
  const spike = new THREE.Mesh(coneGeo, ironMat);
  spike.name = 'spike';
  spike.position.set(-0.225, 0.155, 0.3897);
  spike.rotation.set(deg(180), 0, 0);
  root.add(spike);
  const candle = new THREE.Mesh(new THREE.CylinderGeometry(0.021, 0.023, 0.1119, 6), waxMat);
  candle.name = 'candle';
  candle.position.set(-0.225, 0.301, 0.3897);
  root.add(candle);
  const flameBase = new THREE.Mesh(sphereGeo, flameOutMat);
  flameBase.name = 'flameBase';
  flameBase.position.set(-0.225, 0.3789, 0.3897);
  flameBase.scale.set(1, 1.25, 1);
  root.add(flameBase);
  const flameTip = new THREE.Mesh(coneGeo2, flameInMat);
  flameTip.name = 'flameTip';
  flameTip.position.set(-0.225, 0.4089, 0.3897);
  root.add(flameTip);
  const cup2 = new THREE.Mesh(cylinderGeo, ironMat);
  cup2.name = 'cup';
  cup2.position.set(-0.45, 0.232, 0);
  root.add(cup2);
  const spike2 = new THREE.Mesh(coneGeo, ironMat);
  spike2.name = 'spike';
  spike2.position.set(-0.45, 0.155, 0);
  spike2.rotation.set(deg(180), 0, 0);
  root.add(spike2);
  const candle2 = new THREE.Mesh(new THREE.CylinderGeometry(0.021, 0.023, 0.1557, 6), waxMat);
  candle2.name = 'candle';
  candle2.position.set(-0.45, 0.3228, 0);
  root.add(candle2);
  const flameBase2 = new THREE.Mesh(sphereGeo, flameOutMat);
  flameBase2.name = 'flameBase';
  flameBase2.position.set(-0.45, 0.4227, 0);
  flameBase2.scale.set(1, 1.25, 1);
  root.add(flameBase2);
  const flameTip2 = new THREE.Mesh(coneGeo2, flameInMat);
  flameTip2.name = 'flameTip';
  flameTip2.position.set(-0.45, 0.4527, 0);
  root.add(flameTip2);
  const cup3 = new THREE.Mesh(cylinderGeo, ironMat);
  cup3.name = 'cup';
  cup3.position.set(-0.225, 0.232, -0.3897);
  root.add(cup3);
  const spike3 = new THREE.Mesh(coneGeo, ironMat);
  spike3.name = 'spike';
  spike3.position.set(-0.225, 0.155, -0.3897);
  spike3.rotation.set(deg(180), 0, 0);
  root.add(spike3);
  const candle3 = new THREE.Mesh(new THREE.CylinderGeometry(0.021, 0.023, 0.1493, 6), waxMat);
  candle3.name = 'candle';
  candle3.position.set(-0.225, 0.3197, -0.3897);
  root.add(candle3);
  const flameBase3 = new THREE.Mesh(sphereGeo, flameOutMat);
  flameBase3.name = 'flameBase';
  flameBase3.position.set(-0.225, 0.4163, -0.3897);
  flameBase3.scale.set(1, 1.25, 1);
  root.add(flameBase3);
  const flameTip3 = new THREE.Mesh(coneGeo2, flameInMat);
  flameTip3.name = 'flameTip';
  flameTip3.position.set(-0.225, 0.4463, -0.3897);
  root.add(flameTip3);
  const cup4 = new THREE.Mesh(cylinderGeo, ironMat);
  cup4.name = 'cup';
  cup4.position.set(0.225, 0.232, -0.3897);
  root.add(cup4);
  const spike4 = new THREE.Mesh(coneGeo, ironMat);
  spike4.name = 'spike';
  spike4.position.set(0.225, 0.155, -0.3897);
  spike4.rotation.set(deg(180), 0, 0);
  root.add(spike4);
  const candle4 = new THREE.Mesh(new THREE.CylinderGeometry(0.021, 0.023, 0.1287, 6), waxMat);
  candle4.name = 'candle';
  candle4.position.set(0.225, 0.3094, -0.3897);
  root.add(candle4);
  const flameBase4 = new THREE.Mesh(sphereGeo, flameOutMat);
  flameBase4.name = 'flameBase';
  flameBase4.position.set(0.225, 0.3957, -0.3897);
  flameBase4.scale.set(1, 1.25, 1);
  root.add(flameBase4);
  const flameTip4 = new THREE.Mesh(coneGeo2, flameInMat);
  flameTip4.name = 'flameTip';
  flameTip4.position.set(0.225, 0.4257, -0.3897);
  root.add(flameTip4);
  const cup5 = new THREE.Mesh(cylinderGeo, ironMat);
  cup5.name = 'cup';
  cup5.position.set(0.45, 0.232, 0);
  root.add(cup5);
  const spike5 = new THREE.Mesh(coneGeo, ironMat);
  spike5.name = 'spike';
  spike5.position.set(0.45, 0.155, 0);
  spike5.rotation.set(deg(180), 0, 0);
  root.add(spike5);
  const candle5 = new THREE.Mesh(new THREE.CylinderGeometry(0.021, 0.023, 0.133, 6), waxMat);
  candle5.name = 'candle';
  candle5.position.set(0.45, 0.3115, 0);
  root.add(candle5);
  const flameBase5 = new THREE.Mesh(sphereGeo, flameOutMat);
  flameBase5.name = 'flameBase';
  flameBase5.position.set(0.45, 0.4, 0);
  flameBase5.scale.set(1, 1.25, 1);
  root.add(flameBase5);
  const flameTip5 = new THREE.Mesh(coneGeo2, flameInMat);
  flameTip5.name = 'flameTip';
  flameTip5.position.set(0.45, 0.43, 0);
  root.add(flameTip5);
  const cup6 = new THREE.Mesh(cylinderGeo, ironMat);
  cup6.name = 'cup';
  cup6.position.set(0.225, 0.232, 0.3897);
  root.add(cup6);
  const spike6 = new THREE.Mesh(coneGeo, ironMat);
  spike6.name = 'spike';
  spike6.position.set(0.225, 0.155, 0.3897);
  spike6.rotation.set(deg(180), 0, 0);
  root.add(spike6);
  const candle6 = new THREE.Mesh(new THREE.CylinderGeometry(0.021, 0.023, 0.1341, 6), waxMat);
  candle6.name = 'candle';
  candle6.position.set(0.225, 0.3121, 0.3897);
  root.add(candle6);
  const flameBase6 = new THREE.Mesh(sphereGeo, flameOutMat);
  flameBase6.name = 'flameBase';
  flameBase6.position.set(0.225, 0.4011, 0.3897);
  flameBase6.scale.set(1, 1.25, 1);
  root.add(flameBase6);
  const flameTip6 = new THREE.Mesh(coneGeo2, flameInMat);
  flameTip6.name = 'flameTip';
  flameTip6.position.set(0.225, 0.4311, 0.3897);
  root.add(flameTip6);
  const chainLink = new THREE.Mesh(boxGeo2, ironMat);
  chainLink.name = 'chainLink';
  chainLink.position.set(0, 0.27, 0.2591);
  chainLink.rotation.set(deg(-18.3735), deg(90), 0);
  root.add(chainLink);
  const chainLink2 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink2.name = 'chainLink';
  chainLink2.position.set(0, 0.39, 0.2192);
  chainLink2.rotation.set(deg(161.6265), 0, deg(180));
  root.add(chainLink2);
  const chainLink3 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink3.name = 'chainLink';
  chainLink3.position.set(0, 0.51, 0.1794);
  chainLink3.rotation.set(deg(-18.3735), deg(90), 0);
  root.add(chainLink3);
  const chainLink4 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink4.name = 'chainLink';
  chainLink4.position.set(0, 0.63, 0.1395);
  chainLink4.rotation.set(deg(161.6265), 0, deg(180));
  root.add(chainLink4);
  const chainLink5 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink5.name = 'chainLink';
  chainLink5.position.set(0, 0.75, 0.0996);
  chainLink5.rotation.set(deg(-18.3735), deg(90), 0);
  root.add(chainLink5);
  const chainLink6 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink6.name = 'chainLink';
  chainLink6.position.set(0, 0.87, 0.0598);
  chainLink6.rotation.set(deg(161.6265), 0, deg(180));
  root.add(chainLink6);
  const chainLink7 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink7.name = 'chainLink';
  chainLink7.position.set(0, 0.99, 0.0199);
  chainLink7.rotation.set(deg(-18.3735), deg(90), 0);
  root.add(chainLink7);
  const chainLink8 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink8.name = 'chainLink';
  chainLink8.position.set(-0.2244, 0.27, -0.1295);
  chainLink8.rotation.set(deg(-162.0759), deg(-27.5011), deg(-162.0759));
  root.add(chainLink8);
  const chainLink9 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink9.name = 'chainLink';
  chainLink9.position.set(-0.1898, 0.39, -0.1096);
  chainLink9.rotation.set(deg(-17.0862), deg(-57.5597), deg(-30.5901));
  root.add(chainLink9);
  const chainLink10 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink10.name = 'chainLink';
  chainLink10.position.set(-0.1553, 0.51, -0.0897);
  chainLink10.rotation.set(deg(-162.0759), deg(-27.5011), deg(-162.0759));
  root.add(chainLink10);
  const chainLink11 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink11.name = 'chainLink';
  chainLink11.position.set(-0.1208, 0.63, -0.0698);
  chainLink11.rotation.set(deg(-17.0862), deg(-57.5597), deg(-30.5901));
  root.add(chainLink11);
  const chainLink12 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink12.name = 'chainLink';
  chainLink12.position.set(-0.0863, 0.75, -0.0498);
  chainLink12.rotation.set(deg(-162.0759), deg(-27.5011), deg(-162.0759));
  root.add(chainLink12);
  const chainLink13 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink13.name = 'chainLink';
  chainLink13.position.set(-0.0518, 0.87, -0.0299);
  chainLink13.rotation.set(deg(-17.0862), deg(-57.5597), deg(-30.5901));
  root.add(chainLink13);
  const chainLink14 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink14.name = 'chainLink';
  chainLink14.position.set(-0.0173, 0.99, -0.01);
  chainLink14.rotation.set(deg(-162.0759), deg(-27.5011), deg(-162.0759));
  root.add(chainLink14);
  const chainLink15 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink15.name = 'chainLink';
  chainLink15.position.set(0.2244, 0.27, -0.1295);
  chainLink15.rotation.set(deg(17.9241), deg(-27.5011), deg(17.9241));
  root.add(chainLink15);
  const chainLink16 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink16.name = 'chainLink';
  chainLink16.position.set(0.1898, 0.39, -0.1096);
  chainLink16.rotation.set(deg(-17.0862), deg(57.5597), deg(30.5901));
  root.add(chainLink16);
  const chainLink17 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink17.name = 'chainLink';
  chainLink17.position.set(0.1553, 0.51, -0.0897);
  chainLink17.rotation.set(deg(17.9241), deg(-27.5011), deg(17.9241));
  root.add(chainLink17);
  const chainLink18 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink18.name = 'chainLink';
  chainLink18.position.set(0.1208, 0.63, -0.0698);
  chainLink18.rotation.set(deg(-17.0862), deg(57.5597), deg(30.5901));
  root.add(chainLink18);
  const chainLink19 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink19.name = 'chainLink';
  chainLink19.position.set(0.0863, 0.75, -0.0498);
  chainLink19.rotation.set(deg(17.9241), deg(-27.5011), deg(17.9241));
  root.add(chainLink19);
  const chainLink20 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink20.name = 'chainLink';
  chainLink20.position.set(0.0518, 0.87, -0.0299);
  chainLink20.rotation.set(deg(-17.0862), deg(57.5597), deg(30.5901));
  root.add(chainLink20);
  const chainLink21 = new THREE.Mesh(boxGeo2, ironMat);
  chainLink21.name = 'chainLink';
  chainLink21.position.set(0.0173, 0.99, -0.01);
  chainLink21.rotation.set(deg(17.9241), deg(-27.5011), deg(17.9241));
  root.add(chainLink21);
  const crown = new THREE.Mesh(new THREE.CylinderGeometry(0.018, 0.03, 0.08, 6), ironMat);
  crown.name = 'crown';
  crown.position.set(0, 1.06, 0);
  root.add(crown);
  const crownKnob = new THREE.Mesh(new THREE.SphereGeometry(0.03, 6, 4), ironMat);
  crownKnob.name = 'crownKnob';
  crownKnob.position.set(0, 1.05, 0);
  root.add(crownKnob);
  const hangRing = new THREE.Mesh(new THREE.TorusGeometry(0.05, 0.011, 4, 10), ironMat);
  hangRing.name = 'hangRing';
  hangRing.position.set(0, 1.15, 0);
  root.add(hangRing);

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

export default createChandelier;

평점 및 댓글

—
아직 평점이 없어요 — 첫 평점을 남겨 보세요.
5
0
4
0
3
0
2
0
1
0

평점과 댓글을 남기려면 로그인하세요.

댓글 0개

아직 댓글이 없어요. 이 모델을 어떻게 사용했는지, 어떤 점이 더 나아질 수 있을지 공유해 주세요.

관련 모델

같은 카테고리 또는 비슷한 태그