Le fragment de fragment OpenGL ES 2.0 à flouter est lent et de mauvaise qualité

J'essaye d'écrire un shader de flou pour l'iPad. Je l'ai fonctionné mais je ne suis pas très heureux des résultats. Je reçois des fréquences d'images très agitées et le flou ressemble à de la merde lorsque le flou est trop élevé.

Des idées sur la façon d'améliorer les choses?

Quelques exemples de sortie:

texte alt

uniform sampler2D texture; varying mediump vec2 fragTexCoord; varying mediump vec3 eyespaceNormal; varying highp float blurAmount; void main(void) { highp vec2 gaussFilter[7]; gaussFilter[0] = vec2(-3.0, 0.015625); gaussFilter[1] = vec2(-2.0, 0.09375); gaussFilter[2] = vec2(-1.0, 0.234375); gaussFilter[3] = vec2(0.0, 0.3125); gaussFilter[4] = vec2(1.0, 0.234375); gaussFilter[5] = vec2(2.0, 0.09375); gaussFilter[6] = vec2(3.0, 0.015625); highp float blurSize = blurAmount * 1.0; ///////////////////////////////////////////////// // 7x1 gaussian blur fragment shader ///////////////////////////////////////////////// highp vec4 color = vec4(0,0,0,1); for( int i = 0; i < 7; i++ ) { color += texture2D( texture, vec2( fragTexCoord.x+gaussFilter[i].x*blurSize, fragTexCoord.y+gaussFilter[i].x*blurSize ) )*gaussFilter[i].y; } gl_FragColor = color; } 

Edit: Une boîte de flou peut être le path à parcourir. Voici une version en boîte de flou du shader:

 highp vec4 color = vec4(0,0,0,1); color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 4.0*blurAmount)) * 0.05; color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 3.0*blurAmount)) * 0.09; color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 2.0*blurAmount)) * 0.12; color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - blurAmount)) * 0.15; color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y)) * 0.16; color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + blurAmount)) * 0.15; color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 2.0*blurAmount)) * 0.12; color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 3.0*blurAmount)) * 0.09; color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 4.0*blurAmount)) * 0.05; gl_FragColor = color; 

Voici la sortie du flou de la boîte (notez que c'est seulement un flou horizontal, mais cela pourrait suffire pour ce que je veux): texte alt

Ce shader doit fonctionner deux fois pour que ça fonctionne, ce que vous appelez blurSize devrait être vec2 et la valeur de vec2(0, 1.0/height) devrait être vec2(0, 1.0/height) pour le flou vertical et vec2(1.0/width, 0) pour le flou horizontal.

Voir http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=240334

L'idée de faire un flou à deux passages est de réduire considérablement le nombre de searchs de texture et, espérons-le, d'augmenter la vitesse. Un flou de deux passes avec une taille de kernel de 7×7 nécessitera 14 searchs de texture, mais si cela se fait dans une boucle nestede, vous devrez effectuer 49 searchs de texture.

Faire deux ou plusieurs passages de flou de boîte améliore la qualité à un flou gaussien très proche tout en gardant des performances relativement élevées. Et les brouillages de boîte peuvent être accélérés aussi facilement. Jetez un oeil à http://web.archive.org/web/20060718054020/http://www.acm.uiuc.edu/siggraph/workshops/wjarosz_convolution_2001.pdf

Dans tous les cas, dans la plupart des scènes animées, vous pouvez get un rendu less fidèle que ce qui peut sembler évident à partir des captures d'écran.

On ne sait pas exactement ce que fait votre code. Vous utilisez texture2D qui suggère un filter 2D. Pourtant, votre masortingce de convolution a une dimension et vous ne bouclez qu'une seule fois. Je peux me tromper, mais il semble que vous appliquiez le flou en diagonale. Si c'est censé être un filter 2D, vous aurez besoin de deux loops (nestedes) pour x et y respectivement pour couvrir une zone 2D.

Et à propos de la variable blurSize – son nom est un peu trompeur. La taille du flou dépend de votre masortingce de convolution. Votre est de 7 pixels de large. Cela détermine la taille. La variable est plus comme une "force" de flou qui ne peut que diminuer l'effet de la masortingce de convolution. Si donné une valeur trop élevée, des artefacts apparaîtront.

Je ne suis pas un expert et je n'ai pas écrit de pixel shader en plus de "hello world" mandelbrot one. Si je ne me trompe pas, le blur shader est l'un des pires à accélérer. La plupart des flous en time réel que j'ai vus étaient flous . Essayez de transférer du code d'ici: thread gameDev .