在WPF中,Net4.0不再支持或呈现OuterGlowBitmapEffect.DropShadow有一点共同点,在我的情况下是不可接受的.我最初的目标是在AeroGlass窗口上为黑色ClearType文本制作白色模糊背景,使其在黑暗场景下更具可读性.我开始玩fx和HLSL.它非常有趣和强大,但我仍然无法接近OuterGlowBitmapEffect.
我当前的虚拟版本反映了这个想法:
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;
}
Run Code Online (Sandbox Code Playgroud)
顺便说一下:我可以获得DropShadowEffect的HLSL源来将其用作参考吗?有人能用任何语言指出我的OuterGlowEffect算法吗?
注意:Windows 7 Aero Glass标题栏具有使标题更具可读性的效果!这正是我希望我的文本在窗口的其他部分(DwmExtendFrameIntoClientArea应用)
总体思路是先渲染白色文本,然后对其进行模糊处理。最后使用模糊的白色文本作为黑色文本的背景图像。
您的着色器是正确的模糊,但效率有些低(例如,x=0 的冗余样本)。您可以通过两次传递创建良好的大模糊:一次水平模糊和一次垂直模糊。HSL 代码:
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.
Run Code Online (Sandbox Code Playgroud)
这两个 7 样本通道模拟 7x7 高斯模糊(14 个样本而不是 49 个样本)。您可以使用更多样本来改善结果(使模糊更宽)或仅调整权重以创建更柔和的外观。