Comment puis-je dire à un fragment shader de ne pas écrire un pixel particulier?

11

Dans un WebGL, j'aimerais envoyer un quadrillage d'espace d'écran qui est traité par un fragment shader, mais le fragment shader n'écrit un pixel que dans certaines conditions (disons ... qu'il était dans un cercle ou que le pixel appartenait au côté positif d'un demi-espace défini par une équation de courbe ou quelque chose).

Est-il possible dans un shader de fragment de dire "ne pas écrire de pixel"?

Je sais que cela pourrait être accompli en utilisant diverses autres méthodes comme le mélange alpha, le rendu en premier et le fait de mettre la couleur d'arrière-plan là où il ne veut pas dessiner un pixel, ou peut-être faire un tour avec les tampons de profondeur ou de pochoir. Je sais aussi que je pourrais créer un tas de géométrie pour correspondre à ce que je veux rendre.

Existe-t-il un moyen de faire en sorte que le shader de fragment choisisse de ne pas écrire de pixel du tout?

Alan Wolfe
la source

Réponses:

10

Oui, vous pouvez discarddans le fragment shader pour éviter d'écrire le pixel. Voici un exemple aléatoire que j'ai détourné de Google.

Notez que cela ne peut pas réellement arrêter le shader de fragments de traitement (car le GPU a tendance à traiter les fragments en blocs; seul le rejet de tous les fragments d'un bloc abandonnera le traitement). Mais le fragment ne sera pas écrit dans la sortie, ce qui est fondamentalement ce que vous voulez.

Vous pouvez être intéressé par cette questiondiscard connexe sur les performances de et celle-ci sur SO.

Je n'ai aucune idée si cela est pris en charge dans WebGL. Si ce n'est pas le cas, vous devrez revenir à l'une de vos suggestions (comme le mélange alpha; je pense que ce serait le plus simple).

Communauté
la source
3

La discarddéclaration est utile.

Vous n'avez pas trop parlé de votre chemin de décision, je vais donc vous proposer un exemple en utilisant une simple recherche de texture:

void main() {
    gl_FragColor = texture2D(u_texture, v_uv) * u_color;
    if (gl_FragColor.a <= 0.0) discard;
}

(C'est à partir d'un exemple de code que j'ai écrit avant d'apprendre le mélange alpha.)

rutter
la source