Gostaria de saber como fazer esse efeito da seleção de círculos mesclados. Aqui estão imagens para ilustrar:
Basicamente, estou procurando esse efeito:
Como o efeito de mesclagem dos círculos pode ser alcançado? Não encontrei nenhuma explicação sobre esse efeito. Sei que para projetar essas texturas, posso desenvolver um sistema de decalques, mas não sei como criar o efeito de mesclagem.
Se possível, estou procurando uma solução puramente shaders.
Respostas:
Existem alguns truques que você pode fazer:
Z-buffer
Depois de renderizar todos os outros objetos, para cada unidade, renderize um círculo transparente de tamanho menor com o valor máximo de Z. Em seguida, renderize os decalques dos círculos de seleção no chão. Como estão abaixo na ordem Z, serão descartados quando estiverem em unidades.
Ser totalmente transparente significa que o círculo é gravado apenas no buffer Z (valor Z máximo). Agora, quando você renderiza decalques, eles são testados em relação aos valores do buffer Z e, se passam no teste, são renderizados (o que acontece apenas fora dos círculos)
Estêncil
O mesmo da abordagem anterior, mas desta vez use um buffer de estêncil. Renderize círculos menores para unidades com algum valor de estêncil e, em seguida, renderize decalques de seleção. Configure o estêncil para descartar quaisquer elementos com seu valor de estêncil.
fonte
Você pode, por exemplo, verificar o sombreamento de pixel de renderização de decalques se houver uma interseção com outros decalques e, se houver, eliminar o pixel. É bastante eficiente fazer esse tipo de adesivo circular.
fonte
Você quer dizer aqueles círculos azuis no chão?
Pode haver uma maneira mais inteligente de fazer isso, mas considere minha solução como um exemplo de como isso pode ser feito. Renderize seus círculos para uma textura vazia separada do tamanho da tela. Neste ponto, você pode misturá-los, como quiser. Dependendo das suas necessidades, você pode escrever a cor completa ou apenas as informações de que um círculo está presente em determinado pixel. No entanto, você definitivamente precisará de informações detalhadas para cada pixel que escrever, se desejar um efeito de teste Z.
Ao renderizar o terreno após a etapa anterior, você pode experimentar a textura criada anteriormente, usando as coordenadas da tela no sombreador de pixels, como UVs. Agora você sabe que o círculo deve ou não ser projetado em determinado pixel do terreno. No entanto, dessa maneira, ele funcionará como se o teste Z estivesse desabilitado, portanto, um terreno não pode ocultar nenhum círculo. Se você deseja que um terreno oculte círculos que estão atrás dele, faça um teste de profundidade antes de misturar um círculo com a textura do terreno. Você pode usar um pequeno viés para ativar a renderização de círculos que estão um pouco abaixo do terreno, mas você ainda gostaria que eles renderizassem.
Editar: Agora, para obter o efeito de círculos mesclados, o que você precisa fazer é: Ao renderizar para a textura separada, é necessário verificar se já existe um círculo renderizado no qual você está tentando renderizar um novo. (Verifique se a textura possui um valor). Se houver, apague esse pixel. Isso deve dar o efeito de "estrutura de tópicos" quando dois ou mais círculos se sobrepõem. Para que isso funcione corretamente, você precisará fazer esse teste apenas para o interior do círculo, não para a borda. Portanto, ao renderizar círculos, escreva algum valor específico na textura de saída, o que indica que é um círculo dentro. Então você não precisa renderizar nada no círculo interno e deve ser bom.
Edit2: Para seu exemplo simples de vermelho / verde: Antes de renderizar qualquer pixel, verifique se esse pixel ainda não está verde. Se for, não processe. Isto irá fazer o truque. De fato, ao escrever na textura, você pode usar vermelho / verde para fora / dentro do círculo e, ao renderizar o terreno, leia esses valores e os converta na cor desejada.
Se minha resposta for muito abstrata por acaso, me avise.
fonte
Existem algumas opções. Como método geral, os buffers de estêncil costumam ser muito úteis onde certos desenhos precisam ser mascarados, como o contorno em que os círculos se sobrepõem no seu exemplo.
Nesse caso, acho que isso pode ser feito com a mesma facilidade, sem um buffer de estêncil. Você pode usar o buffer de profundidade para eliminar o contorno onde os círculos se sobrepõem. A idéia é que você desenhe o interior dos círculos apenas no buffer de profundidade (já que não queremos ver o interior) e desenhe o contorno. Dessa forma, a parte do contorno que se sobrepõe a outro círculo será eliminada pelo teste de profundidade.
A única ressalva é que você deve ter cuidado com os combates em profundidade. Você pode usar um pequeno deslocamento para garantir que os contornos estejam realmente atrás do interior e serem eliminados pelo teste de profundidade. Uma alternativa seria usar
glPolygonOffset()
.Digamos que você tenha dois círculos paralelos ao plano xy, com centros em (x1, y1, z) e (x2, y2, z). E você tem estas funções de desenho:
A sequência de desenho fica assim, com
delta
um pequeno deslocamento:fonte
Do alto da minha cabeça, se esses decalques forem desenhados como discos, eu testaria cada círculo em busca de interseção uns contra os outros e colocaria os pontos de interseção em uma matriz. Em seguida, desenhe arcos que não estão dentro de uma interseção. Esta não é uma solução shader, no entanto.
fonte
Você quer escrever aqui. Seu primeiro passe renderiza os círculos no buffer de estêncil. A segunda passagem renderiza o contorno visível , em qualquer lugar em que o buffer do estêncil não tenha sido alterado. A segunda passagem deve usar geometria maior que a primeira, neste caso, um escalar linear simples é suficiente.
Embora a solução que eu tenho para desenhar contornos aqui seja mais do que você precisa (como esse sombreador transforma todas as arestas de malha em um quad completo), ele segue esta abordagem: desenhar o modelo original no buffer de estêncil e renderizar uma versão maior em que o buffer de estêncil ainda é 0.
fonte