¿Cómo hacer que los círculos de selección de unidades se fusionen?

16

Me gustaría saber cómo hacer que este efecto de selección de círculo combinado. Aquí hay imágenes para ilustrar:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Básicamente estoy buscando este efecto:

ingrese la descripción de la imagen aquí

¿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.

Estera
fuente
¿Podría explicar qué quiere decir con "efecto de fusión"?
wondra
Por supuesto, si observa los caracteres de la parte superior derecha de la captura de pantalla, las calcomanías no se cruzan entre sí, sino que las dos de la izquierda cruzan su círculo azul y se fusionan. Agregué una nueva captura de pantalla para mostrar el efecto.
MaT
¿Insiste en la solución de sombreador? Si no, lo resolviste en tu última foto.
wondra
La última captura de pantalla solo muestra el efecto al que estoy apuntando. El resultado final debería parecerse a las capturas de pantalla anteriores.
MaT
1
Sí, estoy de acuerdo, creo que construyen dinámicamente un círculo de malla con la textura y luego cortan la malla para fusionarlos. También es una buena solución, pero creo que es más limitado en términos de efecto que puede hacer.
MaT

Respuestas:

8

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.

Kromster dice que apoya a Mónica
fuente
La técnica Z-Buffer es interesante, pero no entiendo cómo el primer círculo transparente puede recortar las calcomanías del suelo.
MaT
0

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.

JarkkoL
fuente
1
Supongo que ha omitido la parte de su respuesta: pasar todas las ubicaciones de círculos y radios al sombreador.
Kromster dice que apoya a Mónica el
@Krom Si OP expresa algún interés en la solución, me complace dar más detalles.
JarkkoL
0

¿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.

Elvithari
fuente
Tengo la idea general, pero como usted dice, es un poco abstracto para mí con respecto a los círculos fusionados :)
MaT
0

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:

// Draw interior part of circle, shown in green in the schematic in the question.
drawInterior(x, y, z);

// Draw outline of circle, shown in red in the schematic in the question.
drawOutline(x, y, z);

La secuencia de dibujo se ve así, con deltaun pequeño desplazamiento:

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
drawInterior(x1, y1, z + delta);
drawInterior(x2, y2, z + delta);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
drawOutline(x1, y1, z);
drawOutline(x2, y2, z);

fuente
0

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.

melfar
fuente
Sí, pensé en eso también :) pero como dijiste, no es una solución de sombreador y no es una solución muy genérica. Pero gracias !
MaT
Esa es una descripción bastante vaga
Kromster dice que apoya a Mónica el
0

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.

Draco18s ya no confía en SE
fuente
¡Gracias! Entonces, en lugar de dibujar primero las partes visibles, debería comenzar renderizando los círculos transparentes en la plantilla. ¿Pero cómo renderizo círculos redondos transparentes? No puedo limitar partes de la imagen para que se muestren en la plantilla. Cuando paso a la plantilla, todo va allí, ¿estoy en lo cierto?
Doodlemeat
Sí, es por eso que la segunda pasada (la porción visible) se escala más grande: por lo que sus límites son más grandes que el búfer de la plantilla. Solo tiene que aplicar un escalar de vértice en la segunda pasada (busque sombreadores de contorno, la mayoría usa el escalar más simple al que me refiero). Tampoco puede cambiar el búfer de la plantilla si el color es transparente. Probablemente necesitará una segunda máscara de textura en este caso o puede hacer algunos cálculos de distancia para determinar el círculo. Necesitaría un par de horas y acceso a Unity para proporcionar cualquier código.
Draco18s ya no confía en SE
Hmm, ¿qué hay de tener una imagen en blanco y negro solo para escribir en el búfer de la plantilla en la primera pasada para que el negro se convierta en 0 y el blanco se convierta en 1 en la plantilla. ¿Es eso posible?
Doodlemeat
Eso es lo que quise decir con una segunda máscara de textura. Estoy bastante seguro de que funcionaría, simplemente no puedo verificarlo sin tener a Unity frente a mí, lo cual no tendré durante más de 24 horas.
Draco18s ya no confía en SE