1. 融合效果
融合效果是指對兩個接近的元素進行高斯模糊后再提高對比度,使它們看上去“粘”在一起,在之前的一篇文章中,我使用 Win2D 實作了融合效果,效果如下:

不過 Win2D 不適用于 WPF,在 WPF 中可以使用 BlurEffect 配合自定義 Effect 實作類似的效果,HandyControl 中有一個使用自定義的 ContrastEffect 實作融合效果的 Demo,如下圖:

但是 ContrastEffect 是通過 Contrast 屬性同時控制 RGBA 四個通道的對比值,所以沒辦法控制準確地顏色,另外 HandyControl 也提供了 ColorMatrixEffect,不過 ColorMatrixEffect 很難控制對比度,
既然都用到自定義 Effect 了,這次索性自己寫一個,
2. 自定義 Effect
在 Win2D 中,實作融合效果的步驟是先使用 GaussianBlurEffect 在兩個元素間產生粘連在一起的半透明像素,再用 ColorMatrixEffect 加強對比對,使半透明的像素變得完全不透明,
在 WPF 中我們可以直接使用自帶的 BlurEffect 實作高斯模糊,效果如下:

接下來需要加強對比度,WPF 中沒有 ColorMatrixEffect 的替代品,不過我們可以使用 HLSL(高級著色器語言)撰寫 PixelShader 并生成自定義的 WPF Effect,撰寫 PixelShader 可以使用 Shazzam Shader Editor, walterlv 有一篇關于如何使用這款編輯器的教程:
WPF 像素著色器入門:使用 Shazzam Shader Editor 撰寫 HLSL 像素著色器代碼
在這里我撰寫了一個對 Alpha 進行二值化處理的 PixelShader 實作加強對比度功能,它的作用很簡單:當像素的 Alpha 大于閾值就將 Alpha 置為 1,否則為 0,代碼如下:
float Thresh : register(C0);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color;
color = tex2D(input, uv.xy);
if (color.a == 0 || color.a == 1 || Thresh == 0)
{
return color;
}
float4 resultColor = 0;
float opacity = color.a > Thresh ? 1 : 0;
if (opacity > 0)
{
resultColor.rgb = color.rgb / color.a * opacity;
}
resultColor.a = opacity;
return resultColor;
}

雖然確實實作了融合效果,但是圓形的邊緣有嚴重的鋸齒,很明顯,問題出在上面的代碼中 Alpha 通道最終不是 0 就是 1,為了使邊緣平滑,應該留下一些“中間派”,修改后的代碼參考了 LowerThresh 和 UpperThresh,處于這兩個閾值之間的像素用作保持邊緣平滑的“中間派”,具體代碼如下:
float UpperThresh : register(C0);
float LowerThresh : register(C1);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color;
color = tex2D(input, uv.xy);
if (color.a == 0 || color.a == 1 || LowerThresh == 0)
{
return color;
}
if (UpperThresh < LowerThresh)
{
return color;
}
float4 resultColor = 0;
float opacity = 1;
if (color.a < LowerThresh)
{
opacity = 0;
}
if (color.a > LowerThresh && color.a < UpperThresh)
{
opacity = (color.a - LowerThresh) / (UpperThresh - LowerThresh);
}
if (opacity > 0)
{
resultColor.rgb = color.rgb / color.a * opacity;
}
resultColor.a = opacity;
return resultColor;
}

3. 最后
這篇文章介紹了如何使用自定義 Effect 實作融合效果,只要理解了融合效果的原理并動手實作了一次,之后就可以參考博客園的 ChokCoco 大佬玩出更多花樣,例如這種效果::

更多好玩的效果可以參考 ChokCoco 大佬的博客:你所不知道的 CSS 濾鏡技巧與細節
原始碼:https://github.com/DinoChan/wpf_design_and_animation_lab
作者:dino.c
出處:http://www.cnblogs.com/dino623/
說明:歡迎轉載并請標明來源和作者,如有錯漏請指出,謝謝,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/509661.html
標籤:WPF
