Estou trabalhando em um renderizador de frente para trás para um mecanismo 2D usando uma projeção ortográfica. Eu quero usar o buffer de profundidade para evitar excesso. Eu tenho um buffer de profundidade de 16 bits, uma câmera em Z = 100 olhando para Z = 0, zNear é 1 e zFar é 1000. Cada sprite renderizado define suas coordenadas Z para valores cada vez mais distantes, permitindo que o teste de profundidade ignore a renderização qualquer coisa que está por baixo.
No entanto, eu sei que a maneira como as posições Z acabam com os valores do buffer Z não é linear. Eu quero fazer uso da resolução completa do buffer de profundidade de 16 bits, ou seja, permitindo 65536 valores exclusivos. Portanto, para cada sprite renderizado, quero incrementar a posição Z para a próxima posição para correlacionar com o próximo valor exclusivo do buffer de profundidade.
Em outras palavras, eu quero transformar um índice incremental (0, 1, 2, 3 ...) do sprite sendo atraído para a posição Z apropriada para cada sprite para ter um valor único de buffer de profundidade. Eu não tenho certeza da matemática por trás disso. Qual é o cálculo para fazer isso?
Observe que estou trabalhando no WebGL (basicamente OpenGL ES 2) e preciso oferecer suporte a uma ampla gama de hardware, portanto, embora extensões como gl_FragDepth possam facilitar isso, não posso usá-lo por motivos de compatibilidade.
fonte
Respostas:
De fato, os valores armazenados no buffer z não são lineares às coordenadas z reais de seus objetos, mas às suas recíprocas, a fim de dar mais resolução ao que está próximo ao olho do que ao que está mais próximo do plano traseiro.
O que você faz é que você mapear o
zNear
que0
e suazFar
a1
. ParazNear=1
ezFar=2
, deve ficar assimA maneira de calcular isso é definida por:
Onde
... e z_buffer_value é um número inteiro.
A equação acima é apresentada como cortesia desta página incrível , que explica os z-buffers de uma maneira realmente boa.
Portanto, para encontrar o necessário
z
para um dadoz_buffer_value
, basta limpar oz
:fonte
z_buffer_value = k * (a + (b / z))
e simplesmente reorganizar para resolverz
, então eu recebo:z = b / ((z_buffer_value / k) - a)
- como você chegou à última fórmula diferente?(v / k) - a => (v - k * a) / k
e reduz para(k * b) / (v - (k * a))
. É o mesmo resultado.Talvez você deva mudar sua abordagem para algo mais simples. O que eu faria; Mantenha sua profundidade Z, mas mantenha uma lista do que você renderiza. Encomende essa lista com base no valor z Profundidade e renderize os objetos na ordem da lista.
Espero que isso possa ajudar. As pessoas sempre me dizem para manter as coisas simples.
fonte
Como você já tem uma lista ordenada de itens a serem renderizados (da frente para trás), realmente precisa incrementar o índice Z? Você não pode usar "menor ou igual" para a "função de verificação"? Dessa forma, ele realmente verifica se um pixel específico já foi desenhado ou não.
fonte