[Tutorial] Blend Modes

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

[Tutorial] Blend Modes

Mensagem por saim em Qua 29 Jun 2011, 15:44

Nome: Desmistificando os blend modes
Descrição: Esse tutorial é uma mera tradução do tutorial encontrado na gmlspcripts, elaborado por Xot. Obviamente, a imagem não está traduzida. Como foi muito útil pra mim, suponho que seja útil pros demais membros da comunidade. Antes de ler, sugiro ler meus tutoriais sobre surfaces e, principalmente, o de cores, pois fiz ambos apenas como preâmbulo pra esse aqui. Não é necessário ler, mas é recomendável.
Nível de dificuldade: mediano
Requerimentos: GM 7/8 - Pro. Acredito que em versões anteriores também se aplique.
Desenvolvimento: Vamos lá.


Sobre Modos de Mistura (Blend Modes)

Manual escreveu:Existem mais duas funções que não são úteis apenas para desenhar texturas. Normalmente, primitivas são mescladas ao fundo usando o valor de alpha. Na verdade, você pode indicar como isso deve ocorrer. Além do modo normal, é possível indicar que a nova cor deve ser somada à cor existente ou subtraída da cor existente. Isso pode ser usado pra criar, por exemplo, holofotes ou sombras. Também é possível, tipo, escolher o máximo entre a nova cor e a cor existente. Isso pode evitar alguns efeitos de saturação que você consegue com adição. Note que tanto a subtração quanto o máximo não levam o valor de alpha totalmente em conta. (DirectX não permite isso.) Então é melhor você garantir que a área externa esteja preta. Existem duas funções. A primeira te dá apenas as quatro opções descritas acima. A segunda te dá muito mais possibilidades. Você deveria experimentar um pouco com as configurações. Se use usadas efetivamente, elas podem ser usadas pra criar, por exemplo, interessantes efeitos de explosão ou de halo.

NOTA: Blend modes (Modos de mistura) não têm efeito nas funções draw_clear ou draw_clear_alpha. Dizer que algus modes "não levam o valor de alpha totalmente em conta" parece um pouco enganador. A forma que alpha é levada em conta simplesmente pode não ser o que o usuário deseja ou espera.

Blending Padrão


Manual escreveu:draw_set_blend_mode(modo) Indica que modo de mistura será usado. Os seguintes valores são possíveis: bm_normal (0), bm_add (1), bm_subtract (3), and bm_max (2). Não se esqueça de resetar o mode para o normal depois do uso, porque de outra forma, os outros sprites e até os backgrounds serão desenhados no novo modo de mistura.

NOTA: As quatro constantes de modos de mistura devem ser usadas apenas nessa função.

Mistura Extendida


Manual escreveu:draw_set_blend_mode_ext(fonte, destino) Indica qual modo de mistura usar para a cor da fonte e do destino. A nova cor é um tanto vezes a cor da fonte e outro tanto vezes a cor do destino. Esses tantos são definidos com essa função. Para entender isso, a fonte e o destino têm um componente vermelho, verde, azul e alpha. Então a fonte é (Vmf, Vdf, Azf, Alf) e o destino é (Vmd, Vdd, Azd, Ald). Todos são considerados como variando de 0 a 1. Os fatores de mistura que você pode escolher para a fonte e o destino são:

    1. bm_zero: o fator de mistura é (0, 0, 0, 0).
    2. bm_one: o fator de mistura é (1, 1, 1, 1).
    3. bm_src_color: o fator de mistura é (Vmf, Vdf, Azf, Alf).
    4. bm_inv_src_color: o fator de mistura é (1–Vmf, 1–Vdf, 1–Azf, 1–Alf).
    5. bm_src_alpha: o fator de mistura é (Alf, Alf, Alf, Alf).
    6. bm_inv_src_alpha: o fator de mistura é (1–Alf, 1–Alf, 1–Alf, 1–Alf).
    7. bm_dest_alpha: o fator de mistura é (Ald, Ald, Ald, Ald).
    8. bm_inv_dest_alpha: o fator de mistura é (1–Ald, 1–Ald, 1–Ald, 1–Ald).
    9. bm_dest_color: o fator de mistura é (Vmd, Vdd, Azd, Ald).
    10. bm_inv_dest_color: o fator de mistura é (1–Vmd, 1–Vdd, 1–Azd, 1–Ald).
    11. bm_src_alpha_sat: o fator de mistura é (f, f, f, 1); f = min(Alf, 1–Ald).

