Un modello animato GLB o GLTF memorizza geometria e dati di animazione anziché una cartella di immagini pronte. Per creare miniature o una sequenza di fotogrammi, è necessario valutare l’animazione del modello in momenti specifici e renderizzare ogni scena risultante in un’immagine. Questo tutorial spiega come renderizzare i fotogrammi di animazione GLB in Python usando Aspose.3D for Python via .NET. Caricherai un modello animato, selezionerai una clip, campionerai la sua timeline e salverai ogni fotogramma come immagine PNG numerata. Puoi utilizzare le immagini risultanti come anteprime del modello o come input per un flusso di lavoro separato di sequenza di immagini.

Install Aspose.3D for Python via .NET

Installa il pacchetto usando pip:

pip install aspose-3d

Avrai anche bisogno di:

  • Un file .glb animato o un file .gltf con i relativi buffer e texture.
  • Un ambiente di rendering compatibile con i requisiti hardware di Aspose.3D. Vedi i requisiti di sistema.
  • Una posizione della fotocamera che mantenga l’oggetto animato in vista lungo la timeline campionata.

Renderizza una clip di animazione come fotogrammi PNG

Salva il seguente codice come render_glb_animation_frames.py ed eseguilo dalla cartella contenente animated_model.glb.

import hashlib
import math
from pathlib import Path

import aspose.threed as a3d
from aspose.pydrawing import Color, Size
from aspose.pydrawing.imaging import ImageFormat
from aspose.threed.entities import Camera
from aspose.threed.utilities import Vector3

INPUT_FILE = Path("animated_model.glb")
OUTPUT_DIR = Path("frames")
FRAMES_PER_SECOND = 5
IMAGE_WIDTH = 800
IMAGE_HEIGHT = 600

def main():
    if not INPUT_FILE.is_file():
        raise FileNotFoundError(f"Input model not found: {INPUT_FILE}")

scene = a3d.Scene.from_file(str(INPUT_FILE))
    clips = list(scene.animation_clips)
    if not clips:
        raise RuntimeError("The input model has no animation clips.")

clip = clips[0]
    duration = float(clip.stop - clip.start)
    if duration <= 0:
        raise ValueError("The selected animation has no positive time range.")

# Use the same camera position for every frame.
    camera = Camera()
    camera_node = scene.root_node.create_child_node("PreviewCamera", camera)
    camera_node.transform.translation = Vector3(3, 2, 6)
    camera.look_at = Vector3.ORIGIN

options = a3d.ImageRenderOptions()
    options.background_color = Color.white
    options.asset_directories.append(str(INPUT_FILE.resolve().parent))

OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    frame_count = max(1, math.ceil(duration * FRAMES_PER_SECOND))
    hashes = set()

for frame_index in range(frame_count):
        timestamp = float(clip.start) + frame_index / FRAMES_PER_SECOND
        clip.apply_to(timestamp)

frame_path = OUTPUT_DIR / f"frame_{frame_index:04d}.png"
        scene.render(
            camera,
            str(frame_path),
            Size(IMAGE_WIDTH, IMAGE_HEIGHT),
            ImageFormat.png,
            options,
        )

if not frame_path.is_file() or frame_path.stat().st_size == 0:
            raise RuntimeError(f"Rendering did not create a usable PNG: {frame_path}")

hashes.add(hashlib.sha256(frame_path.read_bytes()).digest())
        print(f"Frame {frame_index + 1}/{frame_count}: {frame_path} at {timestamp:.3f}s")

if frame_count > 1 and len(hashes) == 1:
        print("WARNING: All PNG files are byte-identical. Check animation state and camera view.")

print(f"Created {frame_count} PNG file(s) in {OUTPUT_DIR}/")

if __name__ == "__main__":
    main()

Esegui con:

python render_glb_animation_frames.py

Output previsto: una directory frames contenente immagini come frame_0000.png, frame_0001.png e frame_0002.png. Quando il renderer cattura correttamente gli stati di animazione applicati, le immagini mostrano il modello nei punti successivi della sua animazione.

Come funziona il codice di rendering dei frame

Carica la scena e seleziona una clip di animazione

Il metodo Scene.from_file() apre il modello, mentre scene.animation_clips fornisce l’accesso ai clip di animazione che contiene. L’esempio utilizza il primo clip e legge le sue proprietà start e stop per determinare l’intervallo di tempo. Un modello senza clip di animazione non può generare una sequenza animata con questo metodo.

Per ulteriori dettagli sulla selezione dei clip e le trasformazioni dei nodi, vedere Load and Evaluate GLB/GLTF Animations in Python.

Campiona la timeline a intervalli regolari

Lo script utilizza cinque campioni al secondo. Se la clip dura due secondi, richiede dieci fotogrammi con timestamp da 0.0 a 1.8 secondi quando la clip inizia a zero. Escludere il punto finale esatto evita di generare un fotogramma finale ridondante per le animazioni che tornano alla posa iniziale.

Il metodo clip.apply_to(timestamp) applica la clip di animazione selezionata a ciascun timestamp. A differenza della valutazione di una singola sequenza di fotogrammi chiave, questo passaggio è destinato ad aggiornare la scena animata prima che l’immagine venga renderizzata.

Renderizza la scena aggiornata da una camera

L’esempio aggiunge una camera in una posizione fissa e chiama scene.render() per ogni frame. Imposta inoltre una dimensione immagine di 800 × 600 pixel e un formato di output PNG. Mantenere la camera fissa rende più facile ispezionare le differenze frame‑per‑frame.

La Guida di rendering della scena di Aspose.3D mostra come salvare una vista 3D come immagine. Per le sequenze di animazione, verifica che ogni immagine rifletta il timestamp previsto. Se i fotogrammi successivi mostrano la stessa posa, controlla se il percorso di rendering sta utilizzando lo stato animato corrente.

Denomina ogni fotogramma PNG in modo coerente

Il modello frame_0000.png mantiene le immagini in ordine quando vengono ordinate per nome file. È adatto per generare miniature di anteprima o per passare l’output a un flusso di lavoro separato di sequenza di immagini o video. Lo script non crea un video né una GIF animata.

Lo script confronta anche gli hash dei file per avvisare quando tutti i file di output sono identici a livello di byte. Hash diversi non dimostrano di per sé che l’animazione sia stata renderizzata correttamente; ispeziona i fotogrammi rappresentativi fianco a fianco.

Ottieni una licenza temporanea gratuita

Puoi richiedere una licenza temporanea gratuita di 30 giorni per rendere i fotogrammi di animazione GLB e GLTF utilizzando Aspose.3D for Python via .NET senza limitazioni di valutazione. Per applicare la licenza nella tua applicazione Python, segui la guida di licenza di Aspose.3D.

Risorse di apprendimento gratuite

Esplora le seguenti risorse per saperne di più su come caricare modelli 3D animati, lavorare con clip di animazione e renderizzare scene 3D utilizzando Aspose.3D for Python via .NET:

Conclusione

Puoi generare immagini dei fotogrammi campionando una timeline di animazione e renderizzando la scena a ciascun timestamp selezionato. Usa i PNG numerati per creare miniature, confrontare pose o preparare una sequenza di immagini per un altro strumento. Se hai bisogno di valori numerici dell’animazione anziché di immagini, consulta il tutorial di valutazione dei fotogrammi chiave. Per problemi di rendering, visita il forum di supporto Aspose.3D.