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

相关内容

热门资讯

总结f辅助!wepoker养号... 您好,拱趴大菠萝有挂吗这款游戏可以开挂的,确实是有挂的,需要了解加去威信【485275054】很多玩...
指引f辅助!约局吧德州真的存在... 指引f辅助!约局吧德州真的存在透视吗,pokemmo辅助器脚本下载,总结教程(详细教程)1)约局吧德...
指引f辅助!wepoker私人... 指引f辅助!wepoker私人局怎么玩,aapoker ai插件,解迷教程(有挂方针);1、每一步都...
举措f辅助!wpk德州局透视,... 举措f辅助!wpk德州局透视,哈糖大菠萝可以开挂吗,教你教程(有挂工具)1、这是跨平台的哈糖大菠萝可...
手段f辅助!wepoker提高... 手段f辅助!wepoker提高好牌率,wepoker游戏下载,揭露教程(发现有挂)一、wepoker...
讲义f辅助!德州局怎么透视,菠... 讲义f辅助!德州局怎么透视,菠萝辅助器免费版的功能介绍,详细教程(有挂规律)1、下载好菠萝辅助器免费...
妙招f辅助!wepoker辅助... 妙招f辅助!wepoker辅助分析器,竞技联盟辅助,专业教程(详细教程)1.wepoker辅助分析器...
大纲f辅助!aapoker辅助... 大纲f辅助!aapoker辅助插件工具,wpk刷入池率脚本,推荐教程(真实有挂)1、实时aapoke...
手册f辅助!hhpoker辅助... 手册f辅助!hhpoker辅助器,hhpoker德州挂真的有吗,科普教程(有挂技巧)1、hhpoke...
技法f辅助!wpk系统是否存在... 技法f辅助!wpk系统是否存在作弊行为,wpk有辅助器吗,辅助教程(果真有挂)1、下载好wpk系统是...