Por exemplo, o modo de mistura normal define a mistura da fonte para bm_src_alpha e a do destino para bm_inv_src_alpha. Não se esqueça de resetar o mode para o normal depois do uso, porque de outra forma, os outros sprites e até os backgrounds serão desenhados no novo modo de mistura.

NOTA: As onze constantes de modos de mistura devem ser usadas apenas nessa função. Saber esses valores é útil quando consertando códigos que não usa as constantes corretas pra uma função de mistura em particular.


Como os Modos de Mistura funcionam

"Extended blend modes" - Modos de mistura extendidos - são a fonte de mais mistério que quase qualquer coisa no arsenal do Game Maker. Na verdade, eles são completamente lógicos e bastante diretos. Assim que você entender como eles operam, você não terá problemas em predizer o que qualquer modo de mistura particular fará.

É tudo matemático. O uso do termo "factor" (fator) no arquivo de ajuda é a pista, mas não chega perto de ser suficientemente detalhado.

Cada modo de mistura extendido tem dois fatores, definidos pelos dois argumentos da função draw_set_blend_mode_ext. O primeiro fator é para os pixels sendo desenhados (a fonte - source) e o segundo é para o pixel existente (o destino - destination). O pixel da fonte pode vir de qualquer comando de desenho, tais como desenhar sprites ou primitivas. Os pixels do destino podem ser o buffer de fundo (a tela) ou uma surface definida.

Para as misturas, os canais de cor (VerMelho, VerDe e AZul) são considerados como variando desde 0.0 até 1.0, ao invés de desde 0 até 255.

Vamos começar com mistura normal, o modo de mistura default do Game Maker:

Código:
Código:
draw_set_blend_mode_ext(bm_src_alpha, bm_inv_src_alpha);
Olhando na tabela acima:
bm_src_alpha:o fator de mistura é (Alf, Alf, Alf, Alf).
bm_inv_src_alpha:o fator de mistura é (1–Alf, 1–Alf, 1–Alf, 1–Alf).

A tabela diz que o fator de mistura de bm_src_alpha é (Alf, Alf, Alf, Alf). O que isso quer dizer? Que cada um daqueles quatro valores ("Alf") representa o fator pra cada canal de cor (VerMelho, VerDe, AZul, ALpha). O fator "Alf" significa o Alpha do pixel da Fonte. As duas primeiras letras (apenas uma, no manual) se referem ao canal de cor e a terceira (segunda, no manual) se refere aos pixels da fonte ou do destino. Por "fator" queremos dizer multiplicação; nós multiplicaremos cada canal de cor do pixel da fonte por esse fator.

Semelhantemente, faremos o mesmo tipo de operação para os pixels de destino, só que usando o fator bm_inv_src_alpha (1-Alf), no lugar. Quando um fator tem "inv" (inverso) no nome, quer dizer que ele subtrai o canal indicado de um (assim, claro vira escuro e escuro vira claro).

O resultado dessas duas operações são então adicionados para formar a imagem final.

Aqui está toda a operação de mistura normal expressa matematicamente:
FonteDestinoResultado
PixelsPixelsPixels
[Vmf]*[Alf]+[Vmd]*[1-Alf]=novo vermelho
[Vdf]*[Alf]+[Vdd]*[1-Alf]=novo verde
[Azf]*[Alf]+[Azd]*[1-Alf]=novo azul
[Alf]*[Alf]+[Ald]*[1-Alf]=novo alpha

...e visualmente:



