最终效果
两个点我要讲
向量的旋转
事实上是初中知识,但我书读的不好,所以我要给自己讲下。
先弄清楚如何在一个二维空间旋转一个变量。

观察图中v和v`的关系是 v`=[Cosθ,Sinθ]v (假设v是列向量)
但在二维空间中,每个物体都有2个轴且互相垂直,如果旋转一个物体,就相当于旋转这个物体的坐标系,需要同时旋转这个物体的2个轴向量,才能达到完全旋转一个物体的要求。
我们把上面的图扩展下。

这样,我们就成功的获得了一个二维旋转矩阵。
[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值。我们可以取他的余弦实现乒乓效果。
- float t = abs(cos(_Time.x*loopTime));
其他问题
关于描边,注释中有作者的博客地址。
sinθ和cosθ的正负只要成对改,依然能正常旋转,因为和你传入的角度依然是正确的函数关系。
Shader代码
- Shader "QQ/RimLight" {
- Properties{
- _Color("Color", Color) = (1,1,1,1)
- _MainTex("纹理", 2D) = "white" {}
- <span style="white-space:pre"> </span>_LightColor("灯颜色",Color) = (1,1,1,1)
- _LightDir("灯方向",Vector) = (0,1,0,1)
- _OutLine("描边颜色",Color) = (1,1,1,1)
- _EdgeChange("描边大小",Range(0,.1)) = .05
- _FlickerTime("闪烁时间,0为关闭",Range(0,2)) = 1
- }
- CGINCLUDE
- #include "UnityCG.cginc"
- #pragma vertex vert
- #pragma fragment frag
- #pragma target 3.0
- ENDCG
- SubShader{
- Tags{ "RenderType" = "Transparent"
- "Queue" = "Transparent"
- "LightMode" = "ForwardBase" }
- LOD 200
- Pass
- {
- Cull Front
- ZWrite Off
- Blend SrcAlpha OneMinusSrcAlpha
- CGPROGRAM
- fixed4 _OutLine;
- float _EdgeChange;
- float _FlickerTime;
- struct a2v
- {
- float4 vertex:POSITION;
- float3 normal : NORMAL;
- };
- struct v2f
- {
- float4 pos : POSITION;
- };
- v2f vert(a2v v)
- {
- v2f o;
- //参考博客 http://blog.csdn.net/candycat1992/article/details/45577749
- o.pos = mul(UNITY_MATRIX_MV,v.vertex);
- v.normal = mul((float3x3)UNITY_MATRIX_MV,v.normal);
- v.normal.z = -.5;
- o.pos.xyz += v.normal*_EdgeChange;
- o.pos = mul(UNITY_MATRIX_P,o.pos);
- //参考官方教程
- //v.vertex.xyz += v.normal*_EdgeChange;
- //o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- return o;
- }
- fixed4 frag(v2f i) :COLOR
- {
- //闪烁的乒乓的速度,如果脚本传值可以把这段删掉
- _OutLine.a = abs(cos(_Time.x*_FlickerTime));
- return _OutLine;
- }
- ENDCG
- }
- Pass
- {
- CGPROGRAM
- fixed4 _Color;
- sampler2D _MainTex;
- fixed4 _MainTex_ST;
- fixed4 _LightColor;
- fixed4 _LightDir;
- struct a2v
- {
- float4 vertex:POSITION;
- float3 normal : NORMAL;
- float4 texcoord : TEXCOORD0;
- };
- struct v2f {
- float4 pos : POSITION;
- float2 uv:TEXCOORD0;
- float3 normal:TEXCOORD1;
- float3 viewDir:TEXCOORD2;
- UNITY_FOG_COORDS(3)
- };
- v2f vert(a2v v)
- {
- v2f o;
- o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- float4 wPos = mul(_Object2World, v.vertex);
- o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
- //不过分追求效果的情况下在这里normalize,如果追求效果,请在frag内normalize,否则插值会被归一。
- o.normal = normalize(mul(v.normal, _World2Object).xyz);
- //我们希望光是从摄像机对面过来的,所以就反减
- o.viewDir = normalize(wPos.xyz - _WorldSpaceCameraPos);
- //旋转矩阵
- float3x3 rotaX = { 1,0,0,0,cos(_LightDir.x),sin(_LightDir.x),0,-sin(_LightDir.x),cos(_LightDir.x) };
- float3x3 rotaY = { cos(_LightDir.y),0,sin(_LightDir.y),0,1,0,-sin(_LightDir.y),0,cos(_LightDir.y) };
- float3x3 rotaZ = { cos(_LightDir.z),sin(_LightDir.z),0,-sin(_LightDir.z),cos(_LightDir.z),0,0,0,1 };
- o.viewDir = mul(rotaX, o.viewDir);
- o.viewDir = mul(rotaY, o.viewDir);
- o.viewDir = mul(rotaZ, o.viewDir);
- //矩阵相乘后结果不太对,可能写错了。
- //float3x3 rota = { sin(_LightDir.y)*sin(_LightDir.z),sin(_LightDir.y)*cos(_LightDir.z),cos(_LightDir.y),
- // -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),
- // -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)
- //};
- //o.viewDir = mul(rota, o.viewDir);
- return o;
- }
- fixed4 frag(v2f i) :COLOR
- {
- fixed4 col;
- fixed4 tex = tex2D(_MainTex,i.uv);
- //点乘normal和视线,判断相似度
- float diff = max(0,dot(i.normal, i.viewDir));
- col = tex*_Color + _LightColor*diff*_LightDir.w;
- return col;
- }
- ENDCG
- }
- }
- FallBack "Diffuse"
- }
版权声明:本文为博主原创文章,未经博主允许不得转载。
目前您尚未登录,请 登录 或 注册 后进行评论
-
-
puppet_master
2017-05-04 21:57 2楼 -
顶一个!
-
-

-
-
puppet_master
2017-05-04 21:41 1楼 -
顶一个!
-
-

相关文章推荐
-
【Unity技巧】LOGO闪光效果
写在前面本文参考了风宇冲的博文,在按照这篇博文实现LOGO闪光时,发现了一些问题。最严重的就是背景无法透明,看上去背景始终是黑色的;其次就是各个变量的意义不是非常明确,调节起来不方便;而且在闪光...- candycat1992
- 2014年05月13日 20:14
- 17005
-
unity使用屏幕后处理实现闪烁特效,创建新的shader文件过程
shader代码Shader "FlickerEffect"{ Properties { _MainTex ("Texture(RGB)", 2D) = "whit...- zhi_fei
- 2017年05月11日 18:49
- 960
-
程序员想转管理有捷径吗?一位老前辈给我指了这条路!靠谱吗?
做程序员5年了收获蛮多,但是最近【中兴跳楼事件】发生后,我在想如果我到了40岁,会被辞退吗...

-
Unity Shader-边缘光(RimLight)效果
简介写了两篇简单光照模型的shader的文章,虽然Unity自带的shader就有diffuse和specular,效果还比自己写的好,然而要想学好shader,基础还是很重要的。不然到网上到处...- puppet_master
- 2016年12月11日 17:04
- 5963
-
【Shader】边缘发光效果的两种写法
我们可以看到很多游戏经常会有这种模型边缘发光的效果,看起来很高大上的样子。其实实现起来挺简单的,网上也有很多这样的例子分享,现在我也来分享一下两种Shader实现的代码吧。1.Surface Sha...- yangyy753
- 2015年05月15日 11:50
- 9192
-
unity 给物体边缘加高光轮廓的办法,付Demo(增加一组算法)
2013-12-30 17:21:46| 分类:unity3d技术 |举报|字号 订阅1.边缘光方法(Rim Light):Unity官方教程里有例子,其中核...- wolf96
- 2014年08月28日 19:40
- 2932
-
unity 给物体边缘加高光轮廓的办法,付Demo(增加一组算法)
原文链接:http://dong2008hong.blog.163.com/blog/static/469688272013113052146887/1.边缘光方法(Rim Light...- yangyisen0713
- 2015年05月19日 13:48
- 1993
-
Unity Shader 表面着色器边缘光(Rim Lighting)二
这一节我们要实现下面的效果(图一)(图二)首先针对图一我们创建一个材质,并把颜色改成红色的,然后我们就得到了一个很普通的红色小球。我们只需要在鼠标进入的时候把材质的Shad...- jk823394954
- 2015年10月08日 23:34
- 3184
-
unity 靠很近的两个面发生闪烁的解决方案
edit--projectsetting-----quality----anti alissing(把这个值跳到4X)Unity中模型发生闪烁原因通常情况下是因为其中两个面距离太近了。 这里有...- juan01
- 2015年04月15日 11:20
- 3529
-
UnityShader实战之 水波纹的实现
大家好,我是Zander. 今天我们来实现一下水波纹的效果。效果如下: 具体实现如下:Shader "Custom/AnimTextureShader" {Properties {...- zjw1349547081
- 2016年12月29日 16:31
- 1870
-
【Unity Shader】手游中高光效果的几种实现方法
前言 由于手机设备的性能限制,很多计算都得精简和优化才能达到目地。而在Unity中的高光效果,也给予了多种不同的方案,有用于主机的,用于手机的,有限制一盏像素灯的,开发者可以根据不同的...- herox25000
- 2016年01月10日 11:08
- 3709
-
【Unity Shader编程】之十四 边缘发光Shader(Rim Shader)的两种实现形态
这篇文章主要讲解了如何在Unity3D中分别使用Surface Shader和Vertex & Fragment Shader实现边缘发光Shader。一、最终实现的效果 边缘发光Shad...- zhmxy555
- 2016年06月26日 20:42
- 21193
-
【Unity3D Shader编程】之十三 单色透明Shader & 标准镜面高光Shader
本次更新放出的Shader为透明系列的3个Shader和标准的镜面高光Shader的两个Shader。由易到难,由入门级到应用级,难度梯度合理。依然是先放出游戏场景的exe和运行截图。 ...- zhmxy555
- 2016年03月13日 16:48
- 21056
-
unity3d边缘发光效果
这是本人在学习unity的shader的一些理解,效果图如下核心代码为void surf (Input IN, inout SurfaceOutput o) {fixed4 t =...- lj820348789
- 2015年07月21日 17:48
- 1545
-
Delphi7高级应用开发随书源码
- 2003年04月30日 00:00
- 676KB
- 下载

-
Delphi7高级应用开发随书源码
- 2003年04月30日 00:00
- 676KB
- 下载

-
Glow + Outline 轮廓描边
【狗刨学习网】轮廓描边是游戏中的细节 但是一个有特色的效果还是会让人眼前一亮Glow + Outline 的效果就像求生之路2和暗黑3的轮廓描边界一样 对轮廓描边后再进行模糊处理...- book_longssl
- 2015年03月09日 08:51
- 1629
-
Cocos2d-x shader学习3: sprite描边(Outline)
Cocos2d-x 3.x的label使用了freetype字体引擎(http://www.freetype.org/),可以很轻松的实现描边和阴影效果。所以本篇文章只针对于sprite来实现描边效果...- liwenxin_at
- 2016年02月20日 15:47
- 1967
-
【OpenGL】Shader实例分析(五)- 边缘检测
这片文章将介绍基于法线的边缘检测方法- stalendp
- 2014年04月08日 00:02
- 15054
-
三言两语说shader(五)轮廓描边
这也是个常见的shader,可以实现类似动漫《枪之国度》的那种轮廓描边卡通画风。在我手头的项目里用来给怪物加“霸体”效果,所谓霸体意思是怪物此时无法被击倒。用途诸如此类。下面放效果图:...- obmar45
- 2016年04月03日 14:10
- 3152
-
Unity VR 优化
转自: http://www.gameres.com/629910.html GameRes游资网授权发布 文/王寒 简介 对于VR应用来说,如果想要让用户获得好的用户...- sgnyyy
- 2016年04月18日 11:46
- 631
他的热门文章
- [Texture]详解Texture2D
4117
- [Mesh]代码生成圆柱网格
2746
- [Mesh]网格的快速切割
2646
- [网络]Unity的Socket通讯_3_粘包丢包
2276
- [shader]边缘自定角度高光,描边,闪烁
1994