[shader]边缘自定角度高光,描边,闪烁

最终效果

[shader]边缘自定角度高光,描边,闪烁

两个点我要讲

向量的旋转

事实上是初中知识,但我书读的不好,所以我要给自己讲下。
先弄清楚如何在一个二维空间旋转一个变量。
[shader]边缘自定角度高光,描边,闪烁
观察图中v和v`的关系是 v`=[Cosθ,Sinθ]v  (假设v是列向量)
但在二维空间中,每个物体都有2个轴且互相垂直,如果旋转一个物体,就相当于旋转这个物体的坐标系,需要同时旋转这个物体的2个轴向量,才能达到完全旋转一个物体的要求。
我们把上面的图扩展下。
[shader]边缘自定角度高光,描边,闪烁
这样,我们就成功的获得了一个二维旋转矩阵。
[cosθ,-sinθ]
[sinθ,cosθ]
用这个矩阵就可以任意旋转任何二维物体,如果矩阵乘以对应的物体的世界坐标那物体就会围绕世界原心旋转(因为物体的坐标在图形是以矩阵的形式存储的)
旋转的方向如图示,θ是弧度,可不是角度,弧度乘以180/π,才是角度。
现在会旋转二维物体了,其实也就会旋转三维物体了,因为二维旋转就是在绕三维空间的Z轴旋转,只不过Z轴与我们的坐标系垂直,看不到(这里我就不画图啦)。
把上面的矩阵扩展到三维就是
[cosθ,-sinθ,0]
[sinθ,cosθ, 0]
[     0,       0, 1]
我们在3行3列留1,保证相乘后Z轴不变。绕X轴,绕Y轴以此类推。

乒乓效果

其实这个很简单,只是我脑子笨。
shader中,_Time是unity通过cpu给gpu传的time值。我们可以取他的余弦实现乒乓效果。
  1. float t = abs(cos(_Time.x*loopTime));  
用时间取余你的间隔时间比较你的间隔中间时间来,判断到底是增还是减。

其他问题

关于描边,注释中有作者的博客地址。
sinθ和cosθ的正负只要成对改,依然能正常旋转,因为和你传入的角度依然是正确的函数关系。

