clockwork-orrery.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. import type { Scene } from "./_helpers";
  2. export const clockworkOrrery: Scene = {
  3. name: "Clockwork Orrery",
  4. description:
  5. "Interlocking brass/gold rings spinning at different tilts and speeds with orbiting metallic planets. Like the inside of a celestial clockwork mechanism.",
  6. spec: {
  7. root: "scene",
  8. elements: {
  9. scene: {
  10. type: "Group",
  11. props: { position: null, rotation: null, scale: null },
  12. children: [
  13. "cam",
  14. "env",
  15. "ambient",
  16. "key",
  17. "warm",
  18. "accent",
  19. "center",
  20. "ring-spin-0",
  21. "ring-spin-1",
  22. "ring-spin-2",
  23. "ring-spin-3",
  24. "planet-orbit-0",
  25. "planet-orbit-1",
  26. "planet-orbit-2",
  27. "sparkles",
  28. "post",
  29. "controls",
  30. ],
  31. },
  32. cam: {
  33. type: "PerspectiveCamera",
  34. props: {
  35. position: [0, 3, 8],
  36. fov: 50,
  37. makeDefault: true,
  38. },
  39. children: [],
  40. },
  41. env: {
  42. type: "Environment",
  43. props: {
  44. preset: "dawn",
  45. background: true,
  46. blur: 1,
  47. intensity: 0.5,
  48. },
  49. children: [],
  50. },
  51. ambient: {
  52. type: "AmbientLight",
  53. props: { color: "#332200", intensity: 0.4 },
  54. children: [],
  55. },
  56. key: {
  57. type: "DirectionalLight",
  58. props: {
  59. position: [5, 10, 5],
  60. rotation: null,
  61. scale: null,
  62. color: "#ffddaa",
  63. intensity: 2,
  64. castShadow: true,
  65. },
  66. children: [],
  67. },
  68. warm: {
  69. type: "PointLight",
  70. props: {
  71. position: [0, 0, 0],
  72. rotation: null,
  73. scale: null,
  74. color: "#ffaa44",
  75. intensity: 30,
  76. distance: 15,
  77. decay: 2,
  78. castShadow: false,
  79. },
  80. children: [],
  81. },
  82. accent: {
  83. type: "PointLight",
  84. props: {
  85. position: [-4, 3, -4],
  86. rotation: null,
  87. scale: null,
  88. color: "#ffcc88",
  89. intensity: 15,
  90. distance: 15,
  91. decay: 2,
  92. castShadow: false,
  93. },
  94. children: [],
  95. },
  96. center: {
  97. type: "Float",
  98. props: {
  99. position: null,
  100. rotation: null,
  101. scale: null,
  102. speed: 0.5,
  103. rotationIntensity: 0.1,
  104. floatIntensity: 0.2,
  105. enabled: true,
  106. },
  107. children: ["center-sphere"],
  108. },
  109. "center-sphere": {
  110. type: "GlassSphere",
  111. props: {
  112. position: null,
  113. rotation: null,
  114. scale: null,
  115. castShadow: false,
  116. receiveShadow: false,
  117. radius: 0.5,
  118. widthSegments: 32,
  119. heightSegments: 16,
  120. color: "#ffddaa",
  121. transmission: 1,
  122. thickness: 0.8,
  123. roughness: 0,
  124. chromaticAberration: 0.1,
  125. ior: 1.8,
  126. distortion: 0.05,
  127. distortionScale: null,
  128. temporalDistortion: null,
  129. samples: 10,
  130. resolution: 256,
  131. },
  132. children: [],
  133. },
  134. "ring-spin-0": {
  135. type: "Spin",
  136. props: {
  137. position: null,
  138. rotation: [0.3, 0, 0.8],
  139. scale: null,
  140. speed: 1.2,
  141. axis: "y",
  142. },
  143. children: ["ring-torus-0"],
  144. },
  145. "ring-torus-0": {
  146. type: "Torus",
  147. props: {
  148. position: null,
  149. rotation: [1.5708, 0, 0],
  150. scale: null,
  151. castShadow: false,
  152. receiveShadow: false,
  153. material: {
  154. color: "#ffcc44",
  155. metalness: 0.95,
  156. roughness: 0.1,
  157. emissive: "#cc9900",
  158. emissiveIntensity: 0.4,
  159. opacity: null,
  160. transparent: null,
  161. wireframe: null,
  162. },
  163. radius: 2,
  164. tube: 0.04,
  165. radialSegments: null,
  166. tubularSegments: 128,
  167. },
  168. children: [],
  169. },
  170. "ring-spin-1": {
  171. type: "Spin",
  172. props: {
  173. position: null,
  174. rotation: [0.9, 0, -0.2],
  175. scale: null,
  176. speed: -0.7,
  177. axis: "y",
  178. },
  179. children: ["ring-torus-1"],
  180. },
  181. "ring-torus-1": {
  182. type: "Torus",
  183. props: {
  184. position: null,
  185. rotation: [1.5708, 0, 0],
  186. scale: null,
  187. castShadow: false,
  188. receiveShadow: false,
  189. material: {
  190. color: "#cc8833",
  191. metalness: 0.95,
  192. roughness: 0.1,
  193. emissive: "#aa6622",
  194. emissiveIntensity: 0.3,
  195. opacity: null,
  196. transparent: null,
  197. wireframe: null,
  198. },
  199. radius: 3.2,
  200. tube: 0.035,
  201. radialSegments: null,
  202. tubularSegments: 128,
  203. },
  204. children: [],
  205. },
  206. "ring-spin-2": {
  207. type: "Spin",
  208. props: {
  209. position: null,
  210. rotation: [-0.4, 0, 0.5],
  211. scale: null,
  212. speed: 0.4,
  213. axis: "y",
  214. },
  215. children: ["ring-torus-2"],
  216. },
  217. "ring-torus-2": {
  218. type: "Torus",
  219. props: {
  220. position: null,
  221. rotation: [1.5708, 0, 0],
  222. scale: null,
  223. castShadow: false,
  224. receiveShadow: false,
  225. material: {
  226. color: "#bb9944",
  227. metalness: 0.95,
  228. roughness: 0.1,
  229. emissive: "#886622",
  230. emissiveIntensity: 0.25,
  231. opacity: null,
  232. transparent: null,
  233. wireframe: null,
  234. },
  235. radius: 4.5,
  236. tube: 0.03,
  237. radialSegments: null,
  238. tubularSegments: 128,
  239. },
  240. children: [],
  241. },
  242. "ring-spin-3": {
  243. type: "Spin",
  244. props: {
  245. position: null,
  246. rotation: [0.1, 0, -0.1],
  247. scale: null,
  248. speed: -0.2,
  249. axis: "y",
  250. },
  251. children: ["ring-torus-3"],
  252. },
  253. "ring-torus-3": {
  254. type: "Torus",
  255. props: {
  256. position: null,
  257. rotation: [1.5708, 0, 0],
  258. scale: null,
  259. castShadow: false,
  260. receiveShadow: false,
  261. material: {
  262. color: "#997744",
  263. metalness: 0.95,
  264. roughness: 0.1,
  265. emissive: "#664422",
  266. emissiveIntensity: 0.15,
  267. opacity: null,
  268. transparent: null,
  269. wireframe: null,
  270. },
  271. radius: 6,
  272. tube: 0.025,
  273. radialSegments: null,
  274. tubularSegments: 128,
  275. },
  276. children: [],
  277. },
  278. "planet-orbit-0": {
  279. type: "Orbit",
  280. props: {
  281. position: [0, 0, 0],
  282. rotation: null,
  283. scale: null,
  284. speed: 0.6,
  285. radius: 2.5,
  286. tilt: 0.3,
  287. },
  288. children: ["planet-spin-0"],
  289. },
  290. "planet-spin-0": {
  291. type: "Spin",
  292. props: {
  293. position: null,
  294. rotation: null,
  295. scale: null,
  296. speed: 3,
  297. axis: "y",
  298. },
  299. children: ["planet-sphere-0"],
  300. },
  301. "planet-sphere-0": {
  302. type: "Sphere",
  303. props: {
  304. position: null,
  305. rotation: null,
  306. scale: null,
  307. castShadow: false,
  308. receiveShadow: false,
  309. material: {
  310. color: "#ffffff",
  311. metalness: 1,
  312. roughness: 0.02,
  313. emissive: "#ffffff",
  314. emissiveIntensity: 0.2,
  315. opacity: null,
  316. transparent: null,
  317. wireframe: null,
  318. },
  319. radius: 0.2,
  320. widthSegments: 32,
  321. heightSegments: 16,
  322. },
  323. children: [],
  324. },
  325. "planet-orbit-1": {
  326. type: "Orbit",
  327. props: {
  328. position: [0, 0, 0],
  329. rotation: null,
  330. scale: null,
  331. speed: -0.9,
  332. radius: 3.8,
  333. tilt: 0.8,
  334. },
  335. children: ["planet-spin-1"],
  336. },
  337. "planet-spin-1": {
  338. type: "Spin",
  339. props: {
  340. position: null,
  341. rotation: null,
  342. scale: null,
  343. speed: -2,
  344. axis: "x",
  345. },
  346. children: ["planet-sphere-1"],
  347. },
  348. "planet-sphere-1": {
  349. type: "Sphere",
  350. props: {
  351. position: null,
  352. rotation: null,
  353. scale: null,
  354. castShadow: false,
  355. receiveShadow: false,
  356. material: {
  357. color: "#ffcc88",
  358. metalness: 0.8,
  359. roughness: 0.15,
  360. emissive: "#ffcc88",
  361. emissiveIntensity: 0.2,
  362. opacity: null,
  363. transparent: null,
  364. wireframe: null,
  365. },
  366. radius: 0.15,
  367. widthSegments: 32,
  368. heightSegments: 16,
  369. },
  370. children: [],
  371. },
  372. "planet-orbit-2": {
  373. type: "Orbit",
  374. props: {
  375. position: [0, 0, 0],
  376. rotation: null,
  377. scale: null,
  378. speed: 0.35,
  379. radius: 5.2,
  380. tilt: -0.5,
  381. },
  382. children: ["planet-spin-2"],
  383. },
  384. "planet-spin-2": {
  385. type: "Spin",
  386. props: {
  387. position: null,
  388. rotation: null,
  389. scale: null,
  390. speed: 1.5,
  391. axis: "z",
  392. },
  393. children: ["planet-sphere-2"],
  394. },
  395. "planet-sphere-2": {
  396. type: "Sphere",
  397. props: {
  398. position: null,
  399. rotation: null,
  400. scale: null,
  401. castShadow: false,
  402. receiveShadow: false,
  403. material: {
  404. color: "#ccaa66",
  405. metalness: 0.9,
  406. roughness: 0.05,
  407. emissive: "#ccaa66",
  408. emissiveIntensity: 0.2,
  409. opacity: null,
  410. transparent: null,
  411. wireframe: null,
  412. },
  413. radius: 0.18,
  414. widthSegments: 32,
  415. heightSegments: 16,
  416. },
  417. children: [],
  418. },
  419. sparkles: {
  420. type: "Sparkles",
  421. props: {
  422. position: null,
  423. rotation: null,
  424. scale: [14, 10, 14],
  425. count: 150,
  426. speed: 0.15,
  427. opacity: 0.3,
  428. color: "#ffcc66",
  429. size: 1,
  430. noise: 2,
  431. },
  432. children: [],
  433. },
  434. post: {
  435. type: "EffectComposer",
  436. props: { enabled: true, multisampling: 8 },
  437. children: ["bloom", "vignette"],
  438. },
  439. bloom: {
  440. type: "Bloom",
  441. props: {
  442. intensity: 1.2,
  443. luminanceThreshold: 0.2,
  444. luminanceSmoothing: null,
  445. mipmapBlur: true,
  446. },
  447. children: [],
  448. },
  449. vignette: {
  450. type: "Vignette",
  451. props: { offset: 0.5, darkness: 0.5 },
  452. children: [],
  453. },
  454. controls: {
  455. type: "OrbitControls",
  456. props: {
  457. enableDamping: true,
  458. dampingFactor: null,
  459. enableZoom: true,
  460. enablePan: null,
  461. enableRotate: true,
  462. minDistance: 4,
  463. maxDistance: 18,
  464. minPolarAngle: 0.3,
  465. maxPolarAngle: 1.5,
  466. autoRotate: true,
  467. autoRotateSpeed: 0.3,
  468. },
  469. children: [],
  470. },
  471. },
  472. },
  473. };