Que tipo de algoritmo de sombreamento pode ser usado para criar sombras como essas?
o que eu estou fazendo é semelhante, mas tudo é feito com uma API de desenho 2D fornecida pelo OpenGL, portanto não há coordenada Z.
Além disso, para a mão em si, eu realmente gostaria de ter uma sensação sombreada como a vista aqui:
Só não tenho certeza de como obter uma aparência sombreada perto disso.
O número de cartas deve mudar e as cartas são jogadas na mesa, então não posso usar nenhum tipo de mapa de luz.
Em que tipos de algoritmos devo analisar (além do borrão que sei que precisa fazer?)
obrigado
Atualizar
Estou fazendo um jogo de cartas em 2D. Quero adicionar dropshadows offset dos cartões, um pouco como:
O jeito que eu estou pensando em fazer isso é:
- Mantenha uma textura que seja do mesmo tamanho do backbuffer.
Desenhe retângulos escuros como cartões improvisados para essa textura.
Desfoque essa textura.
- Desenhe minhas cartas para essa textura.
- Faça iluminação adicional nos cartões.
- Desenhe essa textura no backbuffer.
Minhas perguntas são:
Essa é a maneira correta de fazer isso?
Existe uma maneira de fazer isso sem renderizar para textura (mantendo um bitmap
tão grande quanto o backbuffer)?É seguro assumir que o tamanho máximo da textura não será
excedido pelo tamanho do backbuffer? (O que quero dizer é que, se o backbuffer
for 2000x3000, é seguro dizer que posso criar uma textura na
memória de vídeo desse tamanho?
obrigado
fonte
Respostas:
Acho que todo mundo está dando soluções muito complicadas para esse problema ..
Então, primeiro, temos a carta (ou o que você quiser desenhar), representada aqui por (a). Em seguida, tiramos uma cópia, preenchemos em preto e executamos um borrão gaussiano (b). Tudo isso acontece no photoshop ou seja qual for a sua ferramenta de arte favorita.
Em seguida, no jogo, quando queremos desenhar o cartão, primeiro desenhe a imagem preta borrada com uma mistura multiplicativa (ou alfa), desloque um pouco em alguma direção e depois desenhe o cartão em cima disso. Voilá.
Para mais truques, você pode alternar entre sombra e renderização de cartas para obter efeito como (d), ou primeiro desenhar todas as sombras e depois as cartas, como em (e) (colori as cartas no caso (e) para mostrar que elas ainda está separado =)
Também é melhor não usar preto puro (ou alfa completo) na sombra para criar sombras mais sutis e transparentes.
fonte
O primeiro não é muito difícil. Se você renderizar um canal alfa para sua mão de cartas (que pode ser tão simples quanto preto para um pixel com um cartão e branco para transparente), você poderá executar qualquer tipo de desfoque que desejar no canal alfa e desloque-o e use-o para controlar a iluminação da mesa. (Presumivelmente, se você não tiver um buffer Z, primeiro terá que exibir o canal alfa fora da tela em algum lugar, depois fazer a mesa com a máscara e depois renderizar as cartas reais.)
O segundo se parece um pouco com o SSAO (oclusão ambiental no espaço da tela). Essa técnica requer uma coordenada Z. No entanto, se você não tiver os ângulos variados entre as cartas (o que eu acho que se você não tiver um buffer Z), provavelmente poderá fazer uma aproximação muito boa renderizando uma sombra projetada (como a primeira) para cada cartão. Porém, o desempenho pode ser um pouco complicado - todo avião precisaria de um canal alfa desfocado para todos os planos acima dele, e se houver um monte de cartas na mesa, isso pode significar algumas passagens de renderização.
fonte
Você não poderia fazer um mapa de sombras? Renderize a cena para um fbo. Salve apenas os valores de profundidade e verifique o valor normal de profundidade no sombreador para ver se uma sombra deve ser renderizada ou não.
fonte
O processo a seguir não requer um destino de renderização fora da tela. No entanto, ao fazê-lo, ganha a exigência de que a tabela seja desenhada primeiro . Ou pelo menos, nada é desenhado nos pixels que a tabela cobrirá antes de ser desenhada. Também exige que a própria mesa seja uma peça única e não sobreposta: uma imagem.
Além disso, seu framebuffer precisa de um componente alfa.
Obtenha uma imagem em escala de cinza de um cartão. Torne-o impreciso nas bordas, possivelmente expandindo seu tamanho. Esta é a sua imagem do cartão de sombra. Observe que esta é uma imagem de canal único. Ao acessar essa textura em seu sombreador, certifique-se de colocar o valor único no componente alfa. Isso pode ser feito no seu sombreador ou em outro lugar.
Um valor de 0,0 na imagem significa que não há sombra. Um valor de 1,0 na imagem significa sombra total . Ou seja, completamente escuro como breu. Você provavelmente deseja um valor de 0,5 ou mais como a sua cor mais escura.
Limpe a tela para que o alfa esteja definido como zero .
Antes de renderizar qualquer coisa (ou pelo menos qualquer coisa que será renderizada "embaixo" da tabela), para cada cartão, renderize a textura difusa, deslocada da posição real do cartão (mas com a mesma orientação). A saída de cor pelo sombreador deve ser A configuração da mistura para isso deve ser (na linguagem OpenGL):
Esse modo de mesclagem é usado para impedir que as sombras sobrepostas se tornem cada vez mais escuras ou mais claras. Simplesmente leva o valor mais escuro gravado para esse pixel. Deve parecer bom o suficiente.
Você também deve usar a máscara de gravação em cores para desativar as gravações em cores.
Renderize a tabela. Ao fazer isso A mistura deve ser configurada da seguinte maneira:
Se as restrições forem muito restritivas para você, será necessário usar um destino de renderização. Isto se faz do seguinte modo:
Crie a imagem do cartão de sombra como antes.
Primeiro, renderize as sombras. Ligue o buffer de estrutura de sombra (que só precisa ser uma imagem de canal único, se o seu hardware puder renderizar um deles). Limpe seu valor para zero.
Para cada cartão, renderize a imagem do cartão de sombra, deslocada como antes. Seu sombreador deve gravar o mesmo valor nos quatro componentes da cor de saída. O modo de mesclagem novamente deve ser
glBlendEquation(GL_MAX)
.Volte para o buffer de quadros comum. Desenhe tudo o que você deseja ser sombreado.
Agora desenhe um quad em tela cheia com a imagem de sombra que renderizamos. O sombreador deve armazenar o texel obtido da imagem de sombra no alfa da saída; o RGB é irrelevante. O modo de mesclagem deve ser:
fonte
Eu usaria o buffer de estêncil. Limpe-o para 1 (de preferência ao mesmo tempo em que limpa a profundidade), desenhe sua mesa. Em seguida, ative o teste de estêncil, desenhe as sombras usando uma textura de retângulo embaçado, aumentando se o estêncil e a profundidade passarem, não fazendo nada se o estêncil falhar, nada se a profundidade falhar e defina sua função de estêncil para GL_EQUAL (ref 1, mascara 0xff), desative o teste de estêncil . (Eu não testei completamente isso, mas é derivado de um código semelhante e deve funcionar bem; talvez seja necessário ajustar os parâmetros). Então desenhe todo o resto.
As chamadas seriam:
A única vez que isso pode causar problemas é se você tiver duas bordas desfocadas que se sobrepõem ligeiramente; caso contrário, ele não precisa de nada sofisticado além do que o OpenGL 1.1 básico oferece e funcionará em todo o hardware (talvez placas 3DFX antigas, que eu assumo que você não esteja realmente preocupado em oferecer suporte ...)
Uma segunda alternativa, que deve funcionar muito bem em um jogo não crítico para o desempenho, é o glCopyTexSubImage2D. Isso também funcionará com uma textura menor que o backbuffer e também é suportado em todo o hardware (faz parte do OpenGL 1.1 e do Doom 3 a utilizou, portanto, você pode esperar que o suporte seja muito bom).
A configuração básica seria assim:
Isso também deve funcionar muito bem, é um pouco mais intensivo em GPU do que o método de buffer de estêncil, mas lida com a caixa sobreposta corretamente e - como eu disse - acho que um jogo como o seu terá potência de GPU para queimar, mesmo em um nível mais baixo cartão.
fonte