J'ai une certaine expérience en programmation de géométrie et de calcul de shaders - mais je ne me suis jamais aventuré en jouant vraiment avec les shaders de fragments. Actuellement, j'essaie de mieux comprendre comment ils fonctionnent et leur potentiel. L'une des choses que j'ai lues à plusieurs endroits est qu'un fragment (c'est-à-dire un pixel d'écran) ne peut pas s'étendre au-delà de lui-même dans le fragment shader. Ce qui signifie qu'un fragment donné en cours d'itération ne peut qu'affecter lui-même.
Par conséquent, et dans un souci d'apprentissage, je voudrais savoir si ce qui suit est possible (et si c'est le cas, comment, en termes généraux, peut-il être réalisé). Supposons que nous ayons, par souci de simplicité, un maillage ponctuel composé de seulement deux sommets (situés dans l'espace 3D World). Pouvons-nous programmer un shader de telle sorte que chacun de ces deux sommets soit peint à l'écran à leur position exacte WorldToViewport, mais aussi qu'un cercle autour de chacun d'eux de rayon = R soit également peint dans les pixels environnants même s'ils s'étendent au-delà du maillage d'origine auquel le shader est attaché? Comme dans la figure ci-dessous (où le carré rouge au centre des cercles représente les sommets peints à l'écran):
Si cela est possible, un shader peut-il également être programmé de telle manière que ces cercles qui s'étendent au-delà des sommets influencent la couleur (RGBA) les uns des autres? Comme dans la figure ci-dessous:
Comme je l'ai dit, si ce sont des choses possibles, j'aimerais savoir un peu comment y parvenir - en termes conceptuels ou pratiques. Est-ce fait dans le shader de fragment, ou doit-il être calculé avant au shaders de vertex ou de géométrie? Comment calculer et passer des "fragments supplémentaires" qui s'étendent au-delà des fragments occupés par le corps maillé?
la source
Réponses:
Lorsque vous utilisez la largeur de ligne ou l'anticrénelage de ligne ou la largeur de point ou les pointsprites, OpenGL crée pour vous un petit rectangle au lieu de la ligne ou du point, avec des coordonnées de texture. De nos jours, vous pouvez même le programmer vous-même en utilisant des shaders de géométrie ou même le tesselator.
Une approche totalement différente consiste à utiliser un ombrage différé, en utilisant un passage géométrique juste pour stocker des informations dans le tampon RGBAZ, puis un deuxième passage que vous exécutez sur tous les pixels de l'écran pour effectuer un processus. (pour agir sur tous les pixels, dessinez simplement un rectangle plein écran). De nos jours, vous pouvez même faire le premier passage comme un ou plusieurs "rendre à la texture", puis MIPmap ces textures, de sorte que le passage final puisse facilement accéder à moins de valeurs locales.
la source
Une bonne façon d'organiser le tracé d'un cercle (ou d'une autre forme) pour chaque sommet d'un maillage consiste à utiliser l' instanciation de la géométrie . Il s'agit d'une fonction GPU qui permet de dessiner plusieurs instances (copies) d'un maillage à la fois, avec les sommets / indices du maillage donnés par un ensemble de tampons et un autre tampon de sommet qui peut fournir des données supplémentaires par instance. Le vertex shader peut être utilisé pour combiner les données des deux tampons de la manière que vous choisissez.
Pour être concret, dans votre cas, vous pouvez créer un maillage représentant un cercle du rayon souhaité, avec ses sommets spécifiés directement en coordonnées d'écran et centrés à l'origine. Ensuite, vous utiliseriez l'instanciation pour que le GPU rende une nouvelle copie du maillage circulaire pour chaque sommet de votre maillage ponctuel d'origine. Dans le vertex shader, vous calculez la position d'espace d'écran du point (en utilisant les transformations de vision du monde comme d'habitude), puis vous traduisez le maillage du cercle pour qu'il soit centré à cette position.
Quant à la deuxième partie de votre question, sur la façon dont les cercles s'influencent mutuellement: cela dépend de ce que vous voulez faire, en particulier. Le mélange de matériel peut être utilisé pour gérer des cas simples, tels que l'ajout ou la multiplication des couleurs, ou le mélange alpha. Si vous voulez quelque chose de plus compliqué que cela, alors il pourrait être possible de le faire avec un algorithme multi-passes ou (sur les derniers GPU) un mélange programmable.
la source