概述
真希望有大佬能带带我啊!这块我是真不会,主要是只了解了WPF的一些基础内容,对如何做图片的一些效果(混合模式)就有点懵逼了,开始公司的大佬说要做滤色这些混合模式要用到OpenGL啥的,我也去看了不少文章,然后发现好像在WPF里面用起来,我不会啊!然后又找了一天的资料,发现可以用WPF中的Effect来进行实现这样一个效果!如果有更好的实现方式,还请帮帮我~
准备说明
PS中有滤色效果,借用知乎上的一位哥们的图片进行说明(https://zhuanlan.zhihu.com/p/158555958)。



如上就是滤色效果了!如何在WPF中实现呢?
元素
- 两张图片:你需要准备两张图片,一张用作底图,一张用作效率叠加图!
- 效果算法:WPF支持已有的一些效果,也支持自定义效果!这里采用自定义效果算法!
- ShaderEffect:本文采用该方式进行混合模式的处理!
- HLSL:全称“高级着色器语言”,参考链接:https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl
代码
继承ShaderEffect类,实现自定义的效果代码!
/// <summary>
/// 滤色混合模式
/// </summary>
public class BlendScreenEffect: ShaderEffect
{
public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty("Input", typeof(BlendScreenEffect), 0);
public static readonly DependencyProperty OverlayProperty = RegisterPixelShaderSamplerProperty("Overlay", typeof(BlendScreenEffect), 1);
public Brush Input
{
get { return (Brush)GetValue(InputProperty); }
set { SetValue(InputProperty, value); }
}
public Brush Overlay
{
get { return (Brush)GetValue(OverlayProperty); }
set { SetValue(OverlayProperty, value); }
}
public BlendScreenEffect()
{
PixelShader = new PixelShader { UriSource = new Uri("pack://application:,,,/Shaders/ScreenEffect.ps", UriKind.RelativeOrAbsolute) };
UpdateShaderValue(InputProperty);
UpdateShaderValue(OverlayProperty);
}
}
其中Input和Overlay被定义为画刷类型,前一个是底图画刷,后一个是覆盖图层画刷!
PixelShader在构造函数中赋值,这里引用加载的就是基于HLSL描述编译后的ps文件。
可以看看滤色效果的HLSL文件源码。
滤色混合模式的源码
//--------------------------------------------------------------------------------------
//
// WPF ShaderEffect HLSL -- ScreenEffect
//
//--------------------------------------------------------------------------------------
sampler2D input : register(s0);
sampler2D blend : register(s1);
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 inputColor;
inputColor = tex2D(input, uv);
float4 blendColor;
blendColor = tex2D(blend, uv);
float4 resultColor;
resultColor.a = inputColor.a;
// un-premultiply the blendColor alpha out from blendColor
blendColor.rgb = clamp(blendColor.rgb / blendColor.a, 0, 1);
// apply the blend mode math
// R = 1 - (1-Base) ?(1-Blend)
resultColor.rgb = 1 - (1 - inputColor.rgb) * (1 - blendColor.rgb);
// re-multiply the blendColor alpha in to blendColor, weight inputColor according to blendColor.a
resultColor.rgb = (1 - blendColor.a) * inputColor.rgb + resultColor.rgb * blendColor.a;
return resultColor;
}
算法和效果代码的准备工作已经做好了,接下来看看如何使用!
<Image
Source="1.png">
<Image.Effect>
<common:BlendScreenEffect>
<common:BlendScreenEffect.Overlay>
<ImageBrush ImageSource="2.png" />
</common:BlendScreenEffect.Overlay>
</common:BlendScreenEffect>
</Image.Effect>
</Image>
<common:BlendScreenEffect>中的common即wpf引用相关命名空间的名称!该命名空间下有BlendScreenEffect类,即我们开始继承ShaderEffect的自定义类!
大致情况就是这样了,如果想做更多效果或者动画,就自行扩展啦!更多混合模式的HLSL编码大家可以网上找找看,也可以留言找我拿!
感谢各位,求大佬们帮忙,看看有没有更好的实现方式?
文章讲述了作者在WPF中遇到如何实现滤色效果的困惑,通过使用ShaderEffect和HLSL编程,展示了如何自定义混合模式,包括代码示例和HLSL源码。寻求更优实现建议。

465

被折叠的 条评论
为什么被折叠?



