Se você estiver criando uma imagem em perspectiva e seu modelo tiver interseções implícitas, se você usar "Z linear", essas interseções aparecerão nos lugares errados.
Por exemplo, considere um plano de solo simples com uma linha de postes telefônicos, recuando para a distância, que perfuram o solo (e continuam abaixo). As interseções implícitas serão determinadas pelos valores de profundidade interpolados. Se não houver interpolação 1/Z
, quando os vértices projetados forem computados com perspectiva, a imagem parecerá incorreta.
Peço desculpas pela qualidade não estética das ilustrações a seguir, mas as fiz em 97.
A primeira imagem mostra o efeito de renderização necessário. (Observe que os "postes" azuis percorrem uma longa distância sob o plano do solo e, portanto, são cortados na parte inferior das imagens)
Esta segunda imagem mostra o resultado do uso de um buffer de profundidade não recíproco: (Desculpas pela mudança de escala - elas foram copiadas de um documento antigo do MS Word e não faço ideia do que aconteceu com a escala).
Como você pode ver, os resultados estão incorretos.
Em outra nota, você tem certeza de que deseja realmente uma representação Z linear? Se você está criando uma perspectiva, certamente alguém quer mais precisão mais perto da câmera do que à distância?
Re seu comentário posterior:
"Se esses não são interpolados com 1 / Z" que eu não entendo. Que interpolação é essa?
A primeira coisa a observar é que, com uma projeção em perspectiva padrão, as retas no espaço do mundo permanecem retas no espaço da perspectiva. Distâncias / comprimentos, no entanto, não são preservados.
Para simplificar, vamos supor que uma transformação de perspectiva trivial seja usada para projetar os vértices, ou seja,
Também devemos calcular uma profundidade recíproca no espaço da tela, por exemplo, mas o Z linear no buffer de profundidade exigiria algo como: (Podemos assumir aqui que escala = 1)XSc r e e n=XWo r l dZWo r l d
YSc r e e n=YWo r l dZWo r l d
ZSc r e e n=1 1ZWo r l d
ZSc r e e n= s c a l e ∗ZWo r l d
Vamos supor que temos uma linha com os pontos finais do espaço mundial
Com a perspectiva mapeada, esses mapas para coordenar o espaço da tela
⎡⎣⎢0 00 01 1⎤⎦⎥um n d⎡⎣⎢2000 010⎤⎦⎥
⎡⎣⎢0 00 01 1⎤⎦⎥um n d⎡⎣⎢200 00,1⎤⎦⎥
O sistema / hardware de renderização interpolará linearmente o espaço da tela z, portanto, no ponto 1/2 da linha, como aparece na tela, ou seja, no pixel (10, 0), obteríamos um Z (inverso) projetado 0,55, que corresponde a um valor de Z do espaço no mundo de ~ 1,818. Dados os valores Z inicial e final, isso é cerca de 20% ao longo do comprimento da linha.
Se, em vez disso, tentássemos interpolar usando os valores Z originais, acabaríamos com Z correspondente a um valor do espaço mundial de 5,5. Desde que nada se cruze, você pode ficar bem (não pensei muito nisso), mas qualquer coisa com interseções implícitas estará incorreta.
O que eu não mencionei é que, depois de introduzir a texturização correta da perspectiva (ou mesmo o sombreamento correto da perspectiva), você deve fazer uma interpolação por pixel de 1 / w e, além disso, também calcular, por pixel, o inverso desse valor interpolado.
far / z
, que é padrão, não faz sentido. Ele produz um buffer de profundidade que se torna mais linear quanto mais próximos os dois planos de clipe estiverem um do outro. Parece uma fusão de dois conceitos: Z espaço-linear da tela e um mapeamento de buffer de profundidade não constante para um hack de desempenho.(x, y, z) / w
por fragmento, mas aparentemente, em vez disso, temos que lidar com uma versão interpolada linearmente de(x/w, y/w, z/w)
? Isso não me parece razoável em 2018, mas seria bom saber se esse é o truque com o qual temos que conviver por enquanto!O uso de Z / W para o buffer de profundidade é mais profundo do que apenas recortar nos planos próximos e distantes. Como Simon mencionou, isso tem a ver com interpolação entre os vértices de um triângulo, durante a rasterização.
Z / W é a opção exclusiva que permite que os valores de profundidade de NDC sejam calculados corretamente para pontos no interior do triângulo, interpolando simplesmente linearmente os valores de profundidade de NDC dos vértices, no espaço da tela . Em princípio, poderíamos usar qualquer função que gostamos de mapear o espaço da câmera Z para o valor do buffer de profundidade - mas qualquer outra opção além de Z / W exigiria uma matemática mais complicada por pixel, que seria mais lenta e mais difícil de executar. construir em hardware.
Observe que se você usar um buffer de profundidade linear, é claro que os valores de profundidade interpolados linearmente estarão corretos no espaço do mundo ... mas não, em geral, no espaço da tela! E é o espaço da tela que importa para a rasterização, pois precisamos gerar valores de profundidade com perspectiva correta (e outros valores de atributo, como UVs) para cada centro de pixel ou outro ponto de amostra dentro dos limites do espaço da tela de um triângulo sendo rasterizado.
fonte