原文:WPF/Silverlight深度解决方案:(七)HLSL自定义渲染特效之完美攻略(中)

通过上一节的解说,大家是否已经对HLSL有了较深刻的认识和理解,HLSL的渲染不仅仅局限于静态处理,通过时时更新HLSL代码的各全局变量值同样可以实现动画形式的渲染,非常Cool对吧~。那么本节我将向大家介绍如何在Silverlight平台上实现HLSL动画渲染特效。

以BandedSwirl(螺旋波纹)渲染特效为例,我们首先要做的是按照上一节的方法将BandedSwirl.ps文件添加进项目中,同时创建一个对应的BandedSwirl.cs文件:

using System.Windows;

using System.Windows.Media;

using System.Windows.Media.Effects;

namespace Silverlight.Shader {

public class BandedSwirl : ShaderEffect {

public static DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(BandedSwirl), 0);

public static DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(System.Windows.Point), typeof(BandedSwirl), new PropertyMetadata(new System.Windows.Point(), PixelShaderConstantCallback(0)));

public static DependencyProperty SpiralstrengthProperty = DependencyProperty.Register("Spiralstrength", typeof(double), typeof(BandedSwirl), new PropertyMetadata(new double(), PixelShaderConstantCallback(1)));

public static DependencyProperty DistancethresholdProperty = DependencyProperty.Register("Distancethreshold", typeof(double), typeof(BandedSwirl), new PropertyMetadata(new double(), PixelShaderConstantCallback(2)));

public BandedSwirl(PixelShader shader) {

PixelShader = shader;

this.UpdateShaderValue(InputProperty);

this.UpdateShaderValue(CenterProperty);

this.UpdateShaderValue(SpiralstrengthProperty);

this.UpdateShaderValue(DistancethresholdProperty);

}

public virtual System.Windows.Media.Brush Input {

get {

return ((System.Windows.Media.Brush)(GetValue(InputProperty)));

}

set {

SetValue(InputProperty, value);

}

}

public virtual System.Windows.Point Center {

get {

return ((System.Windows.Point)(GetValue(CenterProperty)));

}

set {

SetValue(CenterProperty, value);

}

}

public virtual double Spiralstrength {

get {

return ((double)(GetValue(SpiralstrengthProperty)));

}

set {

SetValue(SpiralstrengthProperty, value);

}

}

public virtual double Distancethreshold {

get {

return ((double)(GetValue(DistancethresholdProperty)));

}

set {

SetValue(DistancethresholdProperty, value);

}

}

}

}

接下来在后台cs代码中创建渲染特效实例:

pixelShader = new PixelShader() {

UriSource = GetShaderUri("BandedSwirl.ps")

};

BandedSwirl bandedSwirl = new BandedSwirl(pixelShader) {

Center = new Point(0.5, 0.5),

Spiralstrength = 1,

Distancethreshold = 0

};

Spirit.Effect = bandedSwirl;

最后就是关键环节了,如何实现动画效果呢?大家是否有注意到BandedSwirl类中的CenterProperty、SpiralstrengthProperty、DistancethresholdProperty这三个DependencyProperty(关联属性)参数,它们分别代表该渲染特效的中心、螺旋强度和延伸阈值。由于是关联属性,所以我们可以直接使用Storyboard去实现基于它们的渐变动画,那么以动态修改Distancethreshold值为例,具体实现代码如下:

BeginShaderAnimation(bandedSwirl, 0, 1, 3, "Distancethreshold");

/// <summary>

/// 启动渲染动画

/// </summary>

private void BeginShaderAnimation(DependencyObject shader, double from, double to, double timeSpanFromSeconds, string dependencyProperty) {

if (storyboard != null) { storyboard.Stop(); }

storyboard = new Storyboard();

storyboard.RepeatBehavior = RepeatBehavior.Forever;

storyboard.AutoReverse = true;

doubleAnimation = new DoubleAnimation();

doubleAnimation.From = from;

doubleAnimation.To = to;

doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(timeSpanFromSeconds));

Storyboard.SetTarget(doubleAnimation, shader);

Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(dependencyProperty));

storyboard.Children.Add(doubleAnimation);

storyboard.Begin();

}

通过一个Storyboard故事板,我们让bandedSwirl渲染特效的Distancethreshold值在3秒时间内从0改变到1,然后反序列帧执行并不断循环。至此一个基于HLSL的螺旋波纹渲染特效就制作完成啦!以同样的方法我还特意制作了波浪渲染动画、放大渲染动画、模糊缩放渲染动画、环状发散渲染动画、挤压收缩渲染动画等几个动画,都非常非常的Cool哦~下面是它们的效果截图:

在线演示Demo:

有些遗憾的是,目前的Silverlight3.0版本仅支持基于pixel(像素)的渲染,暂时还无法实现基于Vertex(顶点)的HLSL渲染,但是这些已经很大程度上能够满足我们现有的需求。基于HLSL的动画渲染特效能够通过简单的代码编写再配上合适的图片即可实现诸如光晕、雨雪、云雾、闪电、冰块等环境特效以及爆炸、激光、水晶等魔法特效,这一切一切的实现仅仅使用最大不过几十KB的存储空间。Silverlight的明天更美好!我坚信。

作者:深蓝色右手
出处:http://alamiye010.cnblogs.com/
本系列目录及源码下载:点击进入(欢迎加入WPF/Silverlight小组 WPF/Silverlight博客团队)
本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此段声明,且在文章页面显著位置给出原文连接,否则保留追究法律责任的权利。

WPF/Silverlight深度解决方案:(七)HLSL自定义渲染特效之完美攻略(中)的更多相关文章

  1. WPF/Silverlight深度解决方案:(九)HLSL自定义渲染特效之完美攻略(下)

    原文:WPF/Silverlight深度解决方案:(九)HLSL自定义渲染特效之完美攻略(下) 本想只用两节来完成关于HLSL自定义渲染相关知识的讲解,鉴于最近非常的多的朋友对此相当感兴趣,想知道最多 ...

  2. WPF/Silverlight深度解决方案:(六)HLSL自定义渲染特效之完美攻略(上)

    原文:WPF/Silverlight深度解决方案:(六)HLSL自定义渲染特效之完美攻略(上) Shader Effect种位图特效及2种渲染特效,而Silverlight中仅有这2种渲染特效: Bl ...

  3. WPF/Silverlight深度解决方案:(一)解锁被Storyboard束缚的关联属性

    原文 WPF/Silverlight深度解决方案:(一)解锁被Storyboard束缚的关联属性 如果您在使用WPF/Silverlight进行相关动画开发中使用了Storyboard,并对关联属性进 ...

  4. 使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_132 最近疫情比较严重,很多公司依靠阿里旗下的办公软件钉钉来进行远程办公,当然了,钉钉这个产品真的是让人一言难尽,要多难用有多难用 ...

  5. 制作自定义背景Button按钮、自定义形状Button的全攻略(转)

    在Android开发应用中,默认的Button是由系统渲染和管理大小的.而我们看到的成功的移动应用,都是有着酷炫的外观和使用体验的.因此,我们在开发产品的时候,需要对默认按钮进行美化.在本篇里,笔者结 ...

  6. Silverlight 2.5D RPG游戏技巧与特效处理:(五)HLSL渲染动画

    原文:Silverlight 2.5D RPG游戏技巧与特效处理:(五)HLSL渲染动画 或许大家依旧对上一节中的“黑夜”及“梦回过去”记忆犹新,追问下去HLSL到底是何方神圣能实现如此炫酷之效果?层 ...

  7. XData -–无需开发、基于配置的数据库RESTful服务,可作为移动App和ExtJS、WPF/Silverlight、Ajax等应用的服务端

    XData -–无需开发.基于配置的数据库RESTful服务,可作为移动App和ExtJS.WPF/Silverlight.Ajax等应用的服务端   源起一个App项目,Web服务器就一台,已经装了 ...

  8. WPF/Silverlight Layout 系统概述——Arrange(转)

    Arrange过程概述 普通基类属性对Arrange过程的影响 我们知道Measure过程是在确定DesiredSize的大小,以便Arrange过程参考这个DesiredSize,确定给MyPane ...

  9. WPF/Silverlight Layout 系统概述——Measure(转)

    前言 在WPF/Silverlight当中,如果已经存在的Element无法满足你特殊的需求,你可能想自定义Element,那么就有可能会面临重写MeasureOverride和ArrangeOver ...

随机推荐

  1. Touching segments(数据结构)

    题目链接 Problem Statement Your Maths professor is a very nice guy, but he sometimes comes up with not s ...

  2. MyBatis配置文件(一)――properties属性

    MyBatis配置文件中有很多配置项,这些配置项分别代表什么,有什么作用,需要理一下了.先通过下面这个例子来看都有哪些配置项 <?xml version="1.0" enco ...

  3. Ceisum官方教程3 -- 空间数据可视化

    原文地址:https://cesiumjs.org/tutorials/Visualizing-Spatial-Data/ 这篇教程教你如何使用Cesium的Entity API去绘制空间数据,如点, ...

  4. 【DM642学习笔记四】flash烧写过程——错误记录…

    (欢迎批评指正) 一,打开.cdd配置文件时出错: 解决:在FlashBurn配置窗口中,Conversion Cmd一栏可不用管:      菜单Program—Download FBTC,load ...

  5. vue实现跳转路由

    参考vue官方文档:https://router.vuejs.org/zh/guide/essentials/navigation.html // 字符串 router.push('home') // ...

  6. LC327 Count of Range Number

    这一题,我们使用了分治法. 首先看时间复杂度为o(n^2),比较naïve的方法: 使用一个数组sum[],长度为原数组长度+1,每一个元素sum[i]为原数组中index0~i-1之和,显然当sum ...

  7. mongodb 使用常见问题汇总(主要是集群搭建)

    1 安装 请使用官方推荐的教程 https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/ 2 远程访问失败: 操作系统是u ...

  8. jq写tab切换

    $('.index-news-sub-box ul li').click(function(){ var i=$(this).index(); var img=$('.index-news-img-b ...

  9. MVC的学习步骤

    (1)搭建环境(2)如何完成Controller和 Model的映射(3)如何把值传给Controller(4)Controller如何把值传给viewer(5)异常处理(6)页面标签(7)文件上传( ...

  10. Liferay 7:portlet name

    总结自: https://web.liferay.com/zh/web/user.26526/blog/-/blogs/proper-portlet-name-for-your-portlet-com ...