Cosa fa effettivamente ddx (hlsl)?


17

Sono un po 'confuso. La documentazione ufficiale ( http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588(v=vs.85).aspx ) afferma che ddx (input) è la derivata parziale dell'input rispetto alla "coordinata x spazio-schermo".

Il mio calcolo va bene, ma come può dire da cosa proviene l'input? Se gli passassi una funzione, va bene, posso immaginare cosa farebbe, ma la derivata di un numero è sempre zero ...?

È solo un ridimensionamento? Ad esempio, questo verrebbe ridimensionato a un decimo della sua dimensione a questa distanza, quindi restituisce un decimo? Ma poi non ha bisogno di un input ...

Qualcuno può dare una rapida spiegazione di ciò che sta realmente accadendo?


2
ddxe ddyfai magie che non puoi fare da solo. Hanno accesso a informazioni aggiuntive dalla pipeline di rasterizzazione che non è possibile acquisire all'interno di un pixel shader. Non sono sicuro di quale formula utilizzino; Sono stato portato a credere che usano una tecnica di stima, ma non lo so per certo.
Sean Middleditch,

È profondamente strano, ma comunque. Cosa rappresenta effettivamente ddx (5)? Se dice .1, come dovrei interpretarlo? O -6?
Richard Rast,

1
ddx(5)è un po 'inutile. Usalo con un valore di input, e questo ti darà la derivata di quel valore rispetto ai pixel vicini in un blocco. Ancora una volta, non so con quale precisione calcoli i valori, ma chiedere la derivata di un non input potrebbe essere un comportamento indefinito e produrre immondizia. Vedi fgiesen.wordpress.com/2011/07/10/… per maggiori informazioni di quelle che posso fornire.
Sean Middleditch,

Non sono sicuro, ma potrebbe anche darsi che il compilatore HLSL stia effettivamente facendo una completa differenziazione simbolica dell'espressione che si passa a ddx / ddy. blogs.msdn.com/b/chuckw/archive/2011/03/08/… research.microsoft.com/pubs/146019/…
Ziriax

Che cosa fa? L' unica cosa leggermente ragionevole, ovviamente.
MickLH,

Risposte:


32

Internamente, le GPU non eseguono mai un'istanza di un pixel shader alla volta. Al massimo livello di granularità, eseguono sempre 32-64 pixel contemporaneamente utilizzando un'architettura SIMD. All'interno di questo, i pixel sono ulteriormente organizzati in quadratini 2x2, quindi ogni gruppo di 4 pixel consecutivi nel vettore SIMD corrisponde a un blocco 2x2 di pixel sullo schermo.

I derivati ​​vengono calcolati prendendo le differenze tra i pixel in un quad. Ad esempio, ddxsottrarrà i valori nei pixel sul lato sinistro del quadrato dai valori sul lato destro e ddysottrarrà i pixel inferiori da quelli superiori. Le differenze possono quindi essere restituite come derivata a tutti e quattro i pixel nel quad.

Poiché il pixel shader è in esecuzione in SIMD, è garantito che il valore corrispondente sia nello stesso registro contemporaneamente per tutti i pixel nel quad. Quindi, qualunque espressione o valore tu inserisca ddxo ddy, verrà valutata in tutti e quattro i pixel del quad, quindi verranno sottratti i valori di diversi pixel come descritto sopra.

Quindi prendere la derivata di un valore costante darà zero (come ti aspetteresti dal calcolo, giusto?) Perché è lo stesso valore costante in tutti e quattro i pixel.

Si noti inoltre che esistono derivati ​​"grossolani" e "fini", ddx_coarse/ ddy_coarsee ddx_fine/ ddy_fine. Una spiegazione della distinzione è fornita qui . Semplicemente ddx/ ddysono alias per le versioni grossolane.

A proposito, il motivo per cui esiste questa funzionalità è che le GPU internamente devono prendere le derivate delle coordinate delle trame per fare la selezione mipmap e il filtro anisotropico. Poiché l'hardware necessita comunque della funzionalità (è possibile utilizzare qualsiasi espressione arbitraria per coordinate di trama in uno shader), è stato abbastanza facile esporlo direttamente ai programmatori di shader.


+1; Ho trovato questo utile quando si applica un effetto perturbazione a una trama; i perturbati texcoords davano una certa distorsione del colore, ma usando tex2Dgrad con derivati ​​dai texcoords originali (non disturbati) si ottenne un risultato non distorto.
Maximus Minimus,

Bene, dopo qualche pensiero penso di aver capito la mia confusione. Nella mia mente, ddxfunziona come ogni altra funzione in un linguaggio di programmazione tradizionale; si valuta l'input, lo si trasforma in un float o altro, quindi si esegue la funzione esterna ( ddx). Ma questo è diverso: prende la stringa di input , la valuta in diversi punti, calcola una derivata e riporta il risultato. È giusto?
Richard Rast,

1
@RichardRast Right. Puoi pensare di ddxoperare sull'espressione che ci passi, piuttosto che sul valore .
Nathan Reed,

Ma vedi, è abbastanza strano che dovrebbe essere nella documentazione. Non riesco a pensare a nessun altro momento della mia vita di programmazione in cui sia stato così.
Richard Rast,

Nathan Reed ha affermato che le GPU usano queste funzioni per la selezione di mipmap. Puoi anche usarli per forzare la GPU a selezionare un livello mipmap desiderato o per impedire artefatti da una selezione errata del livello mip. Il processo è descritto alle pagine 163 e 164 di Shader X3.
JamesHoux,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.