Eu tenho tido muitos problemas ao tentar fazer com que uma função de mistura do OpenGL funcionasse como eu esperava, como o que eu esperaria (ou de qualquer programa de edição de imagem sensível). Como exemplo, usarei essas duas imagens para mesclar (um pouco difícil de ver em fundos brancos para que as cores sejam rotuladas):
Imagens a serem mescladas
É isso que espero que aconteça (e o que acontece no paint.net):
resultado esperado
Obviamente, a função de mistura padrão do opengl faz com que seja assim (muito errado):
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
Após uma tonelada de testes, este é o mais próximo que pude de criar uma função de mistura "boa":
glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
Porém, olhando para o resultado original esperado, você notará que algumas das cores são um pouco mais escuras do que deveriam (a parte central esquerda). Especificamente, eles são pré-multiplicados à metade de seu valor de cor (por causa do 0,5 alfa), e não consigo criar uma função que não faça isso (sem causar problemas de mistura estranhos com a parte transparente vermelha quase invisível).
Alguém conhece uma solução para esse problema? Uma que eu tinha era usar alfa pré-multiplicado nas fontes (embora eu não queira fazer isso porque exige trabalho extra para converter todas as cores que eu uso no meu jogo para pré-multiplicar ou apenas escrever algumas coisas em cada sombreador) e fazer assim :
glBlendFuncSeparate (GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA) (sem pré-multiplicação )
Obviamente, isso também está errado, mas este é realmente o único resultado correto que obtive até agora:
glBlendFuncSeparate (GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA) (entradas pré-multiplicadas)
O único problema é: como eu me livraria da pré-multiplicação para exibi-la na tela? Provavelmente, exigiria um ciclo de renderização adicional para cada coisa que eu misturar e isso parece muito complexo para esse problema, então ainda estou procurando uma resposta (é interessante que eu não consiga encontrar nada sobre isso, porque o OpenGL é tão amplamente usado que Eu imagino que alguém tenha encontrado esse problema).
Fontes:
Teste on-line da função de mistura - http://www.andersriggelsen.dk/glblendfunc.php
Imagem da camada inferior - http://i.stack.imgur.com/XjLNW.png
Imagem da camada superior - http: //i.stack.imgur .com / 9CN6w.png