← Learn · Build · 24 October 2026 · 7 min

I turned myself into a 3D character and explored the Taj Mahal

Avatar to rigged 3D character in Tripo, monuments from one line of text, and a playable world built with Opus 5.5. Every prompt, step and code snippet, plus free Tripo credits.

I took my illustrated avatar, turned it into a rigged, animated 3D character, and dropped myself into a playable Taj Mahal. You run through the gardens, jump around, and walk into glowing checkpoints. Each one pops an info bubble with a piece of history. Find all 6 and I dance in front of the Taj.

The split:

  • Tripo made the 3D: me (rigged and animated), the Taj Mahal, the great gate, a royal elephant and the cenotaphs.
  • Opus 5.5 made the world: the garden, the reflecting pool, the sky, the controls, the checkpoints, the camera.

Here's the whole workflow.

0. Get Tripo (free credits)

👉 Sign up with my link

🎁 500 bonus credits + 60% off your first month

  1. Click the link above (or the link in my bio), or
  2. Go to the official Tripo website → click your profile avatar → find the Redeem Code section → enter J0SG4G

Discount code: TRIPOCREW

⚠️ Complete both registration and purchase within 24 hours to get the offer.

1. Turn yourself into a 3D character

All of this happens inside Tripo Studio. No Blender.

  1. Start from one image of you. A selfie, a drawing or your profile picture. Mine is my illustrated avatar, which was only head and shoulders.
  2. Get a full body. Head to the Image tool and use the Character Completion template. It turns a head-and-shoulders picture into a full-body character standing in a T-pose. A T-pose matters because it makes rigging clean.
  3. Image to 3D. Drop the full-body image in and generate. You get a textured 3D model of yourself.
  4. Retopology. This cleans up the mesh so it bends nicely when animated.
  5. Auto Rig. Choose the humanoid rig. Tripo adds a skeleton to your model.
  6. Animate. Pick presets (idle, walk, run, jump, dance). For anything missing, use AI Animation and describe the move in text. That's how I got my slide.
  7. Export as GLB with the animations included.

A tip from doing this twice: the cleaner and more front-facing your full-body image is, the better the 3D model. Arms slightly away from the body helps the rig a lot.

2. Generate the monuments

In Tripo Studio: Model → Text to 3D, one prompt each.

Taj Mahal

the Taj Mahal mausoleum in Agra, complete monument on its square white marble plinth, large central onion dome with smaller chhatri domes, four tall white minarets at the corners, arched iwan facades with fine inlay detail, pristine white Makrana marble, highly detailed architectural model, isolated, no background

The great gate

Darwaza-i-Rauza, the great red sandstone gateway of the Taj Mahal complex, tall central pointed arch, white marble inlay borders, row of small white chhatri domes along the top edge, octagonal corner towers topped with domed kiosks, Mughal architecture, highly detailed, isolated, no background

Royal elephant

A Mughal royal elephant walking, decorated with an ornate red and gold embroidered cloth, golden headpiece and bells, carrying a small block of white marble on its back, stylized realistic, highly detailed, isolated, no background

Cenotaphs

Two white marble cenotaphs side by side inside the Taj Mahal, rectangular tomb chests on stepped bases covered in colorful pietra dura flower inlay and calligraphy, the left one slightly larger, surrounded by a low carved octagonal marble lattice jali screen, highly detailed, isolated, no background

Tip: end every prompt with "isolated, no background" so you get just the object.

3. Shrink everything for the web

Raw models were about 75 MB each. On the web you want 1 to 2 MB:

npm i -g @gltf-transform/cli

gltf-transform optimize "taj mahal.glb" public/models/taj/taj.glb \
  --compress meshopt --texture-compress webp --texture-size 2048 \
  --simplify-ratio 0.06 --simplify-error 0.002

Don't compress your character's GLB too hard. Simplifying a rigged mesh can break the skinning, so for me.glb just resize the textures.

4. The prompt for Opus 5.5

Build a small third-person exploration game in the browser: "Explore the Taj Mahal as me".
Stack: Vite + three.js. Load GLBs with GLTFLoader + MeshoptDecoder and normalise each one to a target size.

Models in public/models/: me/me.glb (my rigged Tripo character with idle, walk, run, jump, dance and cast_a_spell clips), taj/taj.glb, taj/gate.glb, taj/elephant.glb, taj/cenotaph.glb.

World (build in code): a Mughal garden with a long reflecting pool (use three.js Reflector), sandstone walkways, rows of cypress trees, flower beds, red sandstone walls, the gate at one end and the Taj on a terrace at the other. Sky gradient that moves from dawn pink to sunset gold as the player makes progress.

Controls: WASD/arrows move relative to the camera, Shift walks, Space jumps, drag to orbit the camera. On phones: a virtual joystick on the left half of the screen and a jump button.
Animation: idle / walk / run by speed, jump clip in the air (trim it to the airborne part), dance when the tour is complete.
Simple collisions: the pool, the gate, the Taj, the trees and the artifacts.

6 checkpoints: glowing gold rings with a light beam and a floating number. Walking into one opens a speech-bubble card anchored above it in 3D (title, 2 sentences of history, one fun fact) and marks it done (ring turns teal, HUD shows "3 / 6 discovered"). Elephant, cenotaph and inlay checkpoints make me play the cast_a_spell clip while that model grows in with sparkles.
Checkpoints: the Great Gate, the Taj Mahal, the marble (1,000 elephants legend), pietra dura inlay, the cenotaphs (the one asymmetrical detail), the leaning minarets.
Finale at 6/6: "Tour complete" card and I dance.

Add ?autoplay to walk the whole route hands-free for screen recording, and ?opus to swap every model for grey primitives (a before/after shot).

5. Code snippets that make it work

Camera-relative movement

W should always mean "away from the camera", wherever the camera is:

const fwx = -Math.sin(camYaw), fwz = -Math.cos(camYaw); // forward
const rtx = Math.cos(camYaw), rtz = -Math.sin(camYaw);  // right
const mx = fwx * forward + rtx * strafe;
const mz = fwz * forward + rtz * strafe;

if (Math.hypot(mx, mz) > 0.05) {
  const want = Math.atan2(mx, mz);           // face where you're going
  let d = want - player.face;
  d = Math.atan2(Math.sin(d), Math.cos(d));  // shortest turn
  player.face += d * (1 - Math.exp(-dt * 12));
}

Pick the animation from speed

if (player.inAir) play('jump');
else if (speed > 3.4) play('run');
else if (speed > 0.35) play('walk');
else if (tourComplete) play('dance');
else play('idle');

play() just crossfades between AnimationMixer actions with fadeIn and fadeOut so nothing pops.

Trim the AI jump to the airborne part

AI animations often have a long wind-up. This samples the hips' height and keeps only the part where you're actually in the air:

function cutJump(clip, model) {
  const hips = model.getObjectByName('mixamorigHips');
  const mixer = new THREE.AnimationMixer(model), a = mixer.clipAction(clip); a.play();
  const ys = [], p = new THREE.Vector3(), N = 120;
  for (let i = 0; i <= N; i++) { mixer.setTime((i / N) * clip.duration); model.updateMatrixWorld(true); ys.push(hips.getWorldPosition(p).y); }
  const mn = Math.min(...ys), mx = Math.max(...ys);
  const air = ys.map((y) => y > mn + (mx - mn) * 0.45);
  const s = air.indexOf(true), e = air.lastIndexOf(true);
  return THREE.AnimationUtils.subclip(clip, 'jump', Math.floor((s / N) * clip.duration * 30), Math.ceil((e / N) * clip.duration * 30), 30);
}

Checkpoints + info bubble anchored in 3D

for (const c of CHECKPOINTS) {
  const inside = Math.hypot(player.x - c.x, player.z - c.z) < 2.3;
  if (inside && !c.visited) {
    c.visited = true;
    burst(c.position);                         // sparkles
    if (c.art) reveal(c.art);                  // the Tripo model grows in
    play('cast');                              // "summon" gesture
  }
  if (inside) openBubble(c);
}

// every frame: put the HTML bubble above its 3D anchor
const v = new THREE.Vector3(...bubble.anchor).project(camera);
bubbleEl.style.transform = `translate(${(v.x * 0.5 + 0.5) * innerWidth - w / 2}px, ${(-v.y * 0.5 + 0.5) * innerHeight - h - 18}px)`;

Reflecting pool

import { Reflector } from 'three/examples/jsm/objects/Reflector.js';
const water = new Reflector(new THREE.PlaneGeometry(3.2, 88), { clipBias: 0.003, textureWidth: 1024, textureHeight: 1024, color: 0x9aa6a8 });
water.rotation.x = -Math.PI / 2;
scene.add(water);

6. Code vs Tripo

I also had Opus build the Taj Mahal purely in code: an extruded chamfered hall, a lathe onion dome, cylinder minarets and pointed arches. It's clearly the Taj, but it's flat and plain. Flip to the Tripo model and you get the carved arches, the texture of the marble and the detail of the minarets. Opus builds the experience; Tripo builds the things in it.

7. Make your own

  1. Turn yourself into a character in Tripo (step 1).
  2. Pick a place: your city, a monument, your campus, a fantasy world.
  3. Generate 3 to 5 landmarks with Text to 3D.
  4. Paste the prompt from step 4 into Opus 5.5 and swap in your place and your facts.
  5. Record it and tag me @avi_vashishta29.

Free Tripo credits: my invite link · code J0SG4G · discount TRIPOCREW · 500 bonus credits + 60% off your first month (register and purchase within 24 hours).