J'essaie actuellement de faire fonctionner ce shader de bokeh avec GPuimage: http://blaireartists.org/forum/showthread.php?237488-glsl-depth-of-field-withbokeh-v2-4- (mise à jour)
C'est ce que j'ai pour le moment: P>
@implementation ViewController { GPUImageBokehFilter *bokehFilter; GPUImagePicture *bokehMap; UIImage *inputImage; } - (void)viewDidLoad { [super viewDidLoad]; inputImage = [UIImage imageNamed:@"stones"]; bokehMap = [[GPUImagePicture alloc] initWithImage:[UIImage imageNamed:@"bokehmask"]]; _backgroundImage.image = inputImage; bokehFilter = [[GPUImageBokehFilter alloc] init]; [self processImage]; } - (IBAction)dataInputUpdated:(id)sender { [self processImage]; } - (void *)processImage { dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ GPUImagePicture *gpuPicture = [[GPUImagePicture alloc] initWithImage:inputImage]; [gpuPicture addTarget:bokehFilter]; [gpuPicture processImage]; [bokehMap addTarget:bokehFilter]; [bokehMap processImage]; [bokehFilter useNextFrameForImageCapture]; [bokehFilter setFloat:inputImage.size.width forUniformName:@"inputImageTextureWidth"]; [bokehFilter setFloat:inputImage.size.height forUniformName:@"inputImageTextureHeight"]; UIImage *blurredImage = [bokehFilter imageFromCurrentFramebuffer]; dispatch_async(dispatch_get_main_queue(), ^{ [self displayNewImage:blurredImage]; }); }); } - (void)displayNewImage:(UIImage*)newImage { [UIView transitionWithView:_backgroundImage duration:.6f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ _backgroundImage.image = newImage; } completion:nil]; } ...
4 Réponses :
L'artefact diagonal semble être causé par votre gradient de test. Vous pouvez voir qu'il se produit à peu près au même endroit que lorsque votre gradient va complètement blanc. Essayez de diffuser le dégradé de sorte qu'il n'atteint que 1,0 ou 0,0 à 0,0 dans les coins mêmes de l'image. P>
Qui défait le but d'avoir une carte de profondeur en premier lieu.
Que veux-tu dire? Je dis que vous utilisez toujours un gradient, il suffit de ne pas le faire pincer à 1,0 ou 0,0 au milieu de l'image. Essayez de superposer votre gradient (dans Photoshop ou quelque chose) sur votre image; Vous verrez ce que je veux dire.
J'ai besoin de ces zones blanches / noires solides car elles disent au shader quoi de rester pleinement au centre et quoi floue. Si je suis votre conseil, le shader brouille tout sauf une très petite pièce dans le coin de l'image où le gradient atteint 1.0.
Oh d'accord. Je ne comprends pas le shader assez bien pour connaître spécifiquement pourquoi, mais la forme du gradient est définitivement ce qui cause l'artefact - il y a un "bord" comme l'approche de la gradient 0,0 ou 1.0. Si vous y réfléchissez en tant que traitement du signal, les bords sont des changements à haute fréquence. Le shader doit les filtrer; Le shader doit échantillonner plus autour de chaque point. Pour éviter ce changement, vous pouvez essayer un gradient lisse (au lieu d'une linéaire); Un gradient S-courbe (j'oublie de quoi cela s'appelle à l'instant).
Vous pouvez utiliser une carte de profondeur RVB et obtenir des gradations 16777216 au lieu de seulement 256.
Je dirai. J'ai passé des jours à travailler sur des choses comme celle-ci pour une application. Essayer de trouver le coupable quand les choses ne vont pas bien. Je pense qu'Anna est sur quelque chose. Je ne peux pas dire quelle partie de l'image est floue et quelle partie n'est pas. Je fixerais le montant de la partie afin que vous puissiez vraiment dire. Ou utilisez une superposition de couleur au lieu d'un flou pour voir que votre code tampon de profondeur est même correct. Avez-vous écrit tout ce code ou trouvez-le quelque part? Cause pour moi, il semble que une formule soit fausse ou peut-être une indice de précision est éteinte.
Il s'avère que la fonction linéariser () était responsable de l'artefact. Je l'ai supprimé et l'artefact était parti.
Avez-vous essayé d'activer showfocus code>? Cela devrait montrer le point focal en rouge et la plage focale en vert qui devrait aider à déboguer. Vous pouvez également essayer d'activer
autofocus code> de s'assurer que le centre de l'image est en train de se concentrer, car au moment opportun, il n'est pas évident que la distance doit être mise au point, en raison du
linéariser code> Fonction Modification des systèmes de coordonnées. Après cela, essayez de modifier
fstop code> pour obtenir la quantité souhaitée de flou. Vous constaterez probablement également que vous aurez besoin de plus que
échantillons = 3 code> et
anneaux = 3 code> pour produire un effet de bokeh lisse. p>
C'est une très grande question, et je ne peux pas faire une réponse complète car j'aurais vraiment besoin de tester la chose. p>
Mais quelques points: l'image finale que vous avez mise au travail est difficile à travailler. Parce que l'image a tellement été aménagée, je ne peux pas dire si elle est réellement floue ou si elle semble simplement floue à cause de la résolution. Peu importe, la quantité de flou que vous obtenez (par rapport au lien d'origine que vous avez fourni) suggère que quelque chose ne fonctionne pas avec le shader. P>
Une autre chose qui me concerne est le J'espère que ça met de la lumière et bonne chance! P> // Quelque chose d'optimisation code> commentaire que vous avez là-bas. C'est le genre de chose qui va être responsable d'une ligne laid dans votre sortie finale. Dire que vous n'aurez pas de flou sous
flou <0,05 code> n'est pas nécessairement quelque chose que vous pouvez faire! Je m'attendrais à un artefact méchant que le shader passe du shader flou et dans la partie "optimisée". P>
L'optimisation Thingy est en fait très utile, car elle maintient essentiellement le shader de transformer des pièces d'image qui ne sont pas censées être traitées. Il aide à ce que la transition de 0,05% de flou à 0% de flou est à peu près invisible.
Vos réponses m'a aidé à monter sur la bonne voie, et après quelques heures de violation de mon code et du shader, j'ai réussi à obtenir tous les bugs fixés. Voici ce qui les a causés et comment je les ai réparés:
La méthode de la diagonale laide a été causée par la méthode L'image bleu-ish que j'ai obtenue du shader a été causée par ma propre incompétence. Ces deux lignes devaient être placées avant em> les appels vers dans le recul, c'est évident pourquoi je ne veux que J'ai reçu des résultats la deuxième fois que j'ai utilisé le shader. Après avoir corrigé ces bugs, je suis allé l'optimiser un peu pour garder le temps d'exécution aussi bas que possible, et je peux maintenant lui dire de rendant 8 échantillons / 4 anneaux et il le fait en moins d'une seconde. Voici ce qui ressemble à: p> Merci pour les réponses, tout le monde, je n'aurais probablement pas eu ces bugs fixés sans vous. P> P> linéarize () code>, donc je l'ai supprimée et que le shader utilise les valeurs RVB (ou pour être Plus précis: seule la valeur R) de la carte de profondeur sans les traiter d'abord. P>
processImage code>: p>
p>
La première chose qui vous saute est que
[bokehmap processimage]; code> et
[bokehfilter usenextframeframeCapture]; code> sont dans le mauvais ordre. Ils doivent être retournés, de sorte que vous indiquez au filtre que vous en capturerez avant de déclencher le traitement qui met à jour la sortie du filtre. Essayez de changer ceux et voyez ce qui se passe. En plus de cela, il s'agit d'une shader horriblement chère et je me demande si le remplaçait par un filtre à trois entrées qui prend également une version gaussienne floue de l'image pour le mélange (comme Tilt Shift) fonctionnerait mieux.
J'ai renversé les deux appels de méthode, seulement pour obtenir les mêmes résultats. En outre, je sais que ce shader est cher, mais je ne sais pas assez de shaders pour le simplifier. C'est un miracle que j'ai réussi à aller aussi loin sans aide! : D Ce serait génial si quelqu'un qui sait ce qu'ils font prennent cela, nettoyaient et en ont fait une partie «officielle» de GPuimage.
(Aussi, continuez votre excellent travail! GPuimage m'a fait apprendre les bases des shaders de fragments, quelque chose que j'ai mis trop longtemps)