Text to 3D works in two stages: a preview task turns a prompt of up to 800 characters into an untextured mesh, and a refine task paints it, optionally with PBR maps. Image to 3D does both from one picture, and Multi-Image to 3D from up to four views. The default model, Meshy 7.1 20,231 (latest since 18 September 2026), can add an Ultra geometry pass; Smart Topology (meshy-t2) builds clean, separate parts at 100 to 15,000 faces.
Results download as GLB, FBX, OBJ, USDZ or STL, and other endpoints remesh, retexture, resize, rig and animate. Assets are kept for only three days outside Enterprise plans.
<!doctype html>
<style>
body { margin: 0; padding: 8px; background: #fafaf7; font: 12px system-ui, sans-serif; color: #263238; }
canvas { display: block; max-width: 100%; }
.labels { display: flex; width: 600px; max-width: 100%; text-align: center; }
.labels div { flex: 1; }
</style>
<script type="importmap">
{ "imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.186.1/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.186.1/examples/jsm/" } }
</script>
<div class="labels"><div><b>preview</b> task: mesh only (20 credits)</div><div><b>refine</b> task: textures, PBR maps (10 credits)</div></div>
<script type="module">
import * as THREE from 'three';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
renderer.setSize(600, 280);
renderer.setScissorTest(true);
document.body.appendChild(renderer.domElement);
const pmrem = new THREE.PMREMGenerator(renderer);
const env = pmrem.fromScene(new RoomEnvironment(), 0.04).texture;
// A walnut mantel clock with a brass bezel, built from primitives (a stand-in for Meshy output)
function clockFace() {
const c = Object.assign(document.createElement('canvas'), { width: 256, height: 256 }), g = c.getContext('2d');
g.fillStyle = '#fff8e8'; g.beginPath(); g.arc(128, 128, 124, 0, 7); g.fill();
g.fillStyle = '#263238'; g.font = 'bold 26px Georgia'; g.textAlign = 'center'; g.textBaseline = 'middle';
['XII', 'III', 'VI', 'IX'].forEach((t, i) => { const a = -Math.PI / 2 + i * Math.PI / 2; g.fillText(t, 128 + Math.cos(a) * 95, 128 + Math.sin(a) * 95); });
g.lineWidth = 6; g.lineCap = 'round';
g.beginPath(); g.moveTo(128, 128); g.lineTo(128 + 50, 128 - 30); g.moveTo(128, 128); g.lineTo(128 - 10, 128 - 80); g.stroke();
const t = new THREE.CanvasTexture(c); t.colorSpace = THREE.SRGBColorSpace;
return t;
}
function makeClock(refined) {
const clock = new THREE.Group();
const gray = new THREE.MeshStandardMaterial({ color: '#b0b0b0', roughness: 0.8, flatShading: true });
const wood = refined ? new THREE.MeshStandardMaterial({ color: '#5a3522', roughness: 0.45 }) : gray;
const brass = refined ? new THREE.MeshStandardMaterial({ color: '#c9a44c', metalness: 1, roughness: 0.3 }) : gray;
const face = refined ? new THREE.MeshStandardMaterial({ map: clockFace(), roughness: 0.6 }) : gray;
const seg = refined ? 48 : 10; // the preview is coarser
const body = new THREE.Mesh(new THREE.BoxGeometry(1.2, 0.8, 0.45), wood);
const dome = new THREE.Mesh(new THREE.CylinderGeometry(0.5, 0.5, 0.45, seg, 1, false, Math.PI / 2, Math.PI), wood);
dome.rotation.x = Math.PI / 2; dome.position.y = 0.4;
const bezel = new THREE.Mesh(new THREE.TorusGeometry(0.34, 0.04, 12, seg), brass);
bezel.position.set(0, 0.35, 0.23);
const dial = new THREE.Mesh(new THREE.CircleGeometry(0.33, seg), face);
dial.position.set(0, 0.35, 0.228);
const base = new THREE.Mesh(new THREE.BoxGeometry(1.35, 0.1, 0.55), wood);
base.position.y = -0.45;
clock.add(body, dome, bezel, dial, base);
[-0.55, 0.55].forEach(x => { const foot = new THREE.Mesh(new THREE.SphereGeometry(0.06, seg / 2, 8), brass); foot.position.set(x, -0.53, 0.2); clock.add(foot); });
return clock;
}
const views = [false, true].map((refined, i) => {
const scene = new THREE.Scene();
scene.background = new THREE.Color(refined ? '#f3efe6' : '#e9edf0');
if (refined) scene.environment = env;
scene.add(new THREE.HemisphereLight('#ffffff', '#8d6e63', refined ? 0.6 : 1.5));
const sun = new THREE.DirectionalLight('#ffffff', 2); sun.position.set(2, 3, 4); scene.add(sun);
const clock = makeClock(refined);
scene.add(clock);
return { scene, clock, x: i * 300 };
});
const camera = new THREE.PerspectiveCamera(35, 300 / 280, 0.1, 20);
camera.position.set(0, 0.3, 3.6);
camera.lookAt(0, 0.05, 0);
renderer.setAnimationLoop((t) => {
for (const v of views) {
v.clock.rotation.y = Math.sin(t / 2000) * 0.7;
renderer.setViewport(v.x, 0, 300, 280); renderer.setScissor(v.x, 0, 300, 280);
renderer.render(v.scene, camera);
}
});
</script>
<p>Prompt: "An antique walnut mantel clock with a brass bezel, for a bookshop shelf". Downloads: GLB, FBX, OBJ, USDZ, STL; assets kept three days outside Enterprise plans.</p>