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 °.
Lo he comprobado, tiene sentido. –
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
@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? –