¿Qué tipo de algoritmo de sombreado podría usarse para crear sombras como estas?
el que estoy haciendo es similar, pero todo se hace con una API de dibujo 2D impulsada por OpenGL, por lo que no hay una coordenada Z.
Además, para la mano en sí, realmente me gustaría tener una sensación de sombra como se ve aquí:
No estoy seguro de cómo lograr un aspecto sombreado cercano a eso.
El número de cartas está obligado a cambiar y las cartas se arrojan sobre la mesa, por lo que no puedo usar ningún tipo de mapa de luz.
¿Qué tipo de algoritmos debo analizar (aparte del desenfoque que sé que tendré que hacer?)
Gracias
Actualizar
Estoy haciendo un juego de cartas en 2D. Quiero agregar sombras paralelas a las cartas, un poco como:
La forma en que pienso hacerlo es:
- Mantenga una textura que sea del mismo tamaño que el backbuffer.
Dibuja rectángulos oscuros como tarjetas improvisadas para esa textura.
Desenfoca esa textura.
- Dibuja mis cartas con esa textura.
- Haga iluminación adicional en las tarjetas.
- Dibuja esta textura en el backbuffer.
Mis preguntas son:
¿Es esta la forma correcta de hacer esto?
¿Hay alguna manera de hacerlo sin renderizar a la textura (manteniendo un mapa de bits
tan grande como el backbuffer)?¿Es seguro asumir que el tamaño máximo de la textura no será
excedido por el tamaño del backbuffer? (Lo que quiero decir es que si el backbuffer
es 2000x3000, ¿es seguro decir que puedo crear una textura en
la memoria de video de ese tamaño?
Gracias
fuente
Respuestas:
Creo que todos están dando soluciones demasiado complicadas a este problema.
Primero, tenemos la tarjeta (o lo que sea que quieras dibujar), representada aquí por (a). Luego, tomamos una copia, la rellenamos de negro y ejecutamos un desenfoque gaussiano (b). Todo esto sucede en Photoshop o cualquiera que sea tu herramienta de arte favorita.
A continuación, en el juego, cuando queremos dibujar la tarjeta, primero dibuje la imagen negra borrosa con mezcla multiplicativa (o alfa), desplace un poco en alguna dirección, y luego dibuje la tarjeta encima de eso. Voilá
Para obtener más trucos, puede alternar entre el sombreado y el renderizado de la tarjeta para obtener un efecto como (d), o primero dibujar todas las sombras y luego las cartas, como en (e) (coloreé las cartas en el caso (e) para mostrar que todavía estás separado =)
También es mejor no usar negro puro (o alfa completo) para que la sombra cree sombras más sutiles y transparentes.
fuente
El primero no es demasiado difícil. Si renderiza un canal alfa para su mano de tarjetas (que podría ser tan simple como negro para un píxel con una tarjeta en él y blanco para transparente), puede realizar cualquier tipo de desenfoque que desee solo en el canal alfa, y luego compensarlo y usarlo para controlar la iluminación de la mesa. (Presumiblemente, si no tiene un búfer Z, primero debería renderizar el canal alfa fuera de la pantalla, luego hacer la tabla con la máscara y luego renderizar las tarjetas reales).
El segundo se parece un poco a SSAO (oclusión ambiental del espacio de pantalla). Esa técnica requiere una coordenada Z. Sin embargo, si no tiene los ángulos variables entre las tarjetas (que es lo que supongo que no tiene Z-buffer), probablemente pueda hacer una aproximación bastante buena al representar una sombra paralela (como la primera) para cada tarjeta. Sin embargo, el rendimiento podría ser un poco complicado: cada avión necesitaría un canal alfa borroso para todos los planos que se encuentran sobre él, y si hay un montón de cartas en la mesa, eso podría ser un buen número de pases de renderizado.
fuente
¿No podrías hacer un mapa de sombras? Renderiza la escena a un fbo. Guarde solo los valores de profundidad y verifique el valor de profundidad normal en el sombreador para ver si se debe representar una sombra o no.
fuente
El siguiente proceso no requiere un objetivo de renderizado fuera de la pantalla. Sin embargo, al hacerlo, gana el requisito de que la tabla se dibuje primero . O al menos, no se dibuja nada en los píxeles que cubrirá la tabla antes de que se dibuje la tabla. También requiere que la tabla en sí sea una pieza única, no superpuesta: una imagen.
Además, su framebuffer necesita un componente alfa.
Obtenga una imagen en escala de grises de una tarjeta. Hazlo borroso alrededor de los bordes, posiblemente expandiendo su tamaño. Esta es tu imagen de tarjeta de sombra. Tenga en cuenta que esta es una imagen de un solo canal. Cuando accede a esta textura en su sombreador, debe asegurarse de colocar el valor único en el componente alfa. Esto se puede hacer en su sombreador o en otro lugar.
Un valor de 0.0 en la imagen significa que no hay sombra. Un valor de 1.0 en la imagen significa sombra total . Es decir, completamente negro. Probablemente desee un valor de 0.5 más o menos como su color más oscuro.
Borre la pantalla de modo que el alfa esté configurado en cero .
Antes de representar cualquier cosa (o al menos todo lo que se representará "debajo" de la tabla), para cada tarjeta, renderice la textura difusa, desplazada de la posición real de la tarjeta (pero con la misma orientación). La salida de color del sombreador debe ser La configuración de mezcla para esto debe ser (en lenguaje OpenGL):
Este modo de fusión se utiliza para evitar que las sombras superpuestas se vuelvan cada vez más oscuras o más claras. Simplemente toma el valor más oscuro escrito en ese píxel. Debería verse lo suficientemente bien.
También debe usar la máscara de escritura de color para desactivar las escrituras de color.
Renderiza la mesa. Al hacerlo, la combinación se debe configurar de la siguiente manera:
Si las restricciones son demasiado restrictivas para usted, entonces debe usar un objetivo de representación. Esto se hace de la siguiente manera:
Crea la imagen de la tarjeta de sombra como antes.
Primero, renderiza las sombras. Vincula el framebuffer de sombra (que solo necesita ser una imagen de un solo canal, si tu hardware puede renderizar a uno de esos). Borrar su valor a cero.
Para cada tarjeta, renderice la imagen de la tarjeta de sombra, desplazada como antes. Su sombreador debe escribir el mismo valor en los cuatro componentes del color de salida. El modo de mezcla nuevamente debería ser
glBlendEquation(GL_MAX)
.Regrese al framebuffer normal. Dibuja todo lo que quieras que se sombree.
Ahora dibuje un quad de pantalla completa con la imagen de sombra que renderizamos. El sombreador debe almacenar el texel obtenido de la imagen en la sombra en el alfa de la salida; El RGB es irrelevante. El modo de mezcla debe ser:
fuente
Usaría el búfer de la plantilla. Despeje a 1 (preferiblemente al mismo tiempo que despeja la profundidad), dibuje su tabla. Luego habilite la prueba de plantilla, dibuje las sombras usando una textura de rectángulo borrosa, incrementando si la plantilla y la profundidad pasan, sin hacer nada si la plantilla falla, nada si la profundidad falla, y configure su función de plantilla en GL_EQUAL (ref 1, máscara 0xff), desactive la prueba de plantilla . (No he probado completamente esto, pero se deriva del código que hace algo similar y debería funcionar bien; es posible que deba ajustar los parámetros). Luego dibuja todo lo demás.
Las llamadas serían:
La única vez que esto puede causar problemas es si tiene dos bordes borrosos que se superponen ligeramente; de lo contrario, no necesita nada más que lo que ofrece OpenGL 1.1 básico y funcionará en todo el hardware (espere quizás las tarjetas 3DFX antiguas, que supongo que no está realmente preocupado por admitir ...)
Una segunda alternativa, que debería funcionar muy bien en un juego que no es crítico para el rendimiento, es glCopyTexSubImage2D. Eso también funcionará con una textura más pequeña que el backbuffer y también es compatible con todo el hardware (es parte de OpenGL 1.1 y Doom 3 lo usó, por lo que puede esperar que el soporte sea muy bueno).
La configuración básica sería así:
Eso también debería funcionar muy bien, es un poco más intensivo en GPU que el método de búfer de plantilla, pero maneja el caso superpuesto correctamente y, como dije, creo que un juego como el tuyo tendrá potencia de GPU para grabar, incluso en un extremo bajo tarjeta.
fuente