写一个边缘发光shader,我想到如下内容。首先可能是有纹理的,那么我就要在物体的边缘对其颜色做一个修正,这个物体的边缘跟物体应该是无关的,而跟摄像机方向有关
那么在什么情况下会出现某个计算在物体中心颜色为0or很少颜色,在边缘颜色很深呢。
在边缘法线与该点到摄像机的夹角应该是超过90的,在中心位置这个夹角是0,那么我就需要一个从0到90+角度值增大的函数
ret smoothstep(e1, e2, e3)
unity的smoothstep是一个从e1到e2插值函数,用这个函数,我们要控制e3,如果e3在e1一下那么结果就是0,在e2以上就是1,在e1,e2之间就是插值
我们取法线和视角view方向的点乘,这个值是这样的,边缘可能略微大于120度
放一个简图
除此之外要控制一下e1和e2的数值
Shader "Custom/test4" {
Properties{
_MainTex ("Base (RGB)", 2D) = "white"{} //这个没啥好说的,其实用不到纹理
_Color("Main Color", Color) = (1,1,1,1) //白光
_RimColor("Rim Color", Color) = (1,1,1,1)
_RimWidth("Rim Width", float) = 0.9 //这个东西是拿来控制插值函数的起点的,如果这个值大,那麽显示成黄色的区域(即描边)会变大
}
SubShader{
Pass{
Lighting Off
CGPROGRAM
#pragma vertex vert //顶点着色器
#pragma fragment frag //片段着色器
#include "UnityCG.cginc"
struct appdata
{
float4 vertex: POSITION;
float3 normal:NORMAL;
float2 texcoord:TEXCOORD0;
};
struct v2f
{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
fixed3 color :COLOR;
};
uniform float4 _MainTex_ST;
uniform fixed4 _RimColor;
float _RimWidth;
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex); //获得照相机空间坐标
float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
//ObjSpaceViewDir这个函数输入一个模型空间的顶点位置,返回模型空间中从该点到摄像机的观察方向即 view方向
float dotProduct = 1 - dot(v.normal, viewDir); //这里算颜色,采用的是法线和视角的点乘是一个0-1的数值,中心区域的值比较大,等于这个dotProduct在中心位置比较小
//我们想一下,在正中央的这个结果是什么,一个单位向量而且是正向的z,会得到一个结果就是0
o.color = smoothstep(1 - _RimWidth,1.0, dotProduct); //这里的smoothstep,是一个平滑过渡函数, 对于1- RimWidth以下都是0,从1-RimWidth 到1逐渐增加到1, dotProduct控制平滑的参数,对于RimWidth大的情况,dotProduct在比较小的值的时候都不是0,dotProduct比较小的时候意味着是中心,即dot(v.normal, viewDir)比较大
//那么对于dotProduct为0的中心点,这个值就是1
o.color *= _RimColor;给它变个色,这个值在边缘比较大,中心小
o.uv = v.texcoord.xy;
return o;
}
uniform sampler2D _MainTex;
uniform fixed4 _Color;
fixed4 frag(v2f i):COLOR{
//fixed4 texcol = tex2D(_MainTex, i.uv); //纹理取样 没有纹理就是白光1111
//texcol *= _Color;
fixed4 texcol = (1,1,1,1);
texcol *= _Color; //变成MainColor
texcol.rgb += i.color; //在这个上面叠加颜色
return texcol;
}
ENDCG
}
}
FallBack "Diffuse"
}
这里需要明确的是,RimWidth表示了描边的起点半径,而从这点开始到1是一个渐变过程,在边缘的部分描边颜色最明显
这里面的重点是在顶点着色器中计算颜色,核心是球面与view正对的点的法线与view方向的标准向量点积是最小的,边缘部分是最大的