2010-09-07 4 views
2

Existe-t-il un moyen rapide (pour la performance) de détecter dans glsl si un fragment a été multisamplé, mais dans un second passage (léger) en utilisant des textures où a été rendu 1ère passe. Ou comment opengl stocke-t-il des informations sur le multi-échantillonnage?Comment détecter dans glsl si un fragment est multi-échantillonné?

+1

Pourquoi voulez-vous détecter dans votre programme fragment GLSL? Il sera plus facile d'avoir deux shaders différents, un lorsque le multi-échantillonnage est activé et un autre lorsqu'il est éteint, donc pas besoin de le vérifier pendant le rendu, et pas de test de surcharge. – tibur

+0

Pour réduire l'utilisation de la mémoire dans le rendu différé. Quand le fragment est multi-échantillonné alors faites l'éclairage pour tous les échantillons, sinon pour un seul échantillon. – kravemir

Répondre

2

Ils sont plusieurs. L'habitude est de vérifier que les coordonnées du courant (gl_FragCoord) sont (0.5, 0.5). Si c'est le cas, cela signifie que vous êtes au milieu d'un polygone: il est échantillonné une seule fois.

Ce n'est pas, c'est probablement l'un des 4 (pour 4xMSAA) coins tournés-carrés: Vous êtes sur un bord, et openGL a détecté qu'un seul échantillon ne suffit pas.

Voir aussi http://www.opengl.org/pipeline/article/vol003_6/

Afin d'avoir ces informations dans une deuxième passe, vous devrez le stocker dans un g-tampon, cependant.

EDIT: Voici un extrait de code que je viens de faire. Testé sur gtx 470 avec une texture 4xMSAA 1024x1024.

Vertex shader:

#version 400 core 

uniform mat4 MVP; 
noperspective centroid out vec2 posCentroid; 

layout(location = 0) in vec4 Position; 

void main(){  
    gl_Position = MVP * Position; 
    posCentroid = (gl_Position.xy/gl_Position.w)*512; // there is a factor two compared to 1024 because normalized coordinates have range [-1,1], not [0,1] 
} 

shader Fragment:

#version 400 core 

out vec4 color; 
noperspective centroid in vec2 posCentroid; 

void main() 
{ 
    if (abs(fract(posCentroid.x) - 0.5) < 0.01 && abs(fract(posCentroid.y) - 0.5) < 0.01){ 
     color = vec4(1,0,0,0); 
    }else{ 
     color = vec4(0,1,0,0); 
    } 
} 

bords sont verts, centre de polygone est rouge.

Pour votre question initiale, je vous recommande cet article: http://www.gamasutra.com/view/feature/3591/resolve_your_resolves.php

+0

gl_FragCoord est la position [0, taille_de_cran]. J'ai essayé de détecter la position relative par ce code (vec2 a = gl_FragCoord.xy - plancher (gl_FragCoord.xy)! \t si (ax = 0,5 && ay = 0,5) \t \t gl_FragColor = vec4 (1,0 , 0,1); \t else { \t \t gl_FragColor = vec4 (0,1,0,1); \t}), mais il a fonctionne pas – kravemir

+0

C'est normal. Vous devez utiliser un centroïde variable (gl_FragCoord n'est pas centroïde). Je dois vérifier cela, je reviendrai à vous quand je sais comment le faire. – Calvin1602

+0

@Miro http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=277450 Donc quelque chose comme: VS -> hors centroid fragcoord; main() {fragcoord = MVP * in_Position; fragcoord.xy/= fragcoord.w;} et FS -> ce que vous avez fait, mais avec fragcoord – Calvin1602

-1

Le multi-échantillonnage est activé lors de la création du contexte lors du choix du format de pixel. Après cela, vous ne pouvez pas l'éteindre ou le rallumer. Mais lorsque vous restituez une texture, OpenGL n'utilisera pas le multi-échantillonnage quel que soit le paramétrage du contexte.

http://www.opengl.org/wiki/Multisampling

+0

OpenGL prend en charge le multi-échantillonnage à la texture, il existe des formats de texture multi-échantillonnés. chceck nouvelles versions :) – kravemir

+0

Oh, aurait dû figurer dans une extension séparée :) (GL_EXT_framebuffer_multisample) – Daniel

Questions connexes