O que está acontecendo é que a alpha da sprite está sendo usada pra (1) apagar o fundo da srpite do Mario e (2) apagar a área na imagem existente onde o Mario vai aparecer. Quando essas imagens forem combinadas, não haverá iteração entre as duas. Os elementos isolados vão encaixar perfeitamente. Obviamente, esse é um modo de mistura muito útil para jogos, por isso é o default. Aqui está um exemplo da matemática em ação. Digamos que o pixel que estamos desenhando é o da camisa vermelha do Mario (#F84070) sobre um fundo marrom (#C89858). Já que é uma parte do Mario, sabemos que o alpha é 100% pra esse pixel. O fundo também é totalmente opaco.
FonteDestinoResultado
PixelsPixelsPixels
[0xF8]*[1.00]+[0xC8]*[1-1.00]=novo vermelho
[0x40]*[1.00]+[0x98]*[1-1.00]=novo verde
[0x70]*[1.00]+[0x58]*[1-1.00]=novo azul
[1.00]*[1.00]+[1.00]*[1-1.00]=novo alpha
[0.97]*[1.00]+[0.78]*[0.00]=0.97
[0.25]*[1.00]+[0.60]*[0.00]=0.25
[0.44]*[1.00]+[0.35]*[0.00]=0.44
[1.00]*[1.00]+[1.00]*[0.00]=1.00
(#F84070)

O pixel resultante é da cor da camisa. Não é surpresa, eu sei, mas a matemática mostra o porquê. Agora, o que acontece quando o Mario não está totalmente opaco? Vamos tentar seu macacão azul (#408098) num alpha de 60% sobre o mesmo fundo.
[0.25]*[0.60]+[0.78]*[0.40]=0.46
[0.50]*[0.60]+[0.60]*[0.40]=0.54
[0.60]*[0.60]+[0.35]*[0.40]=0.50
[0.60]*[0.60]+[1.00]*[0.40]=0.76
(#75897F)

Conforme esperado, temos uma mistura das duas cores, um tipo de cinza-esverdeado. Note, em particular, o alpha resultante: 0.76. Normalmente, quando desenhando sobre o buffer de fundo, isso é ignorado. A janela do jogo é sempre 100% opaca, afinal. Entretanto, quando desenhando sobre uma surface, isso é extremamente importante. Se fôssemos repetir a última operação numa surface, os pixels resultantes, onde quer que desenhássemos o Mario transparente, iria de fato ficar parcialmente transparentes. Apesar de que esse efeito possa parecer uma estranha zica gráfica, é perfeitamente normal. Pode ser corrigido com operações de misitura adicionais. Faremos isso da próxima vez com algumas misturas "aditivas".

Nosso destino do desenho é uma surface, o resultado da operação anterior. Como notado, alguns pixels ficaram transparentes. Para restaurar a opacidade total, nós vamos desenhar sobre eles com preto. Como o mode de mistura que usaremos simplesmente soma duas cores juntas, e porque preto tem um valor de 0 para VerMelho, VerDe e AZul, isso não vai alterar de modo algum as cores do destino (n+0=n). O ALpha, entretanto, é igual a 1.0, totalmente opaco. Adicionar isso ao alpha existente garantirá que o resultado será, pelo menos, igual a 1.0. Valores acima de 1.0 (ou abaixo de 0.0) são cortados. O fator de mistura que nós usaremos é chamado bm_one (bm_um) que, como você deve ter adivinhado, é igual a 1.0 na equação de mistura. Nós o usaremos tanto para os pixels da fonte quanto para os do destino. O modo básico bm_add (bm_soma) trabalha de forma similar (mas não idêntica).

FonteDestinoResultado
PixelsPixelsPixels
[0.00]*[1.00]+[0.46]*[1.00]=0.46
[0.00]*[1.00]+[0.54]*[1.00]=0.54
[0.00]*[1.00]+[0.50]*[1.00]=0.50
[1.00]*[1.00]+[0.76]*[1.00]=1.00 (cortado de 1.76)
(#75897F)

A cor permanece a mesma, mas agora o pixel está totalmente opaco.

Até agora, todos os modos de mistura mostrados têm fatores que são os mesmo para todos os canais de cores. Não é necessariamente assim. Os fatores de mistura com a palavra "color" (cor) neles têm fatores diferentes pra cada canal. Um uso comum pra eles é em engines de iluminação, os chamados de passagem de luz/textura "multiplicativa". A idéia é desenhar o tom primeiro, então as texturas para os objetos iluminados com uma mistura multiplicativa. As cores na fonte serão multiplicadas pelas cores do destino. Áreas com tons brancos mostrarão a textura normalmente, áreas com tons coloridos vão pintar a textura, áreas com tom preto permanecerão pretas. Você pode ver o mesmo efeito quando usa a variável image_blend pra mudar a cor de uma instância. Os fatores de mistura que usaremos são bm_dest_color e bm_zero.

FonteDestinoResultado
PixelsPixelsPixels
[Vmf]*[Vmd]+[Vmd]*[0.00]=novo vermelho
[Vdf]*[Vdd]+[Vdd]*[0.00]=novo verde
[Azf]*[Azd]+[Azd]*[0.00]=novo azul
[Alf]*[Ald]+[Ald]*[0.00]=novo alpha

Se a cor da fonte é lilás (#C8A2C8) e os pixels do destino são de açafrão intenso(#FF9933):

[0.90]*[1.00]+[1.00]*[0.00]=0.90
[0.64]*[0.60]+[0.60]*[0.00]=0.38
[0.90]*[0.20]+[0.20]*[0.00]=0.18
[1.00]*[1.00]+[1.00]*[0.00]=1.00
(#E6602E)

...o resultado é uma cor acobreada, escurecida. Leitores observadores notarão que o modo de mistura (bm_dest_color, bm_zero) é exatamente o mesmo que (bm_zero, bm_src_color).

Agradecimentos: Ao Xot, obviamente, que postou o tutorial original e ao Lucas Lunar, que postou o tutorial sobre formatação


Última edição por saim em Qui 07 Jul 2011, 16:18, editado 2 vez(es)

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: [Tutorial] Blend Modes

Mensagem por PedroX em Qui 30 Jun 2011, 20:12

Seu tutorial está muito bom.
Esse é um tutorial de alta qualidade.
E claro, cheio de coisas itenteressantes.

Queria saber sobre uma coisa. Uma vez eu simulei um 'balde de tinta' igual ao do mspaint, com objetos para cada pixel. Isso trouxe resultados satisfatórios, mas apresentou um bug (não muito grave), além de ficar lento.

Enfim, queria saber se é possivel desenhar por cima dos pixels que o balde pintaria, ou seja, pintar os pixels, ignorando os de outras cores, através de blend modes, usando as funções de alpha ou qualquer outra.

Até mais!

PedroX

Ranking : Nota C
Número de Mensagens : 6034
Idade : 21
Data de inscrição : 26/07/2008
Notas recebidas : C+B
Reputação : 286
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: [Tutorial] Blend Modes

Mensagem por saim em Sex 01 Jul 2011, 10:23

Pedro Henrique escreveu:Seu tutorial está muito bom.
Esse é um tutorial de alta qualidade.
E claro, cheio de coisas itenteressantes.
Eu achei ele sensacional! Tanto que tive o trabalho de traduzi-lo. Quem me dera ter capacidade de escrever algo assim por conta própria...

Pedro Henrique escreveu:Queria saber sobre uma coisa. Uma vez eu simulei um 'balde de tinta' igual ao do mspaint, com objetos para cada pixel. Isso trouxe resultados satisfatórios, mas apresentou um bug (não muito grave), além de ficar lento.

Enfim, queria saber se é possivel desenhar por cima dos pixels que o balde pintaria, ou seja, pintar os pixels, ignorando os de outras cores, através de blend modes, usando as funções de alpha ou qualquer outra.
Olha, os blend modes servem pra misturar (e uso "misturar", aqui num sentido bem amplo) as cores, eles são aplicados em áreas definidas pelo usuário. Acho difícil encontrar um método que se aplique isoladamente a uma cor específica a ser escolhida a qualquer momento e que, ainda por cima, não se aplique à mesma cor em outras áreas. Claro que é possível usar alguns efeitos que só aparecem sobre certas condições, mas um balde do mspaint me parece bem complicado de se fazer sem usar o draw_getpixel. Uma vez usado, o draw_getpixel, fica tranquilo de continuar ao longo do desenho repetindo: "se o pixel é da cor tal, mudar pra outra cor e checar os pixels adjacentes, de outra forma, não faz nada", mas isso é lento - talvez não tão lento quanto usar um objeto por pixel, mas ainda assim é lento.
Só que isso tem mais a ver com surfaces do que com blending, então respondendo à sua pergunta, acho que não é possível usar blending pra simular o balde.
Vou tentar alguns testes, aqui, e te aviso se conseguir alguma coisa.

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: [Tutorial] Blend Modes

Mensagem por Isaque Onix em Qui 04 Jul 2013, 15:21

olá Saim, tentei criar um sistema de 'luz' com surface, um sprite com um Gradiente (daqueles em forma de circulo, sendo que nas pontas preto e no centro branco) e tentei os 2 tipos de Blend Modes, e com todas as combinações possiveis, mais não consegui, tem como fazer isso? se tem, e você souber, poderia me dizer? Grato pela atenção!

Isaque Onix

Número de Mensagens : 1597
Idade : 23
Data de inscrição : 15/08/2010
Reputação : 147
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

http://spyreserver.16mb.com

Voltar ao Topo Ir em baixo

Re: [Tutorial] Blend Modes

Mensagem por w&sl&y em Sex 05 Jul 2013, 08:49

pó esta muito bom valeu mesmo

w&sl&y

Ranking : Nota D
Número de Mensagens : 60
Idade : 17
Data de inscrição : 30/06/2013
Notas recebidas : D
Reputação : 2
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: [Tutorial] Blend Modes

Mensagem por Conteúdo patrocinado Hoje à(s) 16:02


Conteúdo patrocinado


Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum