No Direct3D, os sombreadores multipass são simples de usar, porque você pode definir literalmente passes dentro de um programa. No OpenGL, parece um pouco mais complexo porque é possível fornecer a um programa de sombreador quantos shaders de vértice, geometria e fragmento desejar.
Um exemplo popular de um sombreador de várias passagens é um sombreador de toon. Uma passagem produz o efeito real de sombreamento e a outra cria o contorno. Se eu tiver dois shaders de vértice, "cel.vert" e "outline.vert", e dois shaders de fragmento, "cel.frag" e "outline.frag" (semelhante à maneira como você faz isso no HLSL), como posso combiná-los para criar o toon shader completo?
Não quero que você diga que um sombreador de geometria pode ser usado para isso, porque eu só quero conhecer a teoria por trás dos sombreadores GLSL multipass;)
Respostas:
Não há "teoria" por trás do multipass. Não há "shaders multipass". Multipass é muito simples: você desenha o objeto com um programa. Então você desenha o objeto com um programa diferente .
Você pode usar coisas do D3DX, como arquivos FX, para ocultar esses passes extras. Mas eles ainda funcionam dessa maneira. O OpenGL simplesmente não tem um esconderijo para isso.
fonte
Renderize o objeto com o sombreador de célula e, em seguida, renderize-o novamente com o sombreador de contorno.
fonte
No OpenGL 4.0, existem sub-rotinas uniformes . Isso permite definir funções que podem ser trocadas em tempo de execução com muito pouca sobrecarga. Então você pode fazer 1 função para cada passe. Também 1 função para cada tipo de sombreador.
Há um tutorial aqui .
Para versões mais antigas do OpenGL, sua melhor aposta é ter um monte de shaders diferentes e trocar entre eles. Caso contrário, você pode adicionar valores multiplicados por um uniforme igual a 0,0 ou 1,0 para ativá-lo ou desativá-lo. Caso contrário, as instruções se condicionais puderem ser usadas, mas o OpenGL executará todos os resultados possíveis a cada execução / aprovação, para garantir que eles não sejam muito pesados.
fonte
Existem algumas pessoas que sabem muito sobre o GLSL, então espero que elas consigam esclarecer as coisas, mas com base no que eu vi, você deve, no seu shader de fragmentos, fazer algo assim (pseudocódigo, eu deixará o GLSL real para as pessoas que o conhecem melhor):
Usando
if
s dessa maneira, você obtém algo como várias passagens. Isso faz sentido?Edit: Além disso, espero que esta pergunta sobre o SO ajude a dissipar alguns mal-entendidos.
fonte