2012-06-23 36 views
5

在WPF中,OuterGlowBitmapEffect不再被Net4.0支持或渲染。 DropShadow有一點共同點,在我的情況下是不可接受的。我最初的目標是在AeroGlass窗口上爲黑色ClearType文本製作一個白色模糊的背景,以便在黑暗場景中使其更易讀。我開始玩fx和HLSL。這是相當有趣和強大的,但我仍然無法接近OuterGlowBitmapEffect。如何使用HLSL製作外發光效果?

反映的想法我當前的虛擬版本:

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:我可以得到一個HLSL源DropShadowEffect使用它作爲一個參考?有人可以用任何語言指向我的OuterGlowEffect算法嗎?

注意:Windows 7 Aero Glass標題欄具有使標題更具可讀性的效果!這正是我想要在窗口的其他部分(DwmExtendFrameIntoClientArea應用)我的文本Aero Glass Window Title

回答

3

一般的想法是先渲染白色文本,然後模糊它。最後使用模糊的白色文字作爲黑色文字的背景圖像。

您的着色器是一個正確的模糊,但它有點低效(例如對於x = 0的冗餘樣本)。您可以通過兩次傳遞創建一個很好的大模糊:一個水平模糊和一個垂直模糊。 HLSL代碼:

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. 

這兩個7樣本遍模擬7×7高斯模糊(14個樣本,而不是49個)。您可以使用更多樣本來改善結果(使模糊變寬)或者只是調整權重以創建更柔和的外觀。

+0

聽起來不錯!但是對於WPF BitmapEffect來說,多通道着色器通常是不可能的:(有一些提示和說明:http://www.codeproject.com/Articles/71617/Getting-Started-with-Shader-Effects-in-WPF 現在性能不是問題,因爲有少量的文本和少量的位圖來渲染,如果你能幫助創建一個單通道函數來渲染具有背景模糊的文本,那將是非常好的。 –

+2

你沒有創建一個多通道着色器,你要做的是: 1.用'PS_BlurHorizo​​ntal'模糊原始圖像, 2.用'PS_BlurVertical'模糊上一步的結果 如果你需要一次通過,看看這個:http://code.google.com/p/sbip/source/browse/trunk/SBIPFramework/Resources/GaussianBlur.fx?r=76 – miloszmaki