Cómo combinar dos cámaras cuando se viaja a través de un portal en Unity3D

18

Antes de llegar a mi pregunta, sé que la solución más obvia sería usar el puerto de vista normalizado rectificado, sin embargo, necesito formas más complejas que un rectángulo, y he buscado usar el puerto de vista rectificado y parece que no. Se mi solución.

EDITAR: Algunas personas estaban confundidas por mi pregunta, déjenme entrar un poco más en detalle. ingrese la descripción de la imagen aquí Lo que sucede es que cuando el jugador se mueve a un portal, creo un controlador FPS clon y lo saco del otro. Esto me da dos cámaras y la vista que ves a la derecha arriba. Solo muestra una cámara y recorta el portal. Lo que quiero es algo similar a estodonde las cámaras se mezclan para crear la ilusión de una transición suave. Lo que quiero hacer es eliminar todo, desde la imagen del verificador verde a la izquierda en la imagen a continuación, y reemplazarlo con la otra cámara. De esa manera, obtiene la parte de la vista de la cámara A que está saliendo del portal, combinada con la parte de la vista de la cámara B que está saliendo del otro portal, para obtener una imagen completa. Y a medida que avanza por el portal, el corte cambia adecuadamente.

He estado diseñando un sistema de portal, tengo todo abajo, incluso hacer que el jugador se mueva suavemente a través del portal. Mi principal problema ahora es conseguir el efecto de mezcla de cámara que hace Valve. Necesito dos cámaras para mezclar sin problemas, como si estuvieras asomando la cabeza por el portal. Y no puede ser solo un rectángulo, tiene que coincidir sin embargo, el jugador está mirando a través del portal.

Mi mejor ventaja en este momento es posiblemente proyectar un sombreador de máscara de profundidad detrás de cada portal, luego hacer que la cámara desde el portal al que viaja sea solo para profundidad. Luego, de alguna manera, mezcle las dos cámaras. Mi principal problema es averiguar exactamente cómo haría esto, cómo hacer que la segunda cámara solo muestre lo que está fuera del portal y que el resto sea la cámara 1 por defecto para obtener una proyección de pantalla completa.

Si pudiera darme ideas o explicar cómo puedo hacer esto con el sombreador de máscara de profundidad, sería de gran ayuda. Continuaré trabajando en esto y actualizando a medida que avance.

Timothy Williams
fuente
55
¿Puedes explicar qué es el "efecto de mezcla de cámara que hace Valve"? He entendido que en el portal la representación de una sola cámara es suficiente. En los juegos en primera persona, se adjunta al jugador y se transforma automáticamente a la nueva ubicación al pasar por el portal junto con el jugador. Para representar el efecto del portal, se representa una copia transformada de la escena. Esto también se puede lograr con una segunda cámara, pero no debería ser necesario mezclarlas.
msell 05 de
1
Ya tengo los efectos visuales perfectamente reducidos. Lo que intento hacer es descubrir cómo lograr el efecto de caminar por el portal. Ya tengo todos los gráficos de personajes y tal movimiento sin problemas, solo necesito que se vea suave desde una perspectiva en primera persona.
Timothy Williams
1
Estoy seguro de que a muchas personas les gustaría ayudarlo con el problema si entendieran de qué se trata. Realmente necesita explicar mejor el problema, tal vez agregar imágenes o incluso un video que visualice lo que está mal.
msell
2
¿Podría agregar un enlace a un video de ejemplo del efecto?
Mike Baxter
2
¿Qué pasa si usó solo una cámara / controlador FPS? Cuando la cámara se mueve a través del portal, puede transformarla a la nueva ubicación y orientación. Si la representación del portal es correcta, la transición debe ser perfecta y no se necesita mezclar.
msell

Respuestas:

6

Entendiendo el problema

Por lo que puedo ver, el problema que está describiendo es el resultado de que el plano cercano de la cámara se cruza con el plano definido por el portal. Mientras se produce esta intersección, puede ver detrás del muro en el que está el portal.

Esto es similar a un problema experimentado en otros juegos cuando el jugador solo está haciendo la transición desde arriba del agua al submarino. Si la cámara está justo encima del agua, no se aplica ningún efecto de procesamiento posterior para ofuscar la vista de los jugadores (oscurecerla, ponerla borrosa y azul). Entonces, si el fondo del avión cercano está justo debajo del agua, el jugador puede ver claramente debajo del agua.

Si estoy en lo correcto, puede confirmarlo cambiando la posición de este plano al definir la matriz de proyección. A medida que aumenta la distancia desde el origen de la cámara hasta el plano cercano, también debería aumentar el problema.

La solución fácil

Hacer que el avión cercano esté muy cerca de la cámara casi debería erradicar este problema. Esta solución no es completa, pero producirá un resultado suficientemente bueno en la gran mayoría de los casos y es eficiente.

La solución completa

Si no basta con acercar el plano cercano a la cámara, puede crear una "máscara" para combinar las imágenes generadas al representar la escena desde la perspectiva del jugador y del portal.

Suponiendo que solo permite que los portales se apliquen a superficies planas, puede calcular la línea de intersección entre el plano cercano de la cámara y el plano definido por el portal (o la pared en la que descansa). Esta línea dividirá la pantalla en dos partes. Determinar en qué lado de la línea está un píxel de la pantalla le permitirá saber qué imagen de renderización usar, la imagen del portal o la imagen de la cámara del reproductor.

