三言两语说shader(七)黑幕扩散

按计划继续,目前为止写了三篇对工程已有shader的分析解读,当然实际上我读的shader远不止这三个啦,比如这周就把乐乐同学的blog里的几十篇文章泛泛通读了一遍,主要也是为自己开始构思写一些简单的shader作准备,所谓“思而不学则殆”,不多看些别人的东西自己就想搞创作明显是要吃亏的。


所谓“黑幕扩散”,就是一开始屏幕全黑,然后从中心向外逐渐展示出游戏画面。

为什么我要做这么一个东西呢?一是它想来比较简单。二是去年这个时候,一个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最终还是不能使用,有谁还在用的可以告诉我一声。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值