Hoe maak je het Outer Glow Effect met HLSL?

In wpf wordt OuterGlowBitmapEffect niet meer ondersteund of weergegeven door Net4.0. DropShadow heeft iets gemeen en is in mijn geval niet acceptabel. Mijn eerste doel is om een ​​witte wazige achtergrond te maken voor zwarte ClearType-tekst in het AeroGlass-venster om het leesbaarder te maken in donkere scènes. Ik begon te spelen met fx en HLSL. Het is best interessant en krachtig, maar ik kan nog steeds niet dichter bij OuterGlowBitmapEffect komen.

Mijn huidige dummy-versie die het idee weerspiegelt:

sampler2D  Sampler : register(S0);
#define PI 3.14f
float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 px = tex2D(Sampler, uv);

    /*
    if (px.a > 0.9)
    {
        return px;
    }
    */

    const float d = 3;

    int cnt = 0;
    float a = 0;
    for (float x = -0.1*d; x < 0.1*d; x += 0.05*d)
    {
        a += tex2D(Sampler, uv + float2(x, 0)).a;
        a += tex2D(Sampler, uv + float2(0, x)).a;
        a += tex2D(Sampler, uv + x).a;
        cnt += 3;
    }
    a /= cnt;

    float4 s = a;

    float4 r = float4(px.rgb*px.a + s.rgb*(1-px.a), max(px.a, a));

    return r;
}

BTW: kan ik een HLSL-bron voor DropShadowEffect krijgen om het als referentie te gebruiken? Kan iemand me wijzen op een OuterGlowEffect-algoritme in welke taal dan ook?

NOTE: Windows 7 Aero Glass title bar have such effect to make title more readable! That exactly what I'd like to have for my text on other parts of window (DwmExtendFrameIntoClientArea applied) Aero Glass Window Title

5

1 antwoord

Het algemene idee is om de witte tekst eerst weer te geven en vervolgens te vervagen. En tot slot om de vage witte tekst als achtergrondafbeelding voor de zwarte tekst te gebruiken.

Uw arcering is een correcte vervaging, maar deze is enigszins inefficiënt (bijvoorbeeld redundante voorbeelden voor x = 0). U kunt een goede grote vervaging met twee passages maken: een horizontale en een verticale vervaging. HLSL-code:

float4 PS_BlurHorizontal( float2 Tex : TEXCOORD0 ) : COLOR0
{
    float Color = 0.0f;

    Color += tex2D(sampler, float2(Tex.x - 3.0*blurSizeX, Tex.y)) * 0.09f;
    Color += tex2D(sampler, float2(Tex.x - 2.0*blurSizeX, Tex.y)) * 0.11f;
    Color += tex2D(sampler, float2(Tex.x - blurSizeX, Tex.y)) * 0.18f;
    Color += tex2D(sampler, Tex) * 0.24f;
    Color += tex2D(sampler, float2(Tex.x + blurSizeX, Tex.y)) * 0.18f;
    Color += tex2D(sampler, float2(Tex.x + 2.0*blurSizeX, Tex.y)) * 0.11f;
    Color += tex2D(sampler, float2(Tex.x + 3.0*blurSizeX, Tex.y)) * 0.09f;

    return Color;
}

float4 PS_BlurVertical( float2 Tex : TEXCOORD0 ) : COLOR0
{
    float Color = 0.0f;

    Color += tex2D(sampler, float2(Tex.x, Tex.y - 3.0*blurSizeY)) * 0.09f;
    Color += tex2D(sampler, float2(Tex.x, Tex.y - 2.0*blurSizeY)) * 0.11f;
    Color += tex2D(sampler, float2(Tex.x, Tex.y - blurSizeY)) * 0.18f;
    Color += tex2D(sampler, Tex) * 0.24f;
    Color += tex2D(sampler, float2(Tex.x, Tex.y + blurSizeY)) * 0.18f;
    Color += tex2D(sampler, float2(Tex.x, Tex.y + 2.0*blurSizeY)) * 0.11f;
    Color += tex2D(sampler, float2(Tex.x, Tex.y + 3.0*blurSizeY)) * 0.09f;

    return Color;
}
// weights: 0.09 + 0.11 + 0.18 + 0.24 + 0.18 + 0.11 + 0.9 = 1
// By default, weigths are symmetrical and sum up to 1,
// but they don't necessarily have to.
// You can change the weights to create more fancy results.

Deze twee 7-sample passes simuleren een 7x7 Gaussiaanse vervaging (14 samples in plaats van 49). U kunt meer voorbeelden gebruiken om het resultaat te verbeteren (maak onscherpte groter) of pas de gewichten aan om een ​​zachtere uitstraling te creëren.

3
toegevoegd
je hoeft geen multi-pass shader te maken, wat je doet is: 1. vervaag de originele afbeelding met PS_BlurHorizontal , 2. vervaag het resultaat van de vorige stap met PS_BlurVertical . als je een enkele pass nodig hebt, bekijk dit dan: code.google.com/p/sbip/source/browse/trunk/SBIPFramework/…
toegevoegd de auteur miloszmaki, de bron
Klinkt goed! Maar over het algemeen is het onmogelijk om een ​​multi-pass-shader voor wpf BitmapEffect :( te hebben (er zijn enkele tips en beschrijvingen: codeproject.com/Articles/71617/… Voorlopig is prestatie geen probleem, omdat een kleine hoeveelheid tekst en kleine hoeveelheid bitmaps te renderen is. zou geweldig zijn als u kunt helpen bij het maken van een single-pass-functie voor het renderen van tekst met een vage achtergrond.
toegevoegd de auteur Dmitry Gusarov, de bron