2012-08-14 17 views
10

He estado aprendiendo OpenGL, y el único tema que continúa desconcertándome es el plano de recorte de lejos. Aunque puedo entender el razonamiento detrás del plano de recortes cercano, y los planos de recorte laterales (que nunca tienen ningún efecto real porque los objetos fuera de ellos nunca se representarían de todos modos), el plano de recorte de lejos parece ser solo una molestia.¿Por qué OpenGL tiene un plano de recorte de lejos, y qué modismos se utilizan para hacer frente a esto?

Dado que los que están detrás de OpenGL obviamente han pensado en esto, sé que debe haber algo que me falta. ¿Por qué OpenGL tiene un plano de recorte de lejos? Y lo que es más importante, como no puede apagarlo, ¿cuáles son las expresiones idiomáticas y prácticas recomendadas para dibujar a grandes distancias (para objetos como estrellas a miles de unidades de distancia en un juego espacial, un palco aéreo, etc.)? ¿Se espera que el plano de recorte esté muy lejos o hay una solución más elegante? ¿Cómo se hace esto en el software de producción?

Respuesta

19

La única razón es la precisión de profundidad. Como solo tiene un número limitado de bits en el búfer de profundidad, también puede representar una cantidad finita de profundidad con él.

Sin embargo, puede establecer el plano lejano en infinitamente lejano: Consulte this. Simplemente no funcionará muy bien con el búfer de profundidad: verá muchos artefactos si tiene una oclusión muy lejos.

Por lo tanto, dado que esto gira en torno al búfer de profundidad, no tendrá problemas para manejar cosas más lejanas, siempre que no lo use. Por ejemplo, una técnica común es renderizar la escena en "losas" que cada una utiliza internamente el búfer de profundidad (para todas las cosas en una losa) pero alguna forma de algoritmo de pintor externamente (para las losas, para que dibuje la más lejana primero)

+0

Puede valer la pena señalar que establecer el plano de recorte cercano a cero causará el mismo efecto que tener el plano de recorte muy lejos demasiado lejos. De acuerdo con http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm aproximadamente la cantidad de bits perdidos es log2 (lejos/cerca). –

9

¿Por qué OpenGL tiene un plano de recortes lejano?

Porque las computadoras son finito.

En general, hay dos maneras de tratar de hacer frente a esto. Una forma es construir la proyección tomando el límite conforme z-far se acerca al infinito. Esto convergerá en valores finitos, pero puede causar estragos con su precisión de profundidad para objetos distantes.

Una alternativa (si está dispuesto a hacer que los objetos que se encuentran más allá de una cierta distancia no hagan una prueba de profundidad correctamente) es activar la fijación de profundidad con glEnable(GL_DEPTH_CLAMP). Esto evitará recortes contra los planos cercano y lejano; es solo que cualquier fragmento que haya normalizado las coordenadas z fuera del rango [-1, 1] será sujetado a ese rango. Como se indicó anteriormente, daña las pruebas de profundidad entre los fragmentos que se sujetan, pero generalmente esos objetos están muy lejos.

0

Es sólo "el hecho de" que OpenGL prueba de la profundidad se realizó en coordenadas espacio de la ventana (dispositivo normalizado coordina en [-1,1]^3. Con glViewport escalamiento adicional y glDepthRange).

Así que, desde mi punto de vista, es uno de los puntos de vista del diseño de la biblioteca OpenGL.


Uno de enfoque para eliminar esta extensión OpenGL/OpenGL funcionalidad central https://www.opengl.org/registry/specs/ARB/depth_clamp.txt si está disponible en su versión de OpenGL.


Quiero describir que en la proyección de perspectiva no hay nada sobre "plano de recorte de lejos".

3.1 Para la proyección en perspectiva necesita configurar el punto \ vec {c} como centro de proyección y plano en el que se realizará la proyección. Llamémoslo plano de imagen T: (\ vec {r} - \ vec {r_0}, \ vec {n})

3.2 Supongamos que el plano proyectado T divide el punto arbitario \ vec {r} y \ vec { c} central de proyección. En otro caso, \ vec {r} y \ vec {c} están en un espacio seguro y el punto \ vec {r} debe descartarse.

3.4 La idea de proyección es encontrar intersección \ vec {i} con el plano T \ vec {i} = (1-t) \ vec {c} + t \ vec {r}

3,5 Como es (\ vec {i} - \ vec {r_0}, \ vec {n}) = 0

=>

((1-t) \ vec {c} + t \ vec {r} - \ vec {r_0}, \ vec {n}) = 0

=>

(\ vec {c } + t (\ vec {r} - \ vec {c}) - \ vec {r_0}, \ vec {n}) = 0

3.6. A partir de "3.5" derivado, puede sustituirse por "3.4" y recibirá una proyección en el plano T.

3.7. Después de la proyección, tu punto estará en el avión. Pero si se supone que el plano de la imagen es paralelo al plano OXY, entonces puedo sugerir utilizar la "profundidad" original para el punto después de la proyección.

Por lo tanto, desde el punto de vista de la geometría es posible no utilizar el avión lejano en absoluto. Como tampoco para usar el modelo [-1,1]^3 explícitamente en absoluto.

p.s. No sé cómo escribir las fórmulas de látex de la manera correcta, s.t. ellos serán rendidos.

Cuestiones relacionadas