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

在 WPF 中实现融合效果的更多相关文章

  1. WPF中制作立体效果的文字或LOGO图形(续)

    原文:WPF中制作立体效果的文字或LOGO图形(续) 上篇"WPF中制作立体效果的文字或LOGO图形"(http://blog.csdn.net/johnsuna/archive/ ...

  2. WPF中制作立体效果的文字或LOGO图形

    原文:WPF中制作立体效果的文字或LOGO图形 较久之前,我曾写过一篇:"WPF绘制党徽(立体效果,Cool) "的博文.有感兴趣的朋友来EMAIL问是怎么制作的?本文解决此类问题 ...

  3. 浅谈WPF中对控件的位图特效(WPF Bitmap Effects)

    原文:浅谈WPF中对控件的位图特效(WPF Bitmap Effects) -------------------------------------------------------------- ...

  4. 使用 Win2D 实现融合效果

    1. 融合效果 在 CSS 中有一种实现融合效果的技巧,使用模糊滤镜(blur)叠加对比度滤镜(contrast)使两个接近的元素看上去"粘"在一起,如下图所示: 博客园的 Cho ...

  5. 在WPF中使用PlaneProjection模拟动态3D效果

    原文:在WPF中使用PlaneProjection模拟动态3D效果 虽然在WPF中也集成了3D呈现的功能,在简单的3D应用中,有时候并不需要真实光影的3D场景.毕竟使用3D引擎会消耗很多资源,有时候使 ...

  6. WPF中,如何将Vista Aero效果扩展到整个窗口

    原文:WPF中,如何将Vista Aero效果扩展到整个窗口   WPF中,如何将Vista Aero效果扩展到整个窗口                                         ...

  7. WPF中利用RadialGradient模拟放大镜效果

    原文:WPF中利用RadialGradient模拟放大镜效果 --------------------------------------------------------------------- ...

  8. WPF中ListBox滚动时的缓动效果

    原文:WPF中ListBox滚动时的缓动效果 上周工作中遇到的问题: 常规的ListBox在滚动时总是一格格的移动,感觉上很生硬. 所以想要实现类似Flash中的那种缓动的效果,使ListBox滚动时 ...

  9. MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

随机推荐

  1. 启用Hyper-v后,重启后界面提示 无法完成功能配置,正在撤销更改

    安装docker后,提示需要启用hyper-v,在控制面板中勾选Hyper-v,然后重启,更新快完成就提示无法完成功能配置,正在撤销更改 解决方法 方法1 控制面板一个一个选 方法2 百度了n多内容, ...

  2. DDL_操作数据库_创建&查询和DDL_操作数据库_修改&删除&使用

    DDL操作数据库.表 1.操作数据库:CRUD C(Create):创建 创建数据库: create database 数据库名称: 创建数据库判断不存在再创建 create database if ...

  3. PLC转OPC UA的协议转换网关需要多少钱呢?

    嵌入式OPC UA网关BL102简化了OPC UA程序的开发与IIOT工业物联网应用 在制造业数字化升级过程中,我们碰到最多的工作便是针对每一款PLC去开发一套OPC UA程序,然后通过这套程序去读取 ...

  4. tcp协议传输中的粘包问题

    什么是粘包问题 tcp是流体协议. 其nagle算法会将数据量较小. 并且发送间隔时间较短的多个数据包合并为一个发送. 网络传输的时候是一段一段字节流的发送. 在接收方看来根本不知道字节流从何开始. ...

  5. Nginx 浏览器缓存配置指令

    # 浏览器缓存 # 当浏览器第一次访问服务器资源的时候,服务器返回到浏览器后,浏览器进行缓存 # 缓存的大概内容有: # 1.缓存过期的日期和时间 # 2.设置和缓存相关的配置信息 # 3.请求资源最 ...

  6. google nexus5x 刷机抓包逆向环境配置(二)

    本文仅供学习交流使用,如侵立删! google nexus5x 刷入永久TWEP和Magisk(面具root) 操作环境 nexus5x kaliLinux win10 准备 下载链接:https:/ ...

  7. java后台生成文件给前端下载(response输出流)

    1.设置 ContentType response.setContentType("application/x-download"); 2.设置文件名,并指定编码格式 fileNa ...

  8. 介绍下Java内存区域(运行时数据区)

    介绍下Java内存区域(运行时数据区) Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域.JDK 1.8 和之前的版本略有不同. 下图是 JDK 1.8 对JV ...

  9. Spring mvc源码分析系列--前言

    Spring mvc源码分析系列--前言 前言 距离上次写文章已经过去接近两个月了,Spring mvc系列其实一直都想写,但是却不知道如何下笔,原因有如下几点: 现在项目开发前后端分离的趋势不可阻挡 ...

  10. Postman中的断言

    Postman设置断言 一.断言的定义 1.什么是断言? 一般一个完整的接口测试,包括:请求->获取响应正文->断言,请求和获取响应正文很常见.断言一般是对请求的响应结果做操作,判断预期结 ...