外发光为HLSL着色器

时间:2012-09-25 14:36:25

标签: image-processing directx hlsl outline glow

我还在开发一个图像处理项目,该项目利用HLSL着色器添加Photoshop-esque过滤器,如投影,斜角等。现在我正在寻找一种在HLSL中实现外部发光效果的方法。

我目前正在尝试以下想法:

1)缩放当前纹理以创建光晕(参数:glowSize,用于设置轮廓的大小)

2)水平模糊

3)模糊垂直,改变模糊颜色以发光颜色并在顶部添加原始纹理

我正在使用以下多遍HLSL着色器渲染光晕:

float4 PS_Scale(VS_OUTPUT IN) : COLOR0
{
    float2 tex = IN.texture0;
    float2 scaleCenter = float2(0.5f, 0.5f);
    float2 scaleTex = (tex - scaleCenter) * glowSize + scaleCenter;
    return tex2D(foreground, scaleTex);
}

float4 PS_GlowH(VS_OUTPUT IN) : COLOR0
{
    float2 Tex = IN.texture0;

    float4 sum = float4(0.0, 0.0, 0.0, 0.0);
    sum += tex2D(secondForeground, float2(Tex.x - 4.0*blur, Tex.y))*0.05;
    sum += tex2D(secondForeground, float2(Tex.x - 3.0*blur, Tex.y))*0.09;
    sum += tex2D(secondForeground, float2(Tex.x - 2.0*blur, Tex.y))*0.12;
    sum += tex2D(secondForeground, float2(Tex.x - blur, Tex.y))*0.15;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y))*0.16;
    sum += tex2D(secondForeground, float2(Tex.x + blur, Tex.y))*0.15;
    sum += tex2D(secondForeground, float2(Tex.x + 2.0*blur, Tex.y))*0.12;
    sum += tex2D(secondForeground, float2(Tex.x + 3.0*blur, Tex.y))*0.09;
    sum += tex2D(secondForeground, float2(Tex.x + 4.0*blur, Tex.y))*0.05;

    return sum;
}

float4 PS_GlowV(VS_OUTPUT IN) : COLOR0
{
    float2 Tex = IN.texture0;

    float4 sum = float4(0.0, 0.0, 0.0, 0.0);
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y - 4.0*blur))*0.05;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y - 3.0*blur))*0.09;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y - 2.0*blur))*0.12;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y - blur))*0.15;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y))*0.16;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y + blur))*0.15;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y + 2.0*blur))*0.12;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y + 3.0*blur))*0.09;
    sum += tex2D(secondForeground, float2(Tex.x, Tex.y + 4.0*blur))*0.05;

    float4 result = sum * opacity;
    result.rgb = float3(glowColor.r, glowColor.g, glowColor.b) / 255.0f;

    float4 src = tex2D(foreground, IN.texture0.xy);
    return result * (1-src.a) + src;
}

使用像椭圆这样的简单形状时,此代码的结果看起来不错,但在文本上应用着色器时不起作用:

Output of the above shader

很明显,缩放存在问题。我没有任何线索如何缩放原始纹理以将其用作轮廓。这甚至可能吗?如何在HLSL中实现外部发光或轮廓滤波器?

提前谢谢。

1 个答案:

答案 0 :(得分:10)

在这种情况下,您的扩展策略无法应用。抛弃缩放步骤,仅使用模糊步骤和合成步骤。它会工作。

让我向您展示模糊着色器如何创建发光效果。

答:有一张原始图片。

Original Image

B:更改图像的颜色,然后应用模糊着色器。

Blurred Image

C:将模糊图像与原始图像合并。

Result Image

如果要控制发光大小,请使用内核大小的模糊步骤,而不是缩放。我使用高斯模糊来创建下面的图像。

  • 内核大小5

Gaussian Size 5

  • 内核大小10

Gaussian Size 10

  • 内核大小15

enter image description here