Como pintar em modelos 3D

Sep 17 2020

Tenho pesquisado este tópico por muito tempo e basicamente não encontrei nenhuma informação sobre ele.

Se tivermos um modelo 3D com um layout uv. Qual é a técnica básica para pintura 3D no referido modelo com um pincel? Uma pincelada consiste nos dados / imagem de pixel do pincel dispostos em sucessão. Portanto, projetamos cada imagem de pincel individual na superfície do objeto? (Embora na realidade, para fazer isso, estaríamos projetando o objeto no espaço da imagem). Já consegui projetar texturas em objetos antes. E projetar cada imagem de pincel individual definitivamente parece viável, mas não tenho certeza se é prático do ponto de vista de desempenho e se há técnicas melhores.

Respostas

1 wychmaster Sep 18 2020 at 15:18

Não posso dar uma abordagem "melhor" aqui, mas acho que a abordagem

projete cada imagem de pincel individual na superfície do objeto

não é realmente um problema de desempenho se você implementar isso usando a GPU. Especialmente em um ambiente de editor, onde não há muita coisa acontecendo em comparação a um jogo de computador. Tudo o que você basicamente deseja fazer é renderizar uma única imagem por quadro em um conjunto limitado de texturas. Posso dar um rascunho de como abordaria o assunto se precisasse desse recurso. No entanto, como ainda não o implementei, pode haver algumas complicações e problemas nos quais não pensei, portanto, avise-me nos comentários se algo não funcionar como esperado.

  1. Encontre as superfícies afetadas

    • Use os cantos de sua textura de pincel e gere um tronco de projeção de pincel reduzido
    • Verifique todos os objetos contra ele e encontre as superfícies mais próximas -> Se você já usa algum tipo de seleção para sua cena, reutilize a lista de objetos já selecionados, uma vez que o pincel só pode "ver" o que a câmera vê
    • Identifique as subsuperfícies / triângulos afetados pelo pincel
  2. Reúna todas as texturas afetadas. Você deve saber, para cada superfície afetada, qual textura ela possui. Idealmente, todo o seu objeto tem apenas uma única textura UV.

  3. Crie um programa de sombreador para renderizar em sua textura.

    • tenha cuidado, o sombreador de vértice tem que calcular as coordenadas UV normalizadas e passá-las para baixo no pipeline como a posição do vértice, uma vez que são a posição em sua textura. Verifique quais informações adicionais você precisa para passar pelo pipeline.
    • No sombreador de fragmento, substitua cada pixel que está sob o pincel. Você pode precisar usar mistura aqui para pincéis não retangulares.
    • A posição da escova é um pouco complicada. Você precisa dele no espaço UV das texturas no shader de fragmento e não tenho certeza se você pode calculá-lo no shader de vértice. Portanto, pode ser necessário fazer isso no shader de fragmento ou, alternativamente, em um shader de geometria. O problema que vejo é que o ângulo em que a projeção do pincel atinge a superfície não pode ser calculado no sombreador de vértice e é necessário determinar a área coberta. O sombreador de geometria tem informações suficientes para calcular o ângulo e a área coberta. No shader de fragmento, você também não pode calcular o ângulo, mas pode simplesmente verificar se e onde ele está localizado no tronco de projeção do pincel.
  4. Agora simplesmente renderize de acordo com suas texturas.

    • Vincule sua textura de pincel
    • Para cada textura afetada
      • Vincule a textura como alvo de renderização
      • Renderize todos os objetos afetados e deixe a GPU decidir quais pixels precisam ser substituídos.
  5. (Opcional) Se você quiser salvar suas modificações, você precisa ler as texturas da GPU e salvá-las.

Como o trabalho principal é feito pela GPU, deve ser bastante rápido. No entanto, posso ver alguns problemas com a abordagem descrita quando o pincel atinge vários objetos / texturas que estão parcialmente sobrepostos. Classificar qual pixel do pincel afeta qual textura / objeto pode ficar confuso. Pode haver alguns truques de estêncil / buffer de profundidade que podemos aplicar, mas acho que esse é um assunto para outra pergunta.

1 Thomas Sep 18 2020 at 15:13

Desde que nenhum pixel na textura seja usado duas vezes, você pode renderizar a geometria e exibir as coordenadas uv (coordenadas de textura). Normalmente, eles são uma combinação de vermelho e verde (2d). Ao usar um pincel, você só precisa ler as coordenadas uv que atingiu e colorir a textura na posição (uv) na cor desejada.

Dica: pinte em uma segunda textura, para não destruir a cor da textura original.

Desvantagens: às vezes, a resolução da textura de diferentes triângulos em uma geometria varia. Portanto, em alguns rostos ficará bonito e em outros será pixelado.

Como dito antes, se a malha (geometria) usa a mesma parte de uma textura duas vezes (duas faces visando as mesmas coordenadas de textura), e você desenha em uma delas, a outra também será pintada.

the1bird Sep 17 2020 at 07:19

Você poderia fazer isso de maneiras diferentes.

Mas a forma mais lógica para mim é que existem pontos amostrados ao longo do caminho, então splines / curvas de benzier são usados ​​para torná-lo suave (pontos adicionais podem ser interpolados), depois disso é projetado e salvo na textura. Portanto, nenhum ponto "todo" precisa ser amostrado.