Skip to content

Instantly share code, notes, and snippets.

@stilllisisi
Created March 12, 2020 02:20
Show Gist options
  • Save stilllisisi/3648ca753a69033f87e51b0b2c04c2d4 to your computer and use it in GitHub Desktop.
Save stilllisisi/3648ca753a69033f87e51b0b2c04c2d4 to your computer and use it in GitHub Desktop.
【游戏-Shader】shader实现边缘自定角度高光、描边、闪烁效果
Shader"QQ/RimLight"{
Properties{
_Color("Color",Color)=(1,1,1,1)
_MainTex("纹理",2D)="white"{}
<spanstyle="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"
#pragmavertexvert
#pragmafragmentfrag
#pragmatarget3.0
ENDCG
SubShader{
Tags{
"RenderType"="Transparent"
"Queue"="Transparent"
"LightMode"="ForwardBase"
}
LOD200
Pass
{
CullFront
ZWriteOff
BlendSrcAlphaOneMinusSrcAlpha
CGPROGRAM
fixed4_OutLine;
float_EdgeChange;
float_FlickerTime;
structa2v
{
float4vertex:POSITION;
float3normal:NORMAL;
};
structv2f
{
float4pos:POSITION;
};
v2fvert(a2vv)
{
v2fo;
//参考博客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);
returno;
}
fixed4frag(v2fi):COLOR
{
//闪烁的乒乓的速度,如果脚本传值可以把这段删掉
_OutLine.a=abs(cos(_Time.x*_FlickerTime));
return_OutLine;
}
ENDCG
}
Pass
{
CGPROGRAM
fixed4_Color;
sampler2D_MainTex;
fixed4_MainTex_ST;
fixed4_LightColor;
fixed4_LightDir;
structa2v
{
float4vertex:POSITION;
float3normal:NORMAL;
float4texcoord:TEXCOORD0;
};
structv2f{
float4pos:POSITION;
float2uv:TEXCOORD0;
float3normal:TEXCOORD1;
float3viewDir:TEXCOORD2;
UNITY_FOG_COORDS(3)
};
v2fvert(a2vv)
{
v2fo;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
float4wPos=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);
//旋转矩阵
float3x3rotaX={1,0,0,0,cos(_LightDir.x),sin(_LightDir.x),0,-sin(_LightDir.x),cos(_LightDir.x)};
float3x3rotaY={cos(_LightDir.y),0,sin(_LightDir.y),0,1,0,-sin(_LightDir.y),0,cos(_LightDir.y)};
float3x3rotaZ={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);
//矩阵相乘后结果不太对,可能写错了。
//float3x3rota={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);
returno;
}
fixed4frag(v2fi):COLOR
{
fixed4col;
fixed4tex=tex2D(_MainTex,i.uv);
//点乘normal和视线,判断相似度
floatdiff=max(0,dot(i.normal,i.viewDir));
col=tex*_Color+_LightColor*diff*_LightDir.w;
returncol;
}
ENDCG
}
}
FallBack"Diffuse"
}
@stilllisisi
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment