Adaptive Bucket Splitting: il rendering con V-Ray non sarà più lo stesso

Link Rapidi

Dopo questo hotfix il rendering con V-Ray non sarà più lo stesso!

Con l’ultimo aggiornamento hotfix di V-Ray per 3ds Max il bucket rendering sarà molto più veloce delle precedenti release. Grazie al nuovo algoritmo intelligente, Chaos ha risolto uno storico “problema” di calcolo, per la gioia di tutti i 3D artist!

Già da tempi immemori, il bucket rendering di V-Ray offre tantissimi vantaggi per noi renderisti: questo sistema di calcolo ci permette di ripartire le risorse di calcolo in maniera più mirata, offre un minor carico di memoria RAM e, non per minor importanza, produce risultati di altissima qualità al primo colpo.

Però il rendering in bucket porta con sé un problema ben noto: la cosiddetta “Sindrome dell’ultimo Bucket”!

Riprendendo la splendida analisi di Emanuele Lecchi nel suo articolo sul sito Chaos Group, oggi voglio parlarti della grandissima rivoluzione rilasciata per tutti gli utenti di V-Ray per 3ds Max: l’Adaptive Bucket Splitting.

Facciamo un quadro generale

Quando ci si trova davanti ad un render complesso o di grandi dimensioni, la scelta di eseguirne il calcolo attraverso il bucket rendering può risultare una soluzione non proprio azzeccata.

Ti spiego brevemente il motivo.

Distribuire la mole di lavoro sui singoli Thread del processore, quando si ha a che fare con una mole di calcolo non indifferente, ci porta dritti a scontrarci con un problema teorico ricorrente nel mondo della computer grafica moderna, e non solo in termini di rendering.

Ogni Bucket (per chi non lo sapesse, parliamo di ogni singolo quadratino colorato rappresentato nell’immagine di copertina) è un “nodo” di calcolo attribuito ad un rispettivo Thread della CPU.

Avvicinandoci alla chiusura dell’ elaborazione dell’immagine, ci troviamo di fronte ad una fase critica in cui i bucket in elaborazione risulteranno essere minori dei Thread disponibili della CPU.

Questo comporta l’aumento proporzionale di Thread inattivi man mano che ci avviciniamo all’ultimazione della scena, e quindi ci troveremo ad avere il processore che risulterà essere man mano più “scarico di lavoro”, rallentando l’elaborazione invece che accelerarla.

La “sindrome” che ti ho nominato all’inizio deriva appunto da questa procedura: un’immagine elaborata in Bucket dovrà per sua definizione chiudersi con un singolo bucket al lavoro e, di conseguenza, con un singolo thread che calcola arditamente mentre tutti gli altri sono a braccia conserte che lo attendono.

In moltissimi casi è possibile trovarsi col singolo bucket che, da solo, richiede un tempo di calcolo pari al resto dell’immagine.

Purtroppo questo è uno scenario molto comune dato che solitamente un’immagine non è mai omogena nel suo sviluppo planare: un cielo limpido infatti sarà calcolato in modo rapido rispetto ad un prato applicato in scattering sul terreno.

L’unica certezza in ogni singolo render è che ci sarà un’ area più ostinata delle altre causata o dalla richiesta di elaborazione per raggiungere la soglia di rumore richiesta, oppure da un piccolo colpo di luce speculare.

Negli anni sono state sviluppate diverse soluzioni a questo fastidioso problema. A partire dalla cura nella configurazione della scena o della sua gestione, fino alla gestione del codice – ad esempio riducendo le dimensioni dei bucket man mano che ci si avvicina alla fineil ventaglio di soluzioni ideate non ha mai portato ad una vera risoluzione del problema.

Nessuno di questi approcci infatti ha potuto eliminare definitivamente la perdita di efficienza del rendering in Bucket in particolare quando ci si avvicina alla fine del rendering stesso, riportando tutte inevitabilmente al fastidioso Bucket bloccato nel tempo e nello spazio.

I vari suggerimenti

Sollevato il problema, bisognava in qualsiasi modo trovare la soluzione. Ed in questo scenario la community di Chaos Group si è rivelata davvero di grande aiuto. Sia utenti che programmatori hanno lottato fianco a fianco in questa battaglia nel corso degli anni.

E di possibili strategie di risoluzione ne sono arrivate davvero tante.

Rimpicciolire i Bucket

Per elaborare una determinata area, ci si può approcciare in due diversi modi:

  1. un grande bucket in grado di coprirla interamente (non risolverebbe il problema dei tempi),
  2. oppure permettere all’algoritmo di elaborare aree minori, quindi impiegando molti più thread in aree via via minori.

