Question

Y at-il quelque chose d'inhabituel sur la façon dont la composante alpha est traitée dans un pixel shader? J'ai une application WPF pour laquelle mon artiste me donne des images en niveaux de gris à utiliser comme arrière-plans, et l'application colorise les images en fonction de l'état actuel. J'ai donc écrit un pixel shader (en utilisant les effets Pixel Shader WPF infrastructure Library) à utiliser comme un effet sur un élément d'image. Le shader prend une couleur en tant que paramètre, qui le convertit en HSL de sorte qu'il peut manipuler la luminosité. Ensuite, pour chaque pixel gris, il calcule une couleur dont la luminosité est interpolée entre le paramètre de couleur et de blanc en fonction de la luminosité du pixel de source.

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 src = tex2D(implicitInputSampler, uv);

    // ...Do messy computation involving src brightness and color parameter...

    float4 dst;
    dst.r = ...
    dst.g = ...
    dst.b = ...
    dst.a = src.a;
    return dst;
}

Cela fonctionne très bien sur les pixels où alpha = 1. Mais où alpha = 0, les pixels résultants sortent blanc, plutôt que d'avoir le spectacle d'arrière-plan de la fenêtre à travers. Donc, j'ai fait un petit changement:

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 src = tex2D(implicitInputSampler, uv);
    if (src.a == 0) 
        return src;
    ...

et maintenant les parties transparentes sont vraiment transparentes. Pourquoi? Pourquoi ne pas la déclaration de dst.a = src.a dans la première version à accomplir cela? Malheureusement, même ce n'est qu'une solution partielle, car il me semble que les pixels avec 0

Quelqu'un sait-il ce que je ne comprends pas au sujet de l'alpha?

Était-ce utile?

La solution

Après un peu plus la recherche web, j'ai découvert la pièce que je manquais.

Selon un article sur MSDN : « WPF utilise alpha prémultipliés partout en interne pour un certain nombre de raisons de performance, de sorte que c'est aussi la façon dont nous interprétons les valeurs de couleur dans le pixel shader personnalisé. »

Ainsi, la solution se révèle être à jeter dans une multiplication par alpha:

float4 main(float2 uv : TEXCOORD) : COLOR
{
    ...
    dst.rgb *= src.a;
    return dst;
}

Et maintenant ma sortie semble que je l'attends.

Autres conseils

  

0

Qu'est-ce que va vous attendez-vous ici?

Toutes les valeurs vont être dans la gamme de 0,0 et 1,0 ... pixel shaders ne fonctionnent pas discrets 256 gammes de couleurs, ils sont à virgule flottante, où 1,0 est l'intensité maximale.

Si vos calculs finissent par mettre en r / g / b valeurs à> 1.0, vous allez obtenir blanc ...

http://www.facewound.com/tutorials/shader1/

Mec je travaille sur un jeu XNA, et je devais utiliser un pixel shader en niveaux de gris et je suis le même problème que vous rencontrez. Je Donno si vous êtes familier avec l'environnement XNA ou non, mais je résolu le problème en changeant la SpriteBatch Dessin SpriteBlendMode de SpriteBlendMode.None SpriteBlendMode.AlphaBlend , j'espère que cela peut vous aider à connaître la raison.

Cordialement,

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top