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. Page和list的区别 mybatis

    先看一段代码 点击查看代码 @Override public Result findUserPage(PageParam pageParam) { Page<SysUser> page = ...

  2. 人理解迭代,神则体会递归,从电影艺术到Python代码实现神的逆向思维模式

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_186 "从来如此,便对么?",鲁迅先生在<狂人日记>中借狂人之口在月光下发出的质疑与呐喊,是的,从 ...

  3. Linux 08 磁盘管理

    参考源 https://www.bilibili.com/video/BV187411y7hF?spm_id_from=333.999.0.0 版本 本文章基于 CentOS 7.6 概述 Linux ...

  4. V8中的快慢属性(图文分解更易理解)

    出于好奇:js中使用json存数据查找速度快,还是使用数组存数据查找快? 探究V8中对象的实现原理,熟悉数组索引属性.命名属性.对象内属性.隐藏类.描述符数组.快慢属性等等. D8调试工具使用请来这里 ...

  5. .NET WebAPI 采用 IDistributedCache 实现分布式缓存过滤器 Redis 模式

    分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护. 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时. 与其 ...

  6. 基于Go语言的xmind读写库,我主要用来把有道云笔记思维导图转为xmind

    项目地址 xmind 基于go语言的xmind接口 使用方法参考: example 本库主要加载xmind文件为json结构,保存文件时也用的json结构而不是xml结构 本库只做了最基本的主题添加功 ...

  7. python常量与变量的本质

    python语法常量与变量的本质 python语法之注释 1.python语法注释有哪几种? (1.)单行注释 # 井号键单行注释 使用方法:首先在另起一行按('#')井号键进行注释,如果需要代码后面 ...

  8. vue.js及H5常见跨域问题解决方案

    一.原生H5跨域问题解决方案 1.live-server 代理解决 首先在有node.js环境下,打开命令行工具,输入 npm install live-server -g 全局安装全局安装 live ...

  9. 「题解报告」Blocks

    P3503 Blocks 题解 原题传送门 思路 首先我们可以发现,若 \(a_l\) ~ \(a_r\) 的平均值大于等于 \(k\) ,则这个区间一定可以转化为都大于等于 \(k\) 的.我们就把 ...

  10. Python入门系列(九)pip、try except、用户输入、字符串格式

    pip 包含模块所需的所有文件. 检查是否安装了PIP $ pip --version 安装包 $ pip install package_name 使用包 import package_name 删 ...