2011-11-11 9 views
12

Tengo una escena en 3D y una cámara definida usando gluPerspective. Tengo un campo de visión fijo, y sé la distancia mínima de cualquier geometría a la cámara (es una vista en primera persona, por lo que es la distancia mínima desde el punto de vista al volumen de colisión del personaje).¿Cómo elijo metódicamente la distancia del plano del clip cercano para una proyección en perspectiva?

¿Cómo se puede elegir el más lejano cerca plano de recorte (para la mejor resolución de buffer de profundidad), que se no causará ningún recorte, no importa cómo el jugador se mueve y se ve?

Estas distancias no son simplemente iguales porque las esquinas del plano cercano están más alejadas del origen que el centro.

Respuesta

12

Fórmula:

PlanoCercano = nearestApproachToPlayer/sqrt (1 + tan (FOV/2) · (aspectRatio + 1)))

JavaScript código:

var nearPlane = nearestApproachToPlayer 
       /Math.sqrt(1 + Math.pow(Math.tan(fov/180*Math.PI/2), 2) 
            * (Math.pow(aspectRatio, 2) + 1)); 

Derivación:

Geométricamente, considere la pirámide cuya base es el plano de recorte cerca y la punta es el origen. Deje que nearPlane sea la altura de la pirámide, y w y h el ancho y la altura de la base de la pirámide.

w = aspectRatio · h

El FOV determina la pendiente de los lados altura del eje de la pirámide:

pendiente = tan (fov/2)

h/PlanoCercano = 2 tan (fov/2)

h/2 = PlanoCercano tan (fov/2)

Cualquier esquina El punto del plano del clip cercano está desplazado del centro del plano del clip por (w/2, h/2), por lo que la distancia es sqrt ((w/2) + (h/2)). El distancia desde el origen de este punto de esquina es la hipotenusa del triángulo rectángulo formado por PlanoCercano y la antigua distancia, por lo que es sqrt ((w/2) + (h/2) + nearPlane).

Queremos que la distancia al punto de esquina sea igual al acercamiento más cercano de cualquier geometría.

nearestApproachToPlayer = sqrt ((w/2) + (h/2) + PlanoCercano)

Aplicando álgebra sencillo produce la fórmula dada arriba.

No he comprobado mi álgebra, pero he probado empíricamente la fórmula: si multiplico cerca de Plano por 1.1, entonces produce un plano de clip que está demasiado lejos, para varias relaciones de aspecto. No he probado diferentes FOV de 60 °.

+0

Lo he comprobado, tiene sentido. –

+0

Uno de los parámetros que llevará a cabo en un programa de representación 3D es el vector de vista, es decir, la dirección a la que apunta la cámara. Digamos que tiene este vector normalizado (es decir, la longitud de la unidad), luego tomar el producto escalar (= punto) con las posiciones de los objetos le da la distancia plana al origen. Este es un enfoque más directo, ya que le da el valor deseado directamente, sin la necesidad de un cuadrado, raíz cuadrada y divisiones. Solo se trata de suma multiplicada, es decir, instrucciones MAD, que son compatibles directamente con los juegos de instrucciones SIMD. – datenwolf

+0

@datenwolf No veo cómo usar eso para resolver este problema. No tengo una colección de objetos específicos; Tengo una distancia mínima e intento calcular una proyección * una vez * en vez de una dinámica. O podría decir que tengo un objeto hipotético colocado en la línea a través de la esquina superior izquierda de la ventana gráfica a la distancia mínima. ¿Puedes calcular la posición de ese objeto para usar el procedimiento que describes, con solo multiplicar/agregar? –

5

¿Cómo puedo elegir el plano más cercano al clip (para la mejor resolución del búfer de profundidad) que no causará ningún recorte, sin importar cómo se mueva y se vea el reproductor?

Simple: turn off near clipping. No puedo creer que la gente no haya oído hablar de esto todavía. Habilita el ajuste de profundidad, lo que hace que los valores cercanos (y lejanos) que están por debajo del límite (o más que el más lejano) se sujeten, en lugar de recortarse.

Esto no evitará que los objetos que realmente van detrás de la cámara se recorten. Y dado que las profundidades están sujetas, pierde la utilidad de un buffer de profundidad para aquellas regiones donde se produce la fijación. Sigue siendo una buena idea usarlo donde sea razonable, si no puede elegir un clip cercano que esté muy lejos de lo contrario.

Por lo general, es mejor habilitar la sujeción y empujar el clip que está cerca de donde está el clip mínimo absoluto cerca del clip.

+0

Creo que malinterpretas. No estoy renderizando un modelo de personaje. El volumen de colisión del personaje es solo una región en la que nada más puede entrar, por lo que se sabe que no hay nada que cortar allí. No estaba al tanto del truco de fijación de profundidad (aunque lo implementaría directamente porque estoy usando GL ES); gracias por eso. No puedo usarlo para obtener un alcance adicional porque es muy posible que los objetos cercanos a la cámara tengan geometría intersecante, pero es una buena contribución a la pregunta que realmente hice. –

+1

@KevinReid: en realidad, a menos que haya una extensión de OES, realmente no se puede usar el pinzamiento de profundidad.No hay forma de implementarlo manualmente. Ah, por cierto, si estás usando OpenGL ES, generalmente es una buena idea poner eso en las etiquetas. OpenGL y GL ES no son lo mismo, después de todo. –

+0

... correcto. Pensaba que podía hacerlo en el sombreador de fragmentos, lo que no puedo hacer ya que es demasiado tarde, y hacerlo en el sombreador de vértices crearía una distorsión visible. –

7

La mejor práctica para elegir las distancias de clip cercanas y lejanas es colocarlas cómodamente sobre la escena, es decir, el plano de clip cercano lo más lejos posible y el plano de clip de lejos lo más cerca posible.

La proyección de tronco común empleada por la mayoría de las aplicaciones 3D para una transformación de perspectiva es una proyección de plano paralelo. Eso significa determinar la distancia plana desde el punto de vista. Esto es realmente bastante simple:

Uno de los parámetros que llevará en un programa de renderizado en 3D es el vector de vista, es decir, la dirección a la que apunta la cámara. Digamos que tiene este vector normalizado (es decir, la longitud de la unidad), luego tomar el producto escalar (= punto) con las posiciones de los objetos le da la distancia plana al origen. Este es un enfoque más directo, ya que le da el valor deseado directamente, sin la necesidad de un cuadrado, raíz cuadrada y divisiones. Solo se trata de suma multiplicada, es decir, instrucciones MAD, que son compatibles directamente con los juegos de instrucciones SIMD.

Cuestiones relacionadas