Como posso criar um efeito de brilho?

9

Estou tentando criar um efeito brilhante para meu shader em tempo real, mas não sei como.

Aqui está um exemplo e outro exemplo .

insira a descrição da imagem aqui

Que técnica posso usar para implementar isso?

Esteira
fonte
Isso poderia ser conseguido através de um efeito pós-processo, semelhante ao bloom, mas aplicando um padrão (uma textura em estrela) à fase de amostra abaixo. Isso tudo é apenas especulação difícil.
precisa saber é
11
Um mapa normal e especular não o deixaria fazer isso através de uma textura?
JohnB
Fiz alguns testes usando o mapa normal. Mas o mais difícil é fazê-los brilhar de acordo com a orientação da vista e a orientação da luz.
MAT

Respostas:

10

Bem, quando nos pedem para projetar qualquer sombreador, devemos começar dividindo as coisas em problemas menores. E, como se observa, o efeito brilhante na verdade não faz o shader parecer bom, mas a iluminação e o efeito geral, usando apenas um deles, não parecerão tão bons.

Antes de tudo, vamos declarar o que não faz parte diretamente do shader:

  1. O sombreamento não faz parte do sombreador e é feito através de um passe de sombreamento separado.
  2. Eu supor que há oclusão de ambiente (especialmente que essa imagem mostrada na questão particularmente não está usando processador de tempo real, mas isso é uma suposição).

Em segundo lugar, vamos dividir o shader real em efeitos separados:

  1. Há uma iluminação anisotrópica, isso é muito essencial para a aparência geral do shader. A razão por trás disso é que o material real contém tecidos, esses tecidos brilhantes fazem com que a reflexão da luz tenha um viés direcional, gerando a maior quantidade de luz refletida nessa determinada direção.

insira a descrição da imagem aqui

insira a descrição da imagem aqui Observe que esses tecidos têm infinitas normais normais, mas a técnica descrita aqui aproxima o padrão normal mais significativo

A fim de aproximar o, uma forma normal mais significativo para o fazer, é a utilização de coordenadas de textura e tangentes calcular da malha, e em vez de calcular N . L você calcula 1- (NT).

Explicação completa aqui . E você provavelmente precisará implementar isso no shader de fragmentos, em vez da técnica de vértice sobre a qual eles falam. Outros modelos anisotrópicos também podem ser aplicados.

Agora, para o efeito brilhante:

Isso pode ser feito no espaço mundial / espaço local de textura ou no espaço da tela como um passe separado.

O algoritmo em que consigo pensar usa a técnica de processamento de imagem (assumindo que a malha tenha cordas de textura).

  • Gere um ruído 2D de alta frequência na superfície da malha usando suas coordenadas de textura; o ruído permanente parece um bom candidato.
  • Aplique um filtro máximo usando o núcleo 3x3 no ruído. Isso gerará um efeito semelhante à imagem abaixo e o filtro máximo é descrito aqui .

insira a descrição da imagem aqui

Observe que a imagem acima é apenas um exemplo do filtro máximo, e aplicá-lo no ruído fornecerá sth semelhante a um campo estrela.

  • Depois de fazer isso, aplique um filtro gaussiano com certo desvio no ruído para obter a forma de estrela.

insira a descrição da imagem aqui

Exemplo de filtro gausiano aplicado ao ruído máximo (ed).

  • O passo final é combinar isso com textura de malha original e luz. É melhor fazer isso usando uma operação binária (|) ou com a textura / cor da malha original, isso retira apenas o branco do ruído e remove os pixels pretos. Em relação à luz (e possivelmente a outros mapas especulares), a melhor coisa a fazer é adicioná-la ou modulá-la com os pixels combinados anteriormente. Você também pode precisar de um efeito de pós-processamento de brilho para obter um brilho melhor.

Observe que essa técnica pode precisar de otimização significativa para um sombreador em tempo real.

concept3d
fonte
3

Há um artigo interessante AMD - Obtendo procedimentos .

Parece que os brilhos são mais difíceis do que eu penso.
Solução decente: use a posição 3D para indexar a função de ruído 3D, adicione o vetor de visualização, use a função frac para randomizar ainda mais as coisas.

Sparkle:
float specBase = saturate(dot(reflect(-normalize(viewVec), normal),
lightDir));
// Perturb a grid pattern with some noise and with the view-vector
// to let the glittering change with view.
float3 fp = frac(0.7 * pos + 9 * Noise3D( pos * 0.04).r + 0.1 * viewVec);
fp *= (1 - fp);
float glitter = saturate(1 - 7 * (fp.x + fp.y + fp.z));
float sparkle = glitter * pow(specBase, 1.5);
Esteira
fonte