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中点乘不懂的话可以联系我。有任何错误请指出,补充请评论,看到会第一时间回复,谢谢。

相关内容

热门资讯

第2分钟操作!圣游科技辅助器,... 第2分钟操作!圣游科技辅助器,随意玩房卡辅助器透视(辅助)本来有挂平台(哔哩哔哩)1、随意玩房卡辅助...
五分钟手筋!好友赣南新版本挂,... 您好,好友赣南新版本挂这款游戏可以开挂的,确实是有挂的,需要了解加去威信【136704302】很多玩...
五分钟手筋!贰柒拾智能辅助柒,... 五分钟手筋!贰柒拾智能辅助柒,新广西老友辅助(辅助)其实存在有插件(哔哩哔哩)进入游戏-大厅左侧-新...
7分钟举措!丫丫衡阳字牌3辅助... 7分钟举措!丫丫衡阳字牌3辅助,樱花之盛辅助器下载(辅助)一贯是真的平台(哔哩哔哩)1、7分钟举措!...
第3分钟教程书!掌电竞技辅助器... 第3分钟教程书!掌电竞技辅助器,悟空大厅辅助器(辅助)一贯是有辅助器(哔哩哔哩)1)掌电竞技辅助器辅...
第2分钟法子!哈糖大菠萝可以开... 第2分钟法子!哈糖大菠萝可以开挂吗,悟空大厅辅助器下载(辅助)确实真的是有软件(哔哩哔哩)1、进入到...
第五分钟机巧!闲逸软件可以控制... 第五分钟机巧!闲逸软件可以控制的吗,新众亿挂机(辅助)都是是有神器(哔哩哔哩)第五分钟机巧!闲逸软件...
1分钟绝活!悠闲卡五星辅助,来... 1分钟绝活!悠闲卡五星辅助,来来拼十辅助(辅助)本来存在有下载(哔哩哔哩)1、悠闲卡五星辅助免费脚本...
第4分钟技法!边锋干瞪眼小程序... 第4分钟技法!边锋干瞪眼小程序辅助,道游互娱辅助免费版(辅助)本来真的有辅助器(哔哩哔哩)1、玩家可...
脚本曝光!hhpoker俱乐部... 脚本曝光!hhpoker俱乐部是干嘛的,hhpoker辅助软件(透视)切实真的有神器(哔哩哔哩)1、...