Je vois quelques grandes approches pour faire de l'ombrage cel:
- Duplication et agrandissement du modèle avec des normales inversées (pas une option pour moi)
- Approches de filtrage / fragment de Sobel pour la détection des contours
- Approches du tampon de gabarit pour la détection des contours
- Approches de shaders de géométrie (ou sommet) qui calculent les normales de face et d'arête
Ai-je raison de supposer que l'approche centrée sur la géométrie donne le plus grand contrôle sur l'éclairage et l'épaisseur des lignes, par exemple. pour un terrain où vous pourriez voir la ligne de silhouette d'une colline se fondre progressivement dans une plaine?
Et si je n'avais pas besoin d'un éclairage pixel sur mes surfaces de terrain? (Et je ne le ferai probablement pas, car je prévois d'utiliser un éclairage / ombrage basé sur les sommets ou les texturemap.) Serais-je alors préférable de m'en tenir à l'approche de type géométrique, ou opter plutôt pour une approche espace / fragment d'écran? pour garder les choses plus simples? Si oui, comment pourrais-je obtenir "l'encrage" des collines dans la silhouette de la maille, plutôt que seulement le contour de la maille entière (sans détails "d'encre" à l'intérieur de ce contour? (Contours suggestifs AKA , plis ).
Enfin, est-il possible d'émuler à moindre coût l'approche des normales inversées, en utilisant un shader de géométrie? Ce qui m'inquiète, c'est que je pourrais certainement dupliquer chaque sommet et les mettre à l'échelle en conséquence, mais comment pourrais-je aborder les normales de retournement et la coloration distincte dans le fragment shader?
Ce que je veux - une épaisseur de ligne variable avec des lignes intrusives à l'intérieur de la silhouette ...
Ce que je ne veux pas ...
EDIT: De nouvelles recherches ont révélé ce qui suit ...
Étant donné que le nombre de sommets sur le terrain est énorme, même en tenant compte de la LoD basée sur la distance, ni les normales inversées ni une approche basée sur un nuanceur de géométrie (même avec un tri sélectif) ne seraient une option raisonnable en raison de la complexité de calcul impliquée dans la duplication et la mise à l'échelle de tous sommets téléchargés.
Étant donné que je n'ai pas besoin d'un éclairage par pixel sous la forme d'un ombrage uni sur les surfaces du terrain, il devient également moins prudent de considérer toutes les approches basées sur la face normale - sinon une exigence pour un éclairage de surface correct - car celles-ci sont naturellement assez chers à calculer. Il est cependant vrai qu'ils donnent le meilleur degré de contrôle; par exemple, la possibilité d'ombrer les bords en utilisant des traits "artistiques": Magnifique, mais encore une fois, pas vraiment viable pour un environnement de jeu massivement complexe.
Je préfère éviter les tampons au pochoir car je préfère faire tout le travail dans les shaders. (L'exemple ci-dessus avec le contour rouge a été fait avec un tampon de pochoir - old school.)
Cela laisse des fragments d'espace image shader. La complexité de calcul est réduite au nombre de fragments plutôt qu'au nombre de sommets (dans mon cas, c'est 10 à 100 fois moins d'opérations que je n'aurais à faire dans le shader de géométrie). Cela nécessite plus d'un passage de rendu afin de générer un g-buffer (composé d'un tampon normal et éventuellement d'un tampon de profondeur également) auquel nous pouvons appliquer des filtres de discontinuité (par exemple, opérateur Sobel). La discontinuité de la profondeur est ce qui permet des contours et des plis évocateurs. Mon seul problème avec cette approche est l'incapacité à fournir un contrôle plus fin sur les largeurs de bords encrés, bien qu'avec le bon algorithme dans le fragment shader, je suis sûr que ce serait possible.
La question devient donc plus précise: comment pourrais-je exactement obtenir des largeurs de bord variables, en particulier sur la silhouette extérieure, dans un fragment shader?