Shader代码

  1. Shader "QQ/RimLight" {  
  2.     Properties{  
  3.         _Color("Color", Color) = (1,1,1,1)  
  4.         _MainTex("纹理", 2D) = "white" {}  
  5.     <span style="white-space:pre">    </span>_LightColor("灯颜色",Color) = (1,1,1,1)  
  6.         _LightDir("灯方向",Vector) = (0,1,0,1)  
  7.         _OutLine("描边颜色",Color) = (1,1,1,1)  
  8.         _EdgeChange("描边大小",Range(0,.1)) = .05  
  9.         _FlickerTime("闪烁时间,0为关闭",Range(0,2)) = 1  
  10.     }  
  11.     CGINCLUDE  
  12.     #include "UnityCG.cginc"  
  13.     #pragma vertex vert  
  14.     #pragma fragment frag  
  15.     #pragma target 3.0  
  16.     ENDCG  
  17.     SubShader{  
  18.     Tags{ "RenderType" = "Transparent"  
  19.     "Queue" = "Transparent"  
  20.     "LightMode" = "ForwardBase" }  
  21.     LOD 200  
  22.     Pass  
  23.     {  
  24.         Cull Front  
  25.         ZWrite Off  
  26.         Blend SrcAlpha OneMinusSrcAlpha  
  27.         CGPROGRAM  
  28.         fixed4 _OutLine;  
  29.         float _EdgeChange;  
  30.         float _FlickerTime;  
  31.     struct a2v  
  32.     {  
  33.         float4 vertex:POSITION;  
  34.         float3 normal : NORMAL;  
  35.     };  
  36.     struct v2f  
  37.     {  
  38.         float4 pos : POSITION;  
  39.     };  
  40.     v2f vert(a2v v)  
  41.     {  
  42.         v2f o;  
  43.         //参考博客 http://blog.csdn.net/candycat1992/article/details/45577749  
  44.         o.pos = mul(UNITY_MATRIX_MV,v.vertex);  
  45.         v.normal = mul((float3x3)UNITY_MATRIX_MV,v.normal);  
  46.         v.normal.z = -.5;  
  47.         o.pos.xyz += v.normal*_EdgeChange;  
  48.         o.pos = mul(UNITY_MATRIX_P,o.pos);  
  49.         //参考官方教程  
  50.         //v.vertex.xyz += v.normal*_EdgeChange;  
  51.         //o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
  52.         return o;  
  53.     }  
  54.     fixed4 frag(v2f i) :COLOR  
  55.     {  
  56.         //闪烁的乒乓的速度,如果脚本传值可以把这段删掉  
  57.         _OutLine.a = abs(cos(_Time.x*_FlickerTime));  
  58.         return _OutLine;  
  59.     }  
  60.     ENDCG  
  61.     }  
  62.     Pass  
  63.     {  
  64.     CGPROGRAM  
  65.     fixed4 _Color;  
  66.     sampler2D _MainTex;  
  67.     fixed4 _MainTex_ST;  
  68.     fixed4 _LightColor;  
  69.     fixed4 _LightDir;  
  70.   
  71.   
  72.     struct a2v  
  73.     {  
  74.         float4 vertex:POSITION;  
  75.         float3 normal : NORMAL;  
  76.         float4 texcoord : TEXCOORD0;  
  77.     };  
  78.     struct v2f {  
  79.         float4 pos : POSITION;  
  80.         float2 uv:TEXCOORD0;  
  81.         float3 normal:TEXCOORD1;  
  82.         float3 viewDir:TEXCOORD2;  
  83.         UNITY_FOG_COORDS(3)  
  84.     };  
  85.   
  86.   
  87.     v2f vert(a2v v)  
  88.     {  
  89.         v2f o;  
  90.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
  91.         float4 wPos = mul(_Object2World, v.vertex);  
  92.         o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);  
  93.         //不过分追求效果的情况下在这里normalize,如果追求效果,请在frag内normalize,否则插值会被归一。  
  94.         o.normal = normalize(mul(v.normal, _World2Object).xyz);  
  95.         //我们希望光是从摄像机对面过来的,所以就反减  
  96.         o.viewDir = normalize(wPos.xyz - _WorldSpaceCameraPos);  
  97.         //旋转矩阵  
  98.         float3x3 rotaX = { 1,0,0,0,cos(_LightDir.x),sin(_LightDir.x),0,-sin(_LightDir.x),cos(_LightDir.x) };  
  99.         float3x3 rotaY = { cos(_LightDir.y),0,sin(_LightDir.y),0,1,0,-sin(_LightDir.y),0,cos(_LightDir.y) };  
  100.         float3x3 rotaZ = { cos(_LightDir.z),sin(_LightDir.z),0,-sin(_LightDir.z),cos(_LightDir.z),0,0,0,1 };  
  101.         o.viewDir = mul(rotaX, o.viewDir);  
  102.         o.viewDir = mul(rotaY, o.viewDir);  
  103.         o.viewDir = mul(rotaZ, o.viewDir);  
  104.         //矩阵相乘后结果不太对,可能写错了。  
  105.         //float3x3 rota = { sin(_LightDir.y)*sin(_LightDir.z),sin(_LightDir.y)*cos(_LightDir.z),cos(_LightDir.y),  
  106.         // -sin(_LightDir.y)*cos(_LightDir.x)*sin(_LightDir.z) - sin(_LightDir.x)*sin(_LightDir.z),-sin(_LightDir.y)*cos(_LightDir.x)*cos(_LightDir.z) + sin(_LightDir.x)*cos(_LightDir.z),cos(_LightDir.x)*cos(_LightDir.y),  
  107.         // -sin(_LightDir.y)*cos(_LightDir.x)*sin(_LightDir.z) + sin(_LightDir.x)*sin(_LightDir.z),-sin(_LightDir.y)*cos(_LightDir.x)*cos(_LightDir.z) - sin(_LightDir.x)*cos(_LightDir.z),cos(_LightDir.x)*cos(_LightDir.y)  
  108.         //};  
  109.         //o.viewDir = mul(rota, o.viewDir);  
  110.         return o;  
  111.     }  
  112.     fixed4 frag(v2f i) :COLOR  
  113.     {  
  114.         fixed4 col;  
  115.         fixed4 tex = tex2D(_MainTex,i.uv);  
  116.         //点乘normal和视线,判断相似度  
  117.         float diff = max(0,dot(i.normal, i.viewDir));  
  118.         col = tex*_Color + _LightColor*diff*_LightDir.w;  
  119.         return col;  
  120.     }  
  121.     ENDCG  
  122.     }  
  123.     }  
  124.     FallBack "Diffuse"  
  125. }  


版权声明:本文为博主原创文章,未经博主允许不得转载。
[shader]边缘自定角度高光,描边,闪烁
[shader]边缘自定角度高光,描边,闪烁

【Unity技巧】LOGO闪光效果

写在前面本文参考了风宇冲的博文,在按照这篇博文实现LOGO闪光时,发现了一些问题。最严重的就是背景无法透明,看上去背景始终是黑色的;其次就是各个变量的意义不是非常明确,调节起来不方便;而且在闪光...

unity使用屏幕后处理实现闪烁特效,创建新的shader文件过程