Questo approccio da un lato aiuterebbe i moderni processori multi-core a sprigionare tutta la loro potenza di calcolo, ma dall’altro lato finirebbe per costare di più in altri termini.

Il bordo di due bucket contigui viene infatti calcolato due volte, prima da un thread e poi dall’altro.

Giocoforza avere un numero maggiore di bucket, benché siano di dimensioni ridotte, comporterebbe più bordi e quindi più elementi da calcolare. Quindi ciò non porterebbe nessun vantaggio sull’ultimo bucket bloccato.

Mouse follow

Altra soluzione ipotizzata era quella di creare un sistema di rendering che permettesse al bucket di seguire i movimenti del mouse.

Ciò però richiede inevitabilmente l’esperienza dell’utente ed una conoscenza iniziale su quale sia l’area più complica da calcolare.

Oltretutto questa proposta non è affatto sostenibile con scene animate o con nuove immagini dove il contenuto o la preview non è ancora nota.

Threshold splitting

Un altro modo per ottimizzare il carico di lavoro è stato quello di andare ad ottimizzare il dimensionamento dei bucket man mano che ci si avvicina all’ultimazione della scena: questo comporta la divisione dei bucket iniziali in altri sempre più piccoli via via che ne rimangono meno, in modo da completare l’immagine ottimizzando l’utilizzo dei thread.

Questo aiuta a mantenere alta l’occupazione del core, ma purtroppo non risulta adeguata con immagini molto disomogenee dove può capitare che un grande bucket iniziale può rimanere bloccato per più tempo rispetto ai bucket più piccoli che vanno per la loro strada verso il completamento.

Impiegare la Light Cache

Per sua definizione il rendering mira a trovare una soluzione grafica ad un problema sconosciuto, per questo motivo qualcuno ha proposto di affrontare la questione con un pre-calcolo della Light Cache in modo da arrivare all’elaborazione con almeno un dato grezzo in mano.

Sfortunatamente è stato dimostrato che l’impiego dei prepass definiti dalla Light Cache per capire in anticipo quali aree dell’immagine richiedano più tempo non è proprio il massimo dell’ottimizzazione: il campionamento infatti non è sufficientemente alto e perciò non si otterrebbe una rappresentazione dell’immagine abbastanza fedele per poter fare delle scelte in anticipo.

Riavvio forzato dei bucket bloccati

La sindrome del bucket bloccato è diventata talmente grave che è stata presa in considerazione l’idea di arrestare e riavviare i bucket che risultano bloccati.

Anche questa soluzione purtroppo non si è rivelata ideale, poiché i campioni già coinvolti verrebbero annullati in qualche punto arbitrario e non ben definito, col rischio di attivare il processo in un punto sbagliato della scena e col potenziale allungamento dei tempi di rendering, specialmente con un bucket bloccato nell’ elaborazione di una porzione finale della scena.

Questa possibile soluzione è stata valutata in diverse varianti, ma sfortunatamente nessuna di loro ha portato alla risoluzione del problema risultando non ottimale in una o più situazioni.

Utilizzo di fotogrammi precedenti

Soprattutto con le animazioni, la soluzione messa in campo poteva essere quella di impiegare i singoli frame precedenti per scoprire o anticipare quali fossero le aree che avrebbero richiesto più tempo di elaborazione.

Sfortunatamente, anche in questo caso, la soluzione non era dietro l’angolo e non c’è stata alcuna evidenza palese di efficacia. Infatti in molte produzioni non è possibile garantire continuità tra i fotogrammi: nuove aree difficili da renderizzare potrebbero entrare nel campo visivo in un fotogramma e scomparire nel seguente, perciò potrebbe diventare impossibile -se non inutile- utilizzare i frame precedenti come base per il precalcolo.

La soluzione

Per arrivare quindi ad una soluzione funzionale ed effettivamente efficace, Radoslav del team di Ricerca & Sviluppo di Chaos ha fatto un lavoro a ritroso, ripercorrendo i passi di V-Ray nelle sue fasi di sviluppo.

Così facendo è stato possibile realizzare un’intelligenza artificiale che permette quindi di ottenere uno Splitting Adattivo del Bucket.

Ma cosa vuol dire a tutti gli effetti?

Quando un thread rimane scarico di lavoro, viene forzato ad aiutare gli altri thread ancora indaffarati nell’elaborazione.

Il bucket verrà quindi diviso, e tutto il campionamento completato dal thread originale non verrà annullato, ma trasferito e condiviso col nuovo thread di supporto, in modo che nessuna fase di campionatura venga persa.

Così facendo, il thread di supporto, ha un punto di partenza ben chiaro da cui far partire la convergenza verso il risultato finale.

