Plans 3D
Three.js (couche en direct)
- Utilisez
threeLayer(el, { update(t), background, fov })depuis/engines/three.js. Ajoutez une carte d'import pourthree(voirexamples/engines-demo/index.html). update(t)définit chaque transformation depuist. Mouvements de caméra : keyframe avec un tween GSAP sur un objet simple (tl.to(cam, { x: 4, z: 8, duration: 2 }, 3)) et copiez-le danscamera.positiondansupdate.- Modèles :
GLTFLoaderdepuisthree/addons/loaders/GLTFLoader.js(ajoutez"three/addons/": "/core/node_modules/three/examples/jsm/"dans la carte d'import). Enveloppez le chargement avecStudio.wait(...). Placez les fichiers de modèle dansassets/models/de la marque ou danscomposition/de la production. - Le look (
looks/README.md) détermine le style de rendu ; le même modèle peut prendre n'importe lequel de ces chemins :- Cartoon (
looks/toon-3d) :toon(color, { steps })+outline(mesh, { thickness }). Lumière dure : uneDirectionalLight+ uneAmbientLightfaible. - Réaliste (
looks/photoreal) :await realistic(renderer, scene)(enveloppez dansStudio.wait: mappage tonal ACES, un environnement de studio pour les réflexions, ombres douces) +pbr(color, { metalness, roughness, clearcoat }). Une lumière clé aveccastShadow, une lumière de bordure froide par derrière, un solShadowMaterialsur un dégradé CSS. Gardez la caméra au-dessus des angles rasants (les faces brillantes deviennent blanches), déplacez-vous lentement, effectuez le rendu final avecStudio.setup({ motionBlur: true }). - Néon (
looks/neon-noir) :emissive(color, intensity)+threeLayer(el, { post: bloom({ strength, threshold }) }),scene.fog. Gardezthreshold≥ 0.2 et emissive ≤ 2, sinon tout devient blanc à cause du bloom.
- Cartoon (
- Clips GLB animés : créez un
AnimationMixer, puis dansupdateappelezmixer.setTime(t - start). N'utilisez jamaismixer.update(delta). - Balises HTML qui suivent des points 3D : dans
update(t), appelezcamera.updateMatrixWorld()et leupdateMatrixWorld()du parent avantvector.applyMatrix4(obj.matrixWorld).project(camera). Three.js ne les rafraîchit que à l'intérieur derender(), donc sans cela une balise suit l'image précédente. Exemple :productions/bike-logger/REEL-002-engines. - Maillages CAO sous forme de JSON (sommets + indices) :
toNonIndexed()+computeVertexNormals()donne des facettes plates nettes. Rendez avecthreeLayer(..., { pixelRatio: 2 })pour des bords suréchantillonnés. - Physique : pré-calculez-la (simulez à pas fixe de 1/120 s dans un tableau avant la première image) et consultez-la par
t. - Personnage parlant : chargez
/engines/lipsync.jset les.visemes.jsde la ligne (depuisscripts/lipsync.sh) avec des balises<script>classiques, puis dansupdate(t):LipSync.paramsAt(cues, t, "mouth", { offset })→{ open, wide, round }(0…1) sur des cibles de morph (mesh.morphTargetInfluences) ou l'échelle d'un maillage de bouche. Voirengines/README.md, Lip sync.
Blender (plateau)
- Un script de scène définit
build(ctx); copiezengines/blender/example_scene.py.ctxdonnetoon(rgb),key(obj, "location", t, value),size,fps,duration,frames,scene. - Rendu :
engines/blender/render.sh scene.py composition/plates/<name>.mp4 --size 1080x1920 --duration 4 [--engine EEVEE|CYCLES|WORKBENCH]. Ébauche à--size 540x960, final à taille réelle. - Couleur de fond : montrez-la seulement à la caméra (mix Light Path "Is Camera Ray", comme dans l'exemple), ou elle éclaire la scène et aplatit les bandes toon.
- La gestion des couleurs est réglée sur Standard pour que les couleurs hex de la marque sortent telles quelles. Pour un plateau photoréaliste, passez à
ctx["scene"].view_settings.view_transform = "AgX"dansbuild, effectuez le rendu avec--engine CYCLES, et utilisez des lumières de zone et la profondeur de champ de la caméra. - Physique et simulations : pré-calculez-les dans le script de scène avant le rendu.
- Personnage parlant :
import lipsync as Ldans le script de scène (run.pymetengines/blender/et le dossier du script lui-même dans le chemin),cues = L.load("productions/…/audio/vo.visemes.json"), puisL.key_shape_keys(head, cues, ctx, offset=VO_START)applique les clés de formeopen,wide,roundsur chaque image (names={"open": "Jaw"}pour d'autres noms). Autre chose :L.params_at(cues, t, offset=…)par image avecctx["key"]. - Dans la composition :
<video src="plates/<name>.mp4">+Studio.video(el, { start }). Les plateaux n'ont pas d'alpha ; mettez le texte et les personnages par-dessus avec des couches HTML.
Vérification
Rendez les beats clés sous forme d'images fixes et regardez-les. Pour Three.js, rendez une image deux fois et comparez les md5. Notez les temps de rendu dans le journal de production.