shader代码Shader "FlickerEffect"{ Properties { _MainTex ("Texture(RGB)", 2D) = "whit...
  • [shader]边缘自定角度高光,描边,闪烁
  • zhi_fei
  • 2017年05月11日 18:49
  • 960
[shader]边缘自定角度高光,描边,闪烁[shader]边缘自定角度高光,描边,闪烁

程序员想转管理有捷径吗?一位老前辈给我指了这条路!靠谱吗?

做程序员5年了收获蛮多,但是最近【中兴跳楼事件】发生后,我在想如果我到了40岁,会被辞退吗...

Unity Shader-边缘光(RimLight)效果

简介写了两篇简单光照模型的shader的文章,虽然Unity自带的shader就有diffuse和specular,效果还比自己写的好,然而要想学好shader,基础还是很重要的。不然到网上到处...

【Shader】边缘发光效果的两种写法

我们可以看到很多游戏经常会有这种模型边缘发光的效果,看起来很高大上的样子。其实实现起来挺简单的,网上也有很多这样的例子分享,现在我也来分享一下两种Shader实现的代码吧。1.Surface Sha...

unity 给物体边缘加高光轮廓的办法,付Demo(增加一组算法)

2013-12-30 17:21:46|  分类:unity3d技术 |举报|字号 订阅1.边缘光方法(Rim Light):Unity官方教程里有例子,其中核...
  • [shader]边缘自定角度高光,描边,闪烁
  • wolf96
  • 2014年08月28日 19:40
  • 2932

unity 给物体边缘加高光轮廓的办法,付Demo(增加一组算法)

原文链接:http://dong2008hong.blog.163.com/blog/static/469688272013113052146887/1.边缘光方法(Rim Light...

Unity Shader 表面着色器边缘光(Rim Lighting)二

这一节我们要实现下面的效果(图一)(图二)首先针对图一我们创建一个材质,并把颜色改成红色的,然后我们就得到了一个很普通的红色小球。我们只需要在鼠标进入的时候把材质的Shad...

unity 靠很近的两个面发生闪烁的解决方案

edit--projectsetting-----quality----anti alissing(把这个值跳到4X)Unity中模型发生闪烁原因通常情况下是因为其中两个面距离太近了。 这里有...
  • [shader]边缘自定角度高光,描边,闪烁
  • juan01
  • 2015年04月15日 11:20
  • 3529

UnityShader实战之 水波纹的实现

大家好,我是Zander. 今天我们来实现一下水波纹的效果。效果如下:  具体实现如下:Shader "Custom/AnimTextureShader" {Properties {...

【Unity Shader】手游中高光效果的几种实现方法

前言        由于手机设备的性能限制,很多计算都得精简和优化才能达到目地。而在Unity中的高光效果,也给予了多种不同的方案,有用于主机的,用于手机的,有限制一盏像素灯的,开发者可以根据不同的...

【Unity Shader编程】之十四 边缘发光Shader(Rim Shader)的两种实现形态

这篇文章主要讲解了如何在Unity3D中分别使用Surface Shader和Vertex & Fragment Shader实现边缘发光Shader。一、最终实现的效果 边缘发光Shad...
  • [shader]边缘自定角度高光,描边,闪烁
  • zhmxy555
  • 2016年06月26日 20:42
  • 21193

【Unity3D Shader编程】之十三 单色透明Shader & 标准镜面高光Shader

本次更新放出的Shader为透明系列的3个Shader和标准的镜面高光Shader的两个Shader。由易到难,由入门级到应用级,难度梯度合理。依然是先放出游戏场景的exe和运行截图。 ...
  • [shader]边缘自定角度高光,描边,闪烁
  • zhmxy555
  • 2016年03月13日 16:48
  • 21056

unity3d边缘发光效果

这是本人在学习unity的shader的一些理解,效果图如下核心代码为void surf (Input IN, inout SurfaceOutput o) {fixed4 t =...
[shader]边缘自定角度高光,描边,闪烁

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
[shader]边缘自定角度高光,描边,闪烁

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Glow + Outline 轮廓描边

【狗刨学习网】轮廓描边是游戏中的细节  但是一个有特色的效果还是会让人眼前一亮Glow + Outline 的效果就像求生之路2和暗黑3的轮廓描边界一样  对轮廓描边后再进行模糊处理...

Cocos2d-x shader学习3: sprite描边(Outline)

Cocos2d-x 3.x的label使用了freetype字体引擎(http://www.freetype.org/),可以很轻松的实现描边和阴影效果。所以本篇文章只针对于sprite来实现描边效果...

【OpenGL】Shader实例分析(五)- 边缘检测

这片文章将介绍基于法线的边缘检测方法
  • [shader]边缘自定角度高光,描边,闪烁
  • stalendp
  • 2014年04月08日 00:02
  • 15054

三言两语说shader(五)轮廓描边

这也是个常见的shader,可以实现类似动漫《枪之国度》的那种轮廓描边卡通画风。在我手头的项目里用来给怪物加“霸体”效果,所谓霸体意思是怪物此时无法被击倒。用途诸如此类。下面放效果图:...
  • [shader]边缘自定角度高光,描边,闪烁
  • obmar45
  • 2016年04月03日 14:10
  • 3152

Unity VR 优化

转自: http://www.gameres.com/629910.html  GameRes游资网授权发布 文/王寒     简介  对于VR应用来说,如果想要让用户获得好的用户...
  • [shader]边缘自定角度高光,描边,闪烁
  • sgnyyy
  • 2016年04月18日 11:46
  • 631