O que são derivados do espaço na tela e quando eu os utilizaria?

12

Vejo as funções ddxe ddyglsl e os equivalentes hlsl aparecerem no código shader de vez em quando. Atualmente, estou usando-os para fazer o mapeamento de resposta sem tangente ou bitangente, mas basicamente colei o código. Eu não entendo o que essas funções realmente são, o que elas fazem e quando eu procuraria usá-las.

Então, perguntas:

  1. Quais são as funções derivadas do espaço na tela?
  2. O que essas funções fazem? Os valores de entrada e valores de saída
  3. Para quais efeitos eles são mais usados?
  4. Que tipo de efeito exige que você observe essas funções?
NeomerArcana
fonte
No passado, eu as usei para distorções de textura, nas quais a distorção pode fazer com que o nível de nível errado seja selecionado para alguns fragmentos; normalmente, um nível médio mais baixo, para que você possa ver a textura mudando visivelmente em detalhes à medida que se deforma. Pegar as derivadas dos cabos de texto sem distorção, calcular a distorção e usar tex2Dgrad / SampleGrad / textureGrad com os cabos e derivações deformados impede que isso aconteça.
Maximus Minimus
@ LeComteduMerde-fou o que são distorções de textura? Um google rápido sugere que você quer dizer wrap?
NeomerArcana 4/10
Não, eu me refiro urdiduras , ou seja, distorcendo a textura, alterando as coordenadas de textura ao longo do tempo.
Maximus Minimus 04/10
Veja esta pergunta relacionada . Não acho que seja uma duplicata, já que a pergunta vinculada é perguntar mais sobre como essas funções funcionam / como são calculadas, em vez de um nível superior "o que é isso e para que serve?"
DMGregory
Olá, estou muito interessado nisso . Atualmente, estou usando-os para fazer o mapeamento de bump sem uma tangente ou bitangente, mas basicamente colei o código. ... Eu estava pensando em usá-lo para isso ... mas não sei como transformar esses derivados do espaço da tela em normais do espaço do mundo usando álgebra linear barata. Talvez eu precise inverso da matriz de projeção da câmera.
Prokop Hapala

Respostas:

12

Primeiro, ajuda a saber que as GPUs sempre avaliam shaders de fragmento / pixel em blocos de 2 x 2 de pixels por vez. (Mesmo que apenas alguns desses pixels precisem ser desenhados, enquanto outros estão fora do polígono ou ocluídos - os fragmentos desnecessários são mascarados em vez de serem escritos no final).

Diagrama ilustrando derivadas em um triângulo rasterizado

A derivada do espaço na tela de uma variável (ou expressão) vno seu sombreador é a diferença no valor de v(nesse ponto do código) de um lado desse quad de 2x2 pixel para o outro. ie ddxé o valor de vno pixel direito menos o valor de vna esquerda e da mesma forma ddyna vertical.

Isso responde "com que rapidez vaumenta ou diminui à medida que nos movemos horizontalmente (ddx) ou verticalmente (ddy) pela tela?" - ie. em termos de cálculo, aproxima as derivadas parciais de sua variável (aproximada porque usa amostras discretas em cada fragmento, em vez de avaliar matematicamente o comportamento infinitesimal da função)

Para quantidades escalares, também podemos ver isso como um vetor de gradiente ∇v = float2(ddx(v), ddy(v)) que aponta ao longo da direção do espaço na tela na qual vestá aumentando mais rapidamente.

Esse tipo de informação é frequentemente usado internamente para selecionar um mipmap apropriado ou um núcleo de filtragem anisotrópico para pesquisas de textura. Por exemplo, se minha câmera parecer quase paralela à uvdireção vertical de um plano de piso texturizado, ddy(uv.y)será muito grande em comparação com ddx(uv.x)(já que o eixo vertical é aumentado na tela - um passo de pixel cobre verticalmente um trecho mais longo do espaço de textura), o que diz ao hardware de amostragem de textura que eu preciso de filtragem anisotrópica para desfocar a direção da textura vertical mais do que a horizontal para evitar artefatos de aliasing.

