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).
A derivada do espaço na tela de uma variável (ou expressão) v
no 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 v
no pixel direito menos o valor de v
na esquerda e da mesma forma ddy
na vertical.
Isso responde "com que rapidez v
aumenta 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 v
está 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 à uv
direçã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 tex2Dlod
em 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)