Mode de fusion Photoshop pour OpenGL ES sans shaders
Question
Je dois imiter les modes de fusion Photoshop ("multiplier", "écran", etc.) dans mon code OpenGL ES 1.1 ( sans shaders).
Certains documents expliquent comment procéder avec HLSL:
- http: //www.nathanm .com / photoshop-blending-math / (archive)
- http: //mouaif.wordpress. com / 2009/01/05 / photoshop-math-with-glsl-shaders /
J'ai besoin d'au moins le mode écran fonctionnel.
Existe-t-il des implémentations sur un pipeline fixe que je pourrais examiner?
La solution
La plupart des modes de fusion photoshop sont basés sur les modes de fusion Porter-Duff.
Cela nécessite que toutes vos images (textures, tampon de rendu) se trouvent dans un espace colorimétrique prémultiplié. Cela se fait généralement en multipliant toutes les valeurs en pixels par la valeur alpha avant de les stocker dans une texture. Par exemple. un pixel totalement transparent ressemblera à du noir dans un espace colorimétrique non prémultiplié. Si vous n'êtes pas familier avec cet espace de couleur, passez une heure ou deux à le lire sur le Web. C'est un concept soigné et intéressant, indispensable pour les compositions de type Photoshop.
Quoi qu’il en soit - une fois que vous avez vos images dans ce format, vous pouvez activer l’ÉCRAN en utilisant:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR)
Le mode MULTIPLES complet n'est pas possible avec le pipeline OpenGL | ES. Si vous travaillez uniquement avec des pixels opaques complets, vous pouvez le simuler avec:
glBlendFunc(GL_ZERO, GL_SRC_COLOR)
Les résultats pour les pixels transparents dans votre texture et dans votre framebuffer seront faux cependant.
Autres conseils
vous devriez essayer ceci:
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA)
Cela ressemble à me multiplier sur l'iPhone / OpenGL ES
Votre meilleur point de départ est de vous procurer un exemplaire du Livre rouge et lisez les chapitres sur les matériaux et les modes de fusion. Il fournit une explication très complète et claire du fonctionnement des fonctions de fusion «classiques» OpenGL.
J'ai constaté qu'en utilisant ceci:
glDepthFun (GL_LEQUAL);
avait tous besoin d'obtenir un effet d'écran, au moins cela a bien fonctionné pour mon projet.
Je ne sais pas pourquoi cela fonctionne, mais si quelqu'un le sait, partagez-le.