O que o ddx (hlsl) realmente faz?


17

Estou um pouco confuso. A documentação oficial ( http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588(v=vs.85).aspx ) diz que ddx (entrada) é a derivada parcial da entrada com relação a para a "coordenada x do espaço na tela".

Meu cálculo é bom, mas como ele pode dizer de onde vem a entrada? Se eu aprovasse uma função, tudo bem, posso imaginar o que faria, mas a derivada de um número é sempre zero ...?

É apenas uma escala? Como, isso seria escalado para um décimo do seu tamanho a essa distância, então retorna um décimo? Mas então não precisa de uma entrada ...

Alguém pode dar uma explicação rápida do que realmente está acontecendo?


2
ddxe ddyfaça mágica que você não pode fazer sozinho. Eles têm acesso a informações adicionais do pipeline de rasterização que você não pode adquirir de dentro de um pixel shader. Não tenho certeza exatamente qual fórmula eles usam; Fui levado a acreditar que eles usam uma técnica de estimativa, mas não sei ao certo.
— Sean Middleditch

Isso é profundamente estranho, mas ainda assim. O que ddx (5) realmente representa? Se diz .1, como devo interpretar isso? Ou -6?
— Richard Rast

1
ddx(5)é meio inútil. Use-o com um valor de entrada, e isso fornecerá a derivada desse valor em relação aos pixels vizinhos em um bloco. Novamente, eu não sei exatamente como ele calcula valores, mas solicitar a derivada de uma não entrada pode muito bem ser apenas um comportamento indefinido e produzir lixo. Veja fgiesen.wordpress.com/2011/07/10/… para obter mais informações do que eu posso fornecer.
— Sean Middleditch

Não tenho certeza, mas pode ser que o compilador HLSL esteja realmente fazendo diferenciação simbólica completa da expressão que você passa para o ddx / ddy. blogs.msdn.com/b/chuckw/archive/2011/03/08/… research.microsoft.com/pubs/146019/…
— Ziriax em

O que isso faz? A ÚNICA coisa ligeiramente razoável, obviamente.
— MickLH

Respostas:


32

Internamente, as GPUs nunca executam uma instância de um pixel shader por vez. No nível mais fino de granularidade, eles estão sempre executando de 32 a 64 pixels ao mesmo tempo, usando uma arquitetura SIMD. Dentro disso, os pixels são ainda organizados em quads 2x2, de modo que cada grupo de 4 pixels consecutivos no vetor SIMD corresponde a um bloco 2x2 de pixels na tela.

As derivadas são calculadas tomando-se diferenças entre os pixels em um quad. Por exemplo, ddxsubtrai os valores nos pixels no lado esquerdo do quad dos valores no lado direito e ddysubtrai os pixels inferiores dos superiores. As diferenças podem então ser retornadas como derivada para todos os quatro pixels no quad.

Como o sombreador de pixels está sendo executado no SIMD, é garantido que o valor correspondente esteja no mesmo registro ao mesmo tempo para todos os pixels no quad. Portanto, seja qual for a expressão ou o valor que você colocar ddxou ddyserá avaliado nos quatro pixels do quadrilátero, os valores de pixels diferentes serão subtraídos conforme descrito acima.

Portanto, tirar a derivada de um valor constante dará zero (como seria de esperar do cálculo, certo?), Porque é o mesmo valor constante em todos os quatro pixels.

Observe também que existem derivadas "grossas" e "finas", ddx_coarse/ ddy_coarsee ddx_fine/ ddy_fine. Uma explicação da distinção é dada aqui . Simplesmente ddx/ ddysão aliases para as versões grosseiras.

BTW, o motivo dessa funcionalidade existir é que as GPUs internamente precisam obter derivadas das coordenadas de textura para fazer a seleção do mipmap e a filtragem anisotrópica. Como o hardware precisa da capacidade de qualquer maneira (você pode usar qualquer expressão arbitrária para coordenadas de textura em um sombreador), foi fácil o suficiente também expô-lo diretamente aos programadores de sombreador.


+1; Achei isso útil ao aplicar um efeito de perturbação a uma textura; os texcoords perturbados causavam alguma distorção de cor, mas o uso do tex2Dgrad com derivadas dos cabos tex tex originais (não perturbados) deu um resultado sem distorções.
— Maximus Minimus

Tudo bem, depois de pensar um pouco, acho que descobri minha confusão. Na minha opinião, ddxfunciona como qualquer outra função em uma linguagem de programação tradicional; você avalia a entrada, transforma-a em um ponto flutuante ou o que for e, em seguida, executa a função externa ( ddx). Mas isso é diferente: pega a sequência de entrada , avalia-a em vários locais, calcula uma derivada e relata o resultado. Isso é certo?
— Richard Rast 24/09

1
@RichardRast Right. Você pode pensar ddxcomo operando na expressão que passa para ela, e não no valor .
— Nathan Reed

Mas veja, isso é estranho o suficiente para constar na documentação. Não consigo pensar em nenhum outro momento da minha vida de programação em que esse tenha sido o caso.
— Richard Rast

Nathan Reed mencionou que as GPUs usam essas funções para a seleção do mipmap. Você também pode usá-los para forçar a GPU a selecionar um nível de mapa mip desejado ou para impedir que artefatos sejam selecionados incorretamente no nível mip. O processo está descrito nas páginas 163 e 164 do Shader X3.
— precisa saber é o seguinte
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.