Para efeitos mais simples, você não precisa usar essas derivadas, já que os métodos básicos de amostragem de textura 2D tratam disso para você. Mas, como o Le Comte du Merde-fou menciona em um comentário acima, ao distorcer suas pesquisas de textura, talvez seja necessário recuperar e / ou massagear manualmente os derivados do espaço na tela a serem usados, para ajudar o hardware a selecionar a filtragem apropriada (por exemplo, via tex2Dlodem HLSL)

Os decalques do espaço da tela são um desses casos, em que um único bloco 2x2 pode cobrir uma grande descontinuidade de salto na coordenada calculada da textura, levando a uma borda manchada ou com alias se você deixar o sistema calcular o nível de filtragem ingenuamente. Este artigo entra em detalhes sobre esse artefato e abordagens para mitigá-lo .

Esses derivados também podem ser úteis quando você estiver usando funções de ruído na geração processual de texturas. Se, por exemplo, você deseja transformar ruído procedural em um mapa normal, ddx e ddy fornecem uma maneira simples, se aproximada, de calcular como o valor do ruído está mudando nas proximidades do fragmento atual e para que lado está inclinado. pode construir um normal apropriado.

As técnicas para renderizar linhas com suavização de borda ou realces de interseção também podem usar derivadas do espaço na tela, para garantir que a espessura / queda seja consistente e não dependa da geometria ou do ângulo de visão.

Nesta palestra sobre renderização de areia no Journey , o palestrante menciona que eles poderiam ter usado essas funções derivativas para controlar o brilho da areia ao longo das bordas que olham ... se eles soubessem sobre ela na época (em vez disso, usaram um truque de mipmapping, que, sob o capô, é alimentado por esses tipos de derivativos)

Uma última observação a ser observada: as derivadas do espaço na tela podem ser calculadas com precisão "grossa" / baixa (o que significa que um par de derivadas é compartilhado por todo o quad) ou "fina" / alta precisão (ou seja, cada pixel é comparado apenas com seu valor imediato) vizinhos no quad, o que poderia dar quatro pares derivados distintos sobre o quad). Geralmente, grosso é o suficiente, mas se você perceber que está obtendo blocos 2x2 visíveis no seu efeito, é uma boa pista que deseja mudar para a precisão fina / alta. ;)

(No diagrama na parte superior, usei cálculos para derivadas finas, mas cuidado com o fato de que apenas ddx / ddy por conta própria pode ter como padrão derivadas grosseiras)

DMGregory
fonte
Quando você diz que é a diferença entre os pixels de um lado do bloco 2x2 para o outro, é a diferença no valor do pixel ou a diferença na posição texel? Se é a diferença de valor, resume os texels no meio ou algo assim?
NeomerArcana 4/10
É a diferença no valor do argumento ( vaqui) e, como é um quad 2x2, não há pixels no meio. Portanto, se estivermos sombreando o fragmento superior esquerdo do quadrilátero, v = 1, e no fragmento superior direito v = 4, então ddx (v) = 3 (dizendo "v aumenta em 3 à medida que avançamos" esquerda para a direita ")
DMGregory
Eu ainda não entendo direito. Se estiver vendo em ângulo, o bloco 2x2 pode não ser composto de pixels lado a lado na textura. Portanto, a diferença de valores é a diferença entre os dois texels selecionados ou a diferença entre os dois texels selecionados, levando em consideração os ignorados?
NeomerArcana 5/10
Esqueça texels - não está provando a textura. Ele pega o valor literal do argumento que você passou para ddx ou ddy e o compara com o valor passado para ddx ou ddy ao avaliar o fragmento vizinho. Se esse valor veio de uma amostra de textura, que seja, mas as funções derivadas não têm conhecimento de texturas. Eles apenas subtraem números. Tentarei adicionar um diagrama a esta resposta quando voltar ao meu PC.
DMGregory
Oh, eu acho que entendo agora. Seria ótimo obter um diagrama, mas acho que entendo. Estas parecem ser funções muito úteis.
NeomerArcana 05/10