Dans Direct3D, les shaders multipass sont simples à utiliser car vous pouvez littéralement définir des passes dans un programme. Dans OpenGL, cela semble un peu plus complexe car il est possible de donner à un programme de shaders autant de vertex, de géométries et de shaders de fragments que vous le souhaitez.
Un exemple populaire de shader multipasse est un shader toon. Un passage fait l'effet cel-shading réel et l'autre crée le contour. Si j'ai deux vertex shaders, "cel.vert" et "outline.vert", et deux fragments shaders, "cel.frag" et "outline.frag" (similaire à la façon dont vous le faites dans HLSL), comment puis-je les combiner pour créer le shader toon complet?
Je ne veux pas que vous disiez qu'un shader de géométrie peut être utilisé pour cela parce que je veux juste connaître la théorie derrière les shaders GLSL multipass;)
Réponses:
Il n'y a pas de "théorie" derrière le multipass. Il n'y a pas de "shaders multipass". Le multipass est très simple: vous dessinez l'objet avec un seul programme. Ensuite, vous dessinez l'objet avec un programme différent .
Vous pouvez utiliser des éléments D3DX comme des fichiers FX pour masquer ces passes supplémentaires. Mais ils fonctionnent toujours de cette façon. OpenGL n'a tout simplement pas de cachette pour cela.
la source
Rendre l'objet avec le shader de cellule, puis le restituer avec le shader de contour.
la source
Dans OpenGL 4.0, il existe des sous-programmes uniformes . Ceux-ci vous permettent de définir des fonctions qui peuvent être échangées au moment de l'exécution avec très peu de surcharge. Vous pouvez donc créer 1 fonction pour chaque passe. Aussi 1 fonction pour chaque type de shader.
Il y a un tutoriel ici .
Pour les anciennes versions d'OpenGL, le mieux est d'avoir un tas de shaders différents et de les échanger. Sinon, vous pouvez additionner les valeurs que vous multipliez par un uniforme de 0,0 ou 1,0 pour l'activer ou le désactiver. Sinon, conditionnel si des instructions peuvent être utilisées, mais OpenGL exécutera tous les résultats possibles à chaque exécution / passage, alors assurez-vous qu'ils ne sont pas trop lourds.
la source
Il y a des gens qui connaissent beaucoup le GLSL, donc j'espère qu'ils viendront remettre les pendules à l'heure, mais d'après ce que j'ai vu, vous devriez pouvoir, dans votre fragment shader, faire quelque chose comme ça (pseudocode, je Je laisserai le GLSL réel aux personnes qui le connaissent mieux):
En utilisant
if
s de cette manière, vous obtenez quelque chose comme plusieurs passes. Cela a-t-il du sens?Edit: En outre, j'espère que cette question sur SO aide à dissiper certains malentendus.
la source