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.