No OpenGL, como posso descobrir a faixa de profundidade de um buffer de profundidade?


11

Estou fazendo um aplicativo de renderização GL de várias passagens para iOS. A primeira passagem é renderizada em uma textura de buffer de profundidade. A segunda passagem usa os valores no buffer de profundidade para controlar a aplicação de um sombreador de fragmento. Desejo redimensionar os valores no buffer de profundidade para algo útil, mas antes que eu possa fazer isso, preciso conhecer o intervalo de valores de profundidade dos valores do buffer de profundidade. Como eu faço isso?

Respostas:


10

O intervalo dos valores gravados no buffer de profundidade é o que você deseja que eles sejam. Normalmente, eles se enquadram no intervalo de 0 para 1. O valor real gravado no buffer de profundidade é calculado durante a transformação da viewport, com base no valor Z do vértice no espaço NDC (após a perspectiva ser dividida por w no espaço do clipe).

O valor da profundidade do NDC (Z, após a divisão da perspectiva por W) é dimensionado pela parte da profundidade da transformação da janela de visualização (que traz suas coordenadas X e Y para um espaço de coordenadas que você associaria com pixels na janela) e, em seguida, dimensionado por (2^n-1)- que deve ser lido como "dois à potência de n" - né a precisão de bits do buffer de profundidade. O valor resultante é gravado no buffer de profundidade.

OpenGL divide definição da matriz de transformação porta de visualização em glViewport e glDepthRange chamadas. glDepthRange é o que controla o fator de escala responsável por determinar a faixa de profundidade que você está perguntando. Você pode chamar glGetFloatv com o GL_DEPTH_RANGEseletor para recuperar o intervalo atual. Isso permitirá que você use o intervalo sem assumir que é de 0 a 1 (embora 99,9% das vezes, na prática, ninguém o mude).

Outras leituras, se você quiser ter uma ideia de como reconstruir a matemática para seguir o valor de Z desde o espaço dos olhos até o buffer de profundidade.


Vou dar este para Josh por todo o material de referência adicional e dicas sobre a planaridade do triângulo. Estou inclinado a fazer um hack onde estão os planos de clipe próximo / distante para corresponder exatamente à extensão z da geometria que estou renderizando, para que o mapa de profundidade tenha bons valores. O que estou fazendo? Eu quero criar efeitos de desfoque específicos de locais interessantes durante o passe 2, com base no que já está no mapa de profundidade do passe 1.
dugla

7

Os valores no buffer de profundidade estão sempre na faixa entre 0-1. Zero é que o fragmento renderizado está na profundidade do plano próximo e 1 é que o fragmento está na profundidade do plano distante. E tudo entre isso.

Se você deseja conhecer a profundidade real no espaço do mundo, é fácil calculá-lo a partir do buffer de profundidade.

depth = nearPlane + ( farPlane - nearPlane ) * depthBufferValue;

E é por isso que você especifica os planos próximos e distantes em sua matriz de projeção, para obter mais precisão do buffer de profundidade.

Também esteja ciente da diferença entre profundidade e distância ao usar valores de buffer de profundidade.


@notebene. Quase lá. Eu quero redimensionar o intervalo de valores no buffer de profundidade ser exatamente 0 -> 1. Portanto, se os valores de profundidade mínimo / máximo renderizados forem 0,25 / 0,75, desejo (valor de profundidade - 0,25) / (75 - 0,25). Assim, há uma forma de descobrir o min / max do depthbuffer seguinte passagem 1 e o uso que para redimensionar durante passe 2.
dugla

1
@ dugla: como você está processando triângulos, que são planos, então os valores mínimo e máximo de profundidade serão associados aos vértices mínimo e máximo da cena. Se você conhece esses dois, pode transformá-los manualmente por todo o pipeline e saberá os valores mínimo e máximo que gravaria no buffer de profundidade. Isso é possivelmente mais fácil do que renderizar, ler novamente todo o buffer de profundidade e iterá-lo.
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.