【shader】边缘自定角度高光,描边,闪烁
来源:互联网 发布:项目数据分析报告 编辑:程序博客网 时间:2024/05/01 09:42
最终效果
两个点我要讲
向量的旋转
事实上是初中知识,但我书读的不好,所以我要给自己讲下。
先弄清楚如何在一个二维空间旋转一个变量。
观察图中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.0ENDCGSubShader{Tags{ "RenderType" = "Transparent""Queue" = "Transparent""LightMode" = "ForwardBase" }LOD 200Pass{Cull FrontZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAMfixed4 _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/45577749o.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{CGPROGRAMfixed4 _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"}
0 0
- 【shader】边缘自定角度高光,描边,闪烁
- [Shader 着色器]边缘高光
- shader 边缘泛光
- shader 边缘泛光2
- 边缘高光实现
- 顶点高光.Shader
- 片段高光.Shader
- U3D实现边缘高光
- Unity Shader Example 21 (Highlighting 边缘光)
- Unity Shader-边缘光(RimLight)效果
- Unity Shader-边缘光(RimLight)效果
- Unity3D脚本:边缘高光脚本
- Unity Shader 表面着色器边缘光(Rim Lighting)一
- Unity Shader 表面着色器边缘光(Rim Lighting)二
- Ogre高光Shader入门(HLSL)
- Unity Shader Example 12 (Bloom 高光)
- shader中创建漫反射和高光
- unity 弧形移动 角度自定
- mac android studio clone github项目到本地.txt
- Android拍照保存在系统相册不显示的问题解决方法
- 根据NSString 转化为 NSDate , 进而根据NSDate 计算年龄
- context使用不当导致安卓内存泄露
- JavaScript btoa atob
- 【shader】边缘自定角度高光,描边,闪烁
- NGINX 用户权限
- 安卓内存泄露之context使用不当
- context使用不当导致安卓内存泄露
- 设计模式(二)----- 抽象工厂(AbstractFactory)----(JAVA版)
- HDU3078 Network
- SURF算法
- 正则表达式在性能测试中的应用(续)
- Cordys对浏览器支持信息(Support information on latest browsers)