Tenga en cuenta que si se produce este problema, entonces el frustum de la vista de la cámara debe estar completamente dentro del portal para que la línea de intersección siempre se corte completamente de un borde de la pantalla a otra.

Este enlace debería ayudar con las matemáticas para encontrar la línea. El siguiente código debe ser aproximadamente correcto.

La línea de intersección se define usando un punto en la línea y la dirección de la línea. Debajo de la dirección de intersección se calcula utilizando el producto transversal del portal normal y la dirección de vista de la cámara (cerca del plano normal). Se da un punto en la línea proyectando un rayo desde un punto en el plano cercano directamente hacia el plano del portal (a lo largo del portal normal) y encontrando el punto de intersección.

Vector3 intersectionDir = Vector3.cross(portalNorm, viewDir);
Ray ray = new Ray(camPos + viewDir * camNearPlaneDist, portalNorm);
Vector3 intersectionPos = ray.intersects(new Plane(portalVert1, portalVert2, portalVert3);

Asegúrese de que viewDir sea un vector unitario. portalVert1, 2 y 3 son solo 3 de los 4 vértices utilizados para la calcomanía del portal o la superficie en la que se encuentra. Hay otras formas de definir el plano en el que se encuentra el portal, pero supongo que esta es la información más fácilmente disponible.

Una vez que tenga estos dos vectores para definir la línea de intersección, multiplique cada uno por la vista y luego matrices de proyección para obtenerlos en el espacio de la pantalla.

Luego puede usar un sombreador posterior al proceso para combinar estas imágenes. Usted selecciona qué imagen usar en cada píxel determinando en qué lado de la línea divisoria se encuentra el píxel actual. Esto se hace tomando la posición del píxel (que también es la posición que usa para buscar el texel objetivo de renderizado) y haciendo;

float d = (pixelX - intersectionPos.X) * intersectionDir.Y - (pixelY - intersectionPos.Y) * intersectionDir.X;

El lado viene dado por si d es más o menos que 0. Si es exactamente 0, entonces estás en la línea.

Para referencia en las matemáticas anteriores, vea esto .

Este método también se puede usar al crear un búfer de máscara / plantilla de profundidad para usar antes de renderizar desde la perspectiva del portal. Puede crear un quad de pantalla completa y usar la línea para cortarlo.

OriginalDaemon
fuente
El plano cercano al clip fue una buena idea, pero no exactamente lo que estoy buscando. Sin embargo, esa segunda parte es un enfoque interesante. Actualmente estoy usando un sombreador de máscara de profundidad en todo lo que está detrás del plano del portal de salida, luego establezco las banderas claras de la cámara de salida solo en profundidad. Esto hace que cualquier parte de la cámara que está saliendo del portal dibuje en la pantalla, y la cámara entrante dibuja en la máscara de profundidad, por lo que crea una imagen al mezclar las partes de cada cámara que está saliendo de ella. portal respectivo. El único problema es que estoy teniendo algunos problemas menores de recorte y como
Timothy Williams
ligero tirón a medida que el jugador viaja. Esta idea que mencionaste suena bastante prometedora. Entonces, esencialmente, lo que necesito hacer es calcular la línea a lo largo de la pantalla en la que la cámara cerca del plano y el plano del portal se cruzan, la dirección me da en qué dirección va la línea y el punto son los diversos puntos de la línea. ¿Cómo determinaría en un sombreador / script en qué lado de la línea divisoria se encuentra un píxel?
Timothy Williams el
Actualicé un poco la respuesta para dar un código básico. Asegúrese de intentar cambiar la vista cerca de la distancia del plano de recorte para confirmar el problema. Hacer esto lo más pequeño posible también puede ser suficiente. Recuerde, póngalo a funcionar, póngalo a funcionar correctamente, luego póngalo a trabajar rápidamente.
OriginalDaemon
Probé cambiando la distancia del plano de recorte cercano, mejoró un poco el problema, pero como dice el artículo que Mell publicó, no soluciona el problema al atravesarlo. Sin embargo, todavía siento que la línea de intersección puede funcionar, así que voy a probarla. También miraré un poco más en ese artículo que Mell publicó. Al final, se reducirá a si una máscara de profundidad es más rápida o si esta línea de intersección es más rápida
Timothy Williams el
3

Las respuestas sugeridas fueron muy buenas, pero terminé optando por una técnica diferente usando una máscara de profundidad.

Lo que debe hacer es tomar ESTE script y sombreador, colocar el script en cada objeto con un renderizador en su escena y establecer la cola de renderizado en 3020 (publicaré un script para facilitar esto más adelante).

Luego, creas una caja de planos (todos mirando hacia adentro, en la imagen no puedes ver el lado de la caja más cercano a ti, pero cuando estás dentro de la caja, todo lo que debes ver es gris) detrás de AMBOS de tus portales así: ingrese la descripción de la imagen aquí y póngalos en una capa especial propia (elegí "DepthMask" para la mía), luego agregue un material con el sombreador de arriba. ingrese la descripción de la imagen aquí

Luego toma la cámara principal y desmarca su capa especial de su máscara de eliminación (desmarqué la capa de máscara de profundidad) y establece su profundidad en 0. ingrese la descripción de la imagen aquí

Luego, cuando se teletransporta y clona la cámara, configure las banderas claras de la otra cámara en "Solo profundidad" y su profundidad en 1. ingrese la descripción de la imagen aquí

Luego obtienes una pantalla perfecta mezclada entre las dos vistas de la cámara.

Timothy Williams
fuente