Me gustaría saber cómo hacer que este efecto de selección de círculo combinado. Aquí hay imágenes para ilustrar:
Básicamente estoy buscando este efecto:
¿Cómo se puede lograr el efecto de fusión de los círculos? No encontré ninguna explicación sobre este efecto. Sé que para proyectar esas texturas puedo desarrollar un sistema de calcomanías, pero no sé cómo crear el efecto de fusión.
Si es posible, estoy buscando una solución puramente shaders.
Respuestas:
Hay algunos trucos que puedes hacer:
Z-buffer
Después de haber renderizado todos los demás objetos, para cada unidad renderice un círculo transparente de menor tamaño con un valor máximo de Z. Luego renderice calcomanías de círculos de selección en el suelo. Como están debajo en orden Z, se descartarán cuando estén debajo de las unidades.
Ser completamente transparente significa que el círculo se escribe solo en Z-buffer (valor máximo de Z). Ahora, cuando renderiza calcomanías, se prueban contra los valores del buffer Z, y si pasan la prueba, se procesan (lo que ocurre solo fuera de los círculos)
Plantilla
Igual que con el enfoque anterior, pero esta vez use un búfer de plantilla. Renderice círculos más pequeños para unidades con algún valor de plantilla, luego renderice calcomanías de selección. Configure la plantilla para descartar cualquier elemento con su valor de plantilla.
fuente
Por ejemplo, puede verificar en el sombreador de píxeles de representación de calcomanías si hay una intersección con cualquier otra calcomanía y eliminar el píxel si es así. Es bastante eficiente para este tipo de calcomanías circulares.
fuente
¿Te refieres a esos círculos azules en el suelo?
Puede haber una forma más inteligente de hacer esto, pero considere mi solución como un ejemplo de cómo se puede hacer esto. Representa tus círculos en una textura vacía separada del tamaño de la pantalla. En este punto, puede mezclarlos, como quiera. Dependiendo de sus necesidades, puede escribir a todo color o solo la información de que un círculo está presente en un píxel dado. Sin embargo, definitivamente necesitará una información de profundidad para cada píxel que escriba si desea un efecto de prueba Z.
Cuando renderiza el terreno después del paso anterior, puede muestrear la textura creada previamente, utilizando coordenadas de pantalla en sombreador de píxeles, como UV. Ahora ya sabes, que el círculo debería o no proyectarse en un píxel dado del terreno. Sin embargo, de esta manera funcionará como si la prueba Z estuviera desactivada, por lo que un terreno no puede ocultar ningún círculo. Si desea un terreno para ocultar círculos que están detrás de él, realice una prueba de profundidad antes de mezclar un círculo con la textura del terreno. Puede usar un pequeño sesgo para permitir la representación de círculos que se encuentran un poco debajo del terreno, pero aún así desea que se representen.
Editar: ahora para obtener el efecto de los círculos fusionados, lo que debe hacer es: Al renderizar en una textura separada, debe verificar si ya hay un círculo renderizado donde está intentando renderizar uno nuevo. (Compruebe si la textura tiene un valor allí) si es así, borre este píxel. Esto debería dar el efecto de "esquema" cuando se superponen dos o más círculos. Para que esto funcione correctamente, sin embargo, deberá realizar esta prueba solo para el interior del círculo, no para el borde. Entonces, al representar círculos, escriba un valor específico en la textura de salida, lo que indica que es un círculo en su interior. Entonces solo necesitas no representar nada en el círculo interior y deberías ser bueno.
Edit2: para su simple ejemplo rojo / verde: antes de renderizar cualquier píxel, verifique si este píxel no es verde. Si es así, no renderice. Esto hará el truco. De hecho, mientras escribe en la textura, incluso puede usar rojo / verde para el exterior / interior del círculo, y luego, mientras renderiza el terreno, lea esos valores y conviértalos al color deseado.
Si mi respuesta es demasiado abstracta por casualidad, avíseme.
fuente
Hay algunas opciones Como método general, los búferes de plantilla a menudo son muy útiles cuando es necesario enmascarar ciertos dibujos, como el contorno donde los círculos se superponen en su ejemplo.
En este caso, creo que esto se puede hacer con la misma facilidad sin un búfer de plantilla. Puede usar el búfer de profundidad para eliminar el contorno donde se superponen los círculos. La idea es dibujar el interior de los círculos solo en el búfer de profundidad (ya que no queremos ver el interior) y luego dibujar el contorno. De esta manera, la parte del contorno que se superpone con otro círculo será eliminada por la prueba de profundidad.
La única advertencia es que debes tener cuidado con la lucha en profundidad. Puede usar un pequeño desplazamiento para asegurarse de que los contornos estén de hecho detrás del interior y que la prueba de profundidad los elimine. Una alternativa sería usar
glPolygonOffset()
.Digamos que tiene dos círculos que son paralelos al plano xy, con centros en (x1, y1, z) y (x2, y2, z). Y tiene estas funciones de dibujo:
La secuencia de dibujo se ve así, con
delta
un pequeño desplazamiento:fuente
Fuera de la parte superior de mi cabeza, si estas calcomanías se dibujan como discos, probaría cada círculo para ver la intersección entre sí y colocaría los puntos de intersección en una matriz. Luego dibuja arcos que no estén dentro de una intersección. Sin embargo, esta no es una solución de sombreador.
fuente
Quieres estar aquí. Su primer pase representa los círculos en el búfer de la plantilla. La segunda pasada representa el contorno visible , en cualquier lugar donde el búfer de la plantilla no haya cambiado. La segunda pasada debe usar geometría que sea más grande que la primera pasada, en este caso, un escalar lineal simple es suficiente.
Si bien la solución que tengo para dibujar contornos aquí es más de lo que necesita (ya que ese sombreador convierte cada borde de malla en un quad completo), sigue este enfoque: dibuja el modelo original en el búfer de la plantilla y luego presenta una versión más grande donde el búfer de la plantilla sigue siendo 0.
fuente