三言两语说shader(七)黑幕扩散
2016-04-09 21:18
260 查看
按计划继续,目前为止写了三篇对工程已有shader的分析解读,当然实际上我读的shader远不止这三个啦,比如这周就把乐乐同学的blog里的几十篇文章泛泛通读了一遍,主要也是为自己开始构思写一些简单的shader作准备,所谓“思而不学则殆”,不多看些别人的东西自己就想搞创作明显是要吃亏的。
所谓“黑幕扩散”,就是一开始屏幕全黑,然后从中心向外逐渐展示出游戏画面。
为什么我要做这么一个东西呢?一是它想来比较简单。二是去年这个时候,一个UI妹子提出了这个需求,我那时哪懂什么shader咯,只好想了个笨办法,找她要了张中间挖了一个圆孔的黑图,贴面片上,放摄像机前面,然后用扩大面片尺寸的方法,好歹也给实现了,哈哈,这当然很蠢。
现在我是具备这个能力了,可惜妹子也早已离职。
废话不多说,开工。
shader是能利用内置的time变量通过取模方式在时间跨度上做一些动画效果的,比如那些UV动画、滚动的波浪、跳动的心之类的。
但是也都只能循环播放,假如想做一些一次性的变化,比如内置一个bool IsAlreadyRunning标志量,第一次运行时执行某些代码,然后将此标志量改变,第二次运行时,就不再执行某些代码,这种功能我估计是必须借助外部脚本控制的,假如哪位大神能不借助外力神奇的只让shader动画播放一次,请赐教。
我的想法是在之前黑屏shader的基础上加个半径属性,使半径圆内不黑掉即可。
试了下是可行的,HLSL有个内置函数distance,然后屏幕中心点借用Unity提供的内置参数_ScreenParams即可。代码如下:
注意这里用了if else这种流程控制语句,因为我查了下Cg/HLSL是支持这些流程控制关键字的,所以就试了下。
但我们会发现别人的shader中基本看不到if,传说这种写法效率极低,具体怎么回事去网上可以搜到相关解释。
不使用if的计算方法肯定是有的,不过我就暂时偷个懒不深究了。
另外在Unity Editor中圆的中心往往和画面中心有偏差,具体原因我也不深究了,反正发布了一个Android包实机测试画面是正确的。
效果如下:
外部控制脚本加个radius变量更新下就好了,这里也略过。
另外通过这次实验我发现顶点经过MVP变换后,pos的xy确实已经是屏幕的像素坐标了,而且坐标原点在左上角,往右是x轴正向,往下是y轴正向。
最后扯点别的,因为我Unity重新安装过,这次为了用UnityRemote看实际效果,又装了次JDK和Android SDK,好像Unity5.0后就要多设置一个JDK路径了,我设了好久都说路径无效,后来把JDK重新装在C盘而不是原来的D盘就没问题了,真是坑。
UnityRemote最终还是不能使用,有谁还在用的可以告诉我一声。
所谓“黑幕扩散”,就是一开始屏幕全黑,然后从中心向外逐渐展示出游戏画面。
为什么我要做这么一个东西呢?一是它想来比较简单。二是去年这个时候,一个UI妹子提出了这个需求,我那时哪懂什么shader咯,只好想了个笨办法,找她要了张中间挖了一个圆孔的黑图,贴面片上,放摄像机前面,然后用扩大面片尺寸的方法,好歹也给实现了,哈哈,这当然很蠢。
现在我是具备这个能力了,可惜妹子也早已离职。
废话不多说,开工。
shader是能利用内置的time变量通过取模方式在时间跨度上做一些动画效果的,比如那些UV动画、滚动的波浪、跳动的心之类的。
但是也都只能循环播放,假如想做一些一次性的变化,比如内置一个bool IsAlreadyRunning标志量,第一次运行时执行某些代码,然后将此标志量改变,第二次运行时,就不再执行某些代码,这种功能我估计是必须借助外部脚本控制的,假如哪位大神能不借助外力神奇的只让shader动画播放一次,请赐教。
我的想法是在之前黑屏shader的基础上加个半径属性,使半径圆内不黑掉即可。
试了下是可行的,HLSL有个内置函数distance,然后屏幕中心点借用Unity提供的内置参数_ScreenParams即可。代码如下:
Shader "MyShader/BlackScreenSpread" { Properties { _Color("Main Color", Color) = (0.5,0.5,0.5,0.5) _MainTex ("Base (RGB)", 2D) = "white" {} _Radius("ViewRadius", float) = 0.0 } SubShader { Pass { CGPROGRAM #include "UnityCG.cginc" #pragma vertex vert_img #pragma fragment frag fixed4 _Color; sampler2D _MainTex; float _Radius; float4 frag (v2f_img i) : COLOR { float2 centerPoint = float2(_ScreenParams.x / 2, _ScreenParams.y / 2); if ( distance(i.pos.xy, centerPoint) > _Radius) { return tex2D(_MainTex, i.uv) * _Color; } else { return tex2D(_MainTex, i.uv); } } ENDCG } } Fallback off }
注意这里用了if else这种流程控制语句,因为我查了下Cg/HLSL是支持这些流程控制关键字的,所以就试了下。
但我们会发现别人的shader中基本看不到if,传说这种写法效率极低,具体怎么回事去网上可以搜到相关解释。
不使用if的计算方法肯定是有的,不过我就暂时偷个懒不深究了。
另外在Unity Editor中圆的中心往往和画面中心有偏差,具体原因我也不深究了,反正发布了一个Android包实机测试画面是正确的。
效果如下:
外部控制脚本加个radius变量更新下就好了,这里也略过。
另外通过这次实验我发现顶点经过MVP变换后,pos的xy确实已经是屏幕的像素坐标了,而且坐标原点在左上角,往右是x轴正向,往下是y轴正向。
最后扯点别的,因为我Unity重新安装过,这次为了用UnityRemote看实际效果,又装了次JDK和Android SDK,好像Unity5.0后就要多设置一个JDK路径了,我设了好久都说路径无效,后来把JDK重新装在C盘而不是原来的D盘就没问题了,真是坑。
UnityRemote最终还是不能使用,有谁还在用的可以告诉我一声。
相关文章推荐
- 解决android EditText自动获取焦点的问题
- uva 1587 Box
- HDU 4715 Difference Between Primes (筛法求素数)
- xshell利用linux rz sz 命令上传、下载文件
- java基础知识
- 京东2016春招(实习)笔试+编程题
- JSP九大内置对象详解(一)
- 青蛙的约会(扩展gcd)
- uva 1588 Kickdown
- 欧拉函数扩展公式(10哈工大多校)(3501)
- 从无头单链表中删除节点
- 详解动态规划——邹博讲动态规划
- 移动端touch事件影响click事件以及在touchmove添加preventDefault导致页面无法滚动的解决方法
- leetcode Search a 2D Matrix
- Mac下安装redis(微原创)
- java基础知识整理(3)
- 值得注意的小细节
- hdoj-1859-最小长方形
- JNI - Call Method(Callback Call java methods from c)
- 设计模式之状态模式