Questa divisione non è però svolta in maniera casuale: infatti la nuova intelligenza artificiale si attiverà in base a quanti thread inattivi sono disponibili e, ovviamente, alla porzione di immagine che è rimasta da renderizzare.

E la vera svolta sai qual è?

È che ora è possibile splittare il singolo bucket fino alla dimensione di un pixel agevolando il tutto, poiché anche l’area all’interno di un singolo bucket è affetta da discontinuità e quindi ci saranno pixel che richiedono meno potenza di elaborazione e altre che ne richiedono di più.

I veri benefici del bucket splitting

Poiché nell’intero processo i dati non vengono mai buttati via, viene sempre mantenuta una base solida di informazioni dal quale far partire la divisione del singolo bucket.

Ma non solo: poiché la divisione avviene solo in presenza di thread inattivi, l’accelerazione dell’elaborazione avviene esattamente nel momento ideale, ossia nel momento in cui un thread è più in affanno rispetto ad altri scarichi.

Questa soluzione inoltre si è rivelata versatile in più situazioni (compreso l’animazione) poiché la suddivisione del bucket avviene senza l’impiego di un’immagine/frame o precalcolo immagazzinato nella cache, e quindi senza la necessità di avere un’immagine grezza renderizzata in partenza: questa tecnica si rivela ottimale nella condivisione del carico di lavoro indipendentemente dal contenuto della scena, o dal tempo già speso per il rendering.

Il concetto alla base è relativamente semplice: finché ci saranno thread liberi e pixel da calcolare, ogni parte del processore verrà messa al lavoro.

Così facendo si ottiene una generale e diffusa diminuzione dei tempi di rendering, che ovviamente rimarranno dipendenti dalla complessità della scena e dal numero di core (e thread) disponibili sulla tua CPU.

I limiti riscontrati

Questa tecnica innovativa mantiene comunque un limite intrinseco: c’è sempre correlazione univoca tra bucket ed il rispettivo thread.

Tradotto in parole semplici se, per pura casualità, la parte che richiede più tempo di elaborazione è un singolo pixel, rimarrà comunque un singolo thread a lavorare per l’ultimazione dell’immagine.

Il bucket bloccato però avrà dimensione di un singolo pixel e non di centinaia o migliaia, ma comunque non verrà annullata la potenziale richiesta di ulteriore tempo di calcolo.

Questo approccio specifico è attualmente applicabile solo in rendering locale e non può essere ad ora attuato su sistemi di rendering distribuito e/o con render farm, poiché ciò richiederebbe un approccio leggermente diverso e che sia in grado di assicurare un traffico di rete basso.

Nel caso te lo stessi chiedendo, la ricerca è attualmente in corso per la risoluzione di questi problemi residui.

Cambiamenti nei flussi di lavoro

La soluzione dell’Adaptive Bucket Splitting è completamente user friendly e non richiede assolutamente alcun sforzo lato utente, soprattutto in termini di cambiamento del proprio workflow o nei settaggi delle scene.

Oltretutto è completamente compatibile con il mouse follow o con il region rendering.

Nel caso di Region Rendering, non c’è bisogno di cambiare le dimensioni dei bucket per farli rientrare all’interno di una singola regione, mentre il mouse follow dividerà in modo del tutto automatico qualsiasi bucket rimanente, annullando totalmente la necessità di interazione dell’utente finale.

Oltretutto questa tecnica permetterà l’utilizzo di bucket più grandi e li manterrà più a lungo rispetto al precedente metodo di divisione.

Bisogna fare però attenzione a non scegliere una dimensione iniziale dei bucket troppo grande, poiché questo potrebbe causare altri inconvenienti. In sostanza, quindi, non c’è bisogno di scegliere piccole dimensioni dei bucket per completare l’immagine in modo più rapido ed efficiente: il nuovo algoritmo si autoregolerà in autonomia in base alle dimensioni predefinite (o più grandi).

Come da corollario, i ben noti problemi di campionamento della Profondità di Campo (DOF) o del Motion Blur saranno notevolmente migliorati (benchè i bucket piccoli abbiano comunque una maggior probabilità di perdere campioni).

Come ottenerlo?

Questo nuovo algoritmo sarà rilasciato a partire dall’hotfix 3 dell’update 2 di V-Ray 5 per 3ds Max.

In ogni caso questo algoritmo verrà esteso a tutte le altre integrazioni DCC.

Se non disponi di una licenza di V-Ray 5 puoi ottenerla rapidamente accedendo al nostro shop cliccando qui oppure puoi contattarci in qualsiasi momento per avere maggiori informazioni.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Su questo articolo

Con l' hotfix di V-Ray per 3ds Max il bucket rendering sarà migliore delle precedenti release grazie all' algoritmo intelligente di Chaos!

Altri articoli interessanti