Unity_物体轮廓外发光
创始人
2024-11-15 18:36:29
0

Shader实现Unity中物体轮廓外发光效果,效果如图

上述效果分两个pass实现,就是每一个pass会绘制一次,至于为什么更改Shader以及相关GPU绘制物体基本流程可以自行搜索,这里只做代码实现以及实现原理,这里更改顶点Shader以及片元着色Shader,这也是我们自己可以代码干预的。

在Assets目录下创建Shader:Create->Shader->Unlit Shader

再创建材质球:Create->Material,将材质球拖入你需要外发光的物体上

创建好后单机材质球在Inspector中找到Shader,更换为Shader->Unlit->你创建好的Shader然后双击打开shader

一、物体边缘黑色光

 Pass  {       cull front      CGPROGRAM       #pragma vertex vert      #pragma fragment frag      #pragma multi_compile_fog      #include "UnityCG.cginc"      struct appdata      {          float4 vertex : POSITION;          float2 uv : TEXCOORD0;          float3 normal:NORMAL;      };      struct v2f      {          float2 uv : TEXCOORD0;          UNITY_FOG_COORDS(1)          float4 vertex : SV_POSITION;           float4 w_vertex:TEXTURE2;          float3 w_normal:TEXTURE1;      };      sampler2D _MainTex;      float4 _MainTex_ST;      v2f vert (appdata v)      {          v2f o;          float4 new_vert=v.vertex+float4(v.normal,1)*float4(0.1,0.1,0.1,1);          o.vertex = UnityObjectToClipPos(new_vert);          o.uv = TRANSFORM_TEX(v.uv, _MainTex);          o.w_normal=UnityObjectToWorldNormal(v.normal);          o.w_vertex=mul(unity_ObjectToWorld,v.vertex);          UNITY_TRANSFER_FOG(o,o.vertex);          return o;      }      fixed4 frag (v2f i) : SV_Target      {          fixed4 col =  fixed4(0,0,0,1);           UNITY_APPLY_FOG(i.fogCoord, col);          return col;      }      ENDCG  }

在第一个pass后直接添加第二个pass,下面讲解上述代码原理:

1.原理

网格包含有顶点坐标,发现,纹理坐标等信息,我们利用法线扩大物体顶点后计算相机与物体顶点法线的之间,法线与相机的角度cos,作为每个顶点都不同的值,并将他作为混合模式的值进行光照计算

2.实现

2.1CGPROGRAM

CGPROGRAM表示Cg program,cg代码开始,最后会有ENDCG表示cg结束

2.2顶点、片元着色器
 #pragma vertex vert  #pragma fragment frag

顶点着色器函数名为vert  
片元着色器函数名为frag  

 #include "UnityCG.cginc"

shader的库函数

v2f vert (appdata v)

 这里开始顶点绘制,在上面struct v2f中拿到需要的参数

 v2f vert (appdata v)  {      v2f o;      float4 new_vert=v.vertex+float4(v.normal,1)*float4(0.1,0.1,0.1,1);      o.vertex = UnityObjectToClipPos(new_vert);      o.uv = TRANSFORM_TEX(v.uv, _MainTex);      o.w_normal=UnityObjectToWorldNormal(v.normal);      o.w_vertex=mul(unity_ObjectToWorld,v.vertex);      UNITY_TRANSFER_FOG(o,o.vertex);      return o;  }

将顶点沿着法线方向放大0.1,

并将新顶点模型坐标转为世界坐标再转为相对相机为原点的坐标。法线向量从对象空间转换到世界空间,返回数据给渲染管道。

fixed4 frag (v2f i) : SV_Target {     fixed4 col =  fixed4(0,0,0,1);      UNITY_APPLY_FOG(i.fogCoord, col);     return col; }

这里我只需要黑色外轮廓所以直接返回黑色

注意cull front剔除前面

上面把效果图中黑色外轮廓实现,注意unity写shader并没有提示,小心错误

二、物体边缘轮廓发亮

 Pass  {      cull front      blend SrcAlpha One      CGPROGRAM       #pragma vertex vert      #pragma fragment frag      #include "UnityCG.cginc"      struct appdata      {          float4 vertex : POSITION;          float2 uv : TEXCOORD0;          float3 normal:NORMAL;      };      struct v2f      {          float2 uv : TEXCOORD0;          UNITY_FOG_COORDS(1)          float4 vertex : SV_POSITION;          float4 w_vertex:TEXTURE2;          float3 w_normal:TEXTURE1;      };      sampler2D _MainTex;      float4 _MainTex_ST;      v2f vert (appdata v)      {          v2f o;          float4 new_vert=v.vertex+float4(v.normal,1)*float4(0.5,0.5,0.5,1);          o.vertex = UnityObjectToClipPos(new_vert);          o.w_normal=UnityObjectToWorldNormal(v.normal);          o.w_vertex=mul(unity_ObjectToWorld,v.vertex);          UNITY_TRANSFER_FOG(o,o.vertex);          return o;      }      fixed4 frag (v2f i) : SV_Target      {         float3 view_dir=i.w_vertex-_WorldSpaceCameraPos;         float3 w_normal=i.w_normal;         view_dir=normalize(view_dir);         w_normal=normalize(w_normal);         float value=dot(view_dir,w_normal);         value=(value<0)?0:value;         value=pow(value,2);          fixed4 col =fixed4(0,1,0,value);          UNITY_APPLY_FOG(i.fogCoord, col);          return col;      }      ENDCG  }

blend SrcAlpha One 这种混合模式通常用于实现一些半透明的效果,其他混合模式可以去unity官方手册查看,下面提供跳转链接

Unity 用户手册 2020.3 (LTS) - Unity 手册

frag中的参数用于计算value值

这样写完之后会导致边缘可能发黑,因为剔除前面但可能网格包含前面,

所以value=(value<0)?0:value;将前面的删除。其他原理与上述差不多

注意:
本篇参考博易创为老师的内容,可以去搜索看看。
只想实现的可以直接复制上述两个pass的代码。

结尾:实现的方式有好多种,我的只是参考。如果frag中点乘不懂的话可以联系我。有任何错误请指出,补充请评论,看到会第一时间回复,谢谢。

相关内容

热门资讯

今天下午!微信老铁13水辅助,... 今天下午!微信老铁13水辅助,潮汕雀友会辅助,总结教程(有挂细节)-哔哩哔哩1、微信老铁13水辅助辅...
详情透视!xpoker辅助!分... 详情透视!xpoker辅助!分辨真假辅助攻略(有挂教程)-哔哩哔哩小薇(辅助器软件下载)致您一封信;...
据监测!欢游互动辅助,蜀山四川... 据监测!欢游互动辅助,蜀山四川破解好友版辅助,手册教程(有挂分析)-哔哩哔哩1、蜀山四川破解好友版辅...
科普透视!wepoker有没有... 科普透视!wepoker有没有插件!每日必看辅助攻略(今日头条)-哔哩哔哩1、操作简单,无需wepo...
据权威媒体报道!雀姬辅助器,四... 据权威媒体报道!雀姬辅助器,四川家园辅助软件,讲义教程(有挂技巧)-哔哩哔哩一、四川家园辅助软件可以...
专业透视!pokemmo辅助官... 专业透视!pokemmo辅助官网!玩家必看教程辅助神器(有挂头条)-哔哩哔哩1、进入到pokemmo...
普及透视!wepoker软件安... 普及透视!wepoker软件安装包!重大通报辅助技巧(真是有挂)-哔哩哔哩暗藏猫腻,小编详细说明we...
有消息称!衢州都莱有没有辅助器... 有消息称!衢州都莱有没有辅助器,钱塘十水三挂件,攻略教程(有挂教学)-哔哩哔哩衢州都莱有没有辅助器破...
关于透视!hhpoker德州牛... 关于透视!hhpoker德州牛仔视频!总算清楚辅助技巧(有挂解惑)-哔哩哔哩1、点击下载安装,hhp...
针对!天天微友辅助器通用版,广... 针对!天天微友辅助器通用版,广东雀神智能辅助照片,学习教程(有挂教学)-哔哩哔哩1、下载好天天微友辅...