L'interface utilisateur n'est plus superposee a la scene : elle en fait partie. Boutons, sliders, textes vivent comme des objets 3D dans l'espace. Chaque element UI est un volume interactif. Ce paradigme est le pont entre le web et la VR/XR.
// Un bouton 3D diegetique : geometrie + interaction
function createDiegeticButton(label, position, color) {
const group = new THREE.Group();
// Corps du bouton (boite arrondie)
const body = new THREE.Mesh(
new THREE.BoxGeometry(1.2, 0.5, 0.15, 4, 4, 2),
new THREE.MeshPhongMaterial({
color: color,
emissive: color,
emissiveIntensity: 0.15,
shininess: 80
})
);
group.add(body);
// Texte (sprite dans l'espace)
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 256; canvas.height = 64;
ctx.fillStyle = '#0a0a0a';
ctx.font = 'bold 28px monospace';
ctx.textAlign = 'center';
ctx.fillText(label, 128, 42);
const tex = new THREE.CanvasTexture(canvas);
const sprite = new THREE.Sprite(
new THREE.SpriteMaterial({ map: tex, transparent: true })
);
sprite.scale.set(1, 0.25, 1);
sprite.position.z = 0.09;
group.add(sprite);
group.position.copy(position);
return group;
}
// Slider 3D : rail + curseur deplacable
function createDiegeticSlider(pos, length) {
const rail = new THREE.Mesh(
new THREE.CylinderGeometry(0.03, 0.03, length, 8),
new THREE.MeshPhongMaterial({ color: 0x444444 })
);
rail.rotation.z = Math.PI / 2;
const knob = new THREE.Mesh(
new THREE.SphereGeometry(0.12, 16, 16),
new THREE.MeshPhongMaterial({
color: 0xc8f135,
emissive: 0xc8f135,
emissiveIntensity: 0.4
})
);
// knob is draggable along rail axis
return { rail, knob };
}
Creez un element UI diegetique supplementaire : un toggle switch 3D (interrupteur a bascule). Il doit pivoter de 45 degres au clic et changer de couleur. Indice : utilisez THREE.Group avec deux cylindres (rail + poignee) et une animation rotation